Ticket #31373: 31373.2.patch
File 31373.2.patch, 256.5 KB (added by , 10 years ago) |
---|
-
src/wp-admin/admin-ajax.php
61 61 'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor', 62 62 'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs', 63 63 'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail', 64 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin' 64 'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post', 65 'press-this-add-category', 65 66 ); 66 67 67 68 // Register core Ajax calls. -
src/wp-admin/css/forms.css
684 684 685 685 .pressthis { 686 686 margin: 20px 0; 687 vertical-align: top; 688 position: relative; 689 z-index: 1; 687 690 } 688 691 689 692 .pressthis a, … … 748 751 box-shadow: 0 10px 8px rgba(0, 0, 0, 0.6); 749 752 } 750 753 754 .pressthis .button { 755 margin-left: 10px; 756 padding: 0; 757 height: auto; 758 vertical-align: top; 759 } 760 761 .pressthis button .dashicons { 762 margin: 5px 8px 6px 7px; 763 color: #777; 764 } 765 766 .press-this-install { 767 margin: 20px 0 0 0; 768 padding: 0.7em 2em 1em; 769 max-width: 520px; 770 } 771 772 .press-this-install textarea { 773 width: 100%; 774 font-size: 1em; 775 } 776 777 .press-this-install h4 { 778 margin: 2em 0 1em; 779 } 780 781 751 782 /*------------------------------------------------------------------------------ 752 783 20.0 - Settings 753 784 ------------------------------------------------------------------------------*/ -
src/wp-admin/css/press-this-editor.css
1 /* 2 Press This TinyMCE editor styles :) 3 */ 4 5 6 /** 7 * Links 8 */ 9 @import url("//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,600,700"); 10 a { 11 color: #0074a2; 12 } 13 14 a:visited { 15 color: #0074a2; 16 } 17 18 a:hover, 19 a:focus, 20 a:active { 21 color: #2ea2cc; 22 } 23 24 25 /** 26 * Lists 27 */ 28 ul, 29 ol { 30 margin: 0 0 1.5em 3em; 31 } 32 33 ul { 34 list-style: disc; 35 } 36 37 ol { 38 list-style: decimal; 39 } 40 41 li > ul, 42 li > ol { 43 margin-bottom: 0; 44 margin-left: 1.5em; 45 } 46 47 dt { 48 font-weight: 700; 49 } 50 51 dd { 52 margin: 0 1.5em 1.5em; 53 } 54 55 56 /** 57 * Media 58 * 59 * Basic image and object styles 60 */ 61 img { 62 max-width: 100%; 63 height: auto; 64 } 65 66 /* Makes sure embeds and iframes fit inside their containers */ 67 embed, 68 iframe, 69 object { 70 max-width: 100%; 71 } 72 73 74 /** 75 * TinyMCE styles 76 * 77 * Pretty dang good. 78 */ 79 body { 80 color: #404040; 81 font-family: "Open Sans", Helvetica, Arial, sans-serif; 82 font-size: 20px; 83 font-weight: 400; 84 line-height: 1.6; 85 } 86 @media (max-width: 900px) { 87 body#tinymce { 88 padding-top: 30px !important; 89 } 90 } 91 @media (max-width: 640px) { 92 body { 93 font-size: 16px; 94 } 95 } 96 @media (max-width: 320px) { 97 body { 98 margin: 0 15px; 99 } 100 } 101 102 #tinymce b, 103 #tinymce strong { 104 /* overrides TinyMCE's !important. Woohoo. */ 105 font-weight: 700 !important; 106 } 107 108 blockquote { 109 margin: 1em 1.5em; 110 color: #9ea7af; 111 font-size: em(25px); 112 font-style: italic; 113 } 114 @media (max-width: 900px) { 115 blockquote { 116 margin: 1.5em 1em; 117 } 118 } 119 120 ul, 121 ol { 122 margin: 0 0 1.5em .75em; 123 } 124 /* 125 Press This TinyMCE editor styles :) 126 */ 127 128 129 /** 130 * Links 131 */ 132 @import url("//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,600,700"); 133 a { 134 color: #0074a2; 135 } 136 137 a:visited { 138 color: #0074a2; 139 } 140 141 a:hover, 142 a:focus, 143 a:active { 144 color: #2ea2cc; 145 } 146 147 148 /** 149 * Lists 150 */ 151 ul, 152 ol { 153 margin: 0 0 1.5em 3em; 154 } 155 156 ul { 157 list-style: disc; 158 } 159 160 ol { 161 list-style: decimal; 162 } 163 164 li > ul, 165 li > ol { 166 margin-bottom: 0; 167 margin-left: 1.5em; 168 } 169 170 dt { 171 font-weight: 700; 172 } 173 174 dd { 175 margin: 0 1.5em 1.5em; 176 } 177 178 179 /** 180 * Media 181 * 182 * Basic image and object styles 183 */ 184 img { 185 max-width: 100%; 186 height: auto; 187 } 188 189 /* Makes sure embeds and iframes fit inside their containers */ 190 embed, 191 iframe, 192 object { 193 max-width: 100%; 194 } 195 196 197 /** 198 * TinyMCE styles 199 * 200 * Pretty dang good. 201 */ 202 body { 203 color: #404040; 204 font-family: "Open Sans", Helvetica, Arial, sans-serif; 205 font-size: 20px; 206 font-weight: 400; 207 line-height: 1.6; 208 } 209 @media (max-width: 900px) { 210 body#tinymce { 211 padding-top: 30px !important; 212 } 213 } 214 @media (max-width: 640px) { 215 body { 216 font-size: 16px; 217 } 218 } 219 @media (max-width: 320px) { 220 body { 221 margin: 0 15px; 222 } 223 } 224 225 #tinymce b, 226 #tinymce strong { 227 /* overrides TinyMCE's !important. Woohoo. */ 228 font-weight: 700 !important; 229 } 230 231 blockquote { 232 margin: 1em 1.5em; 233 color: #9ea7af; 234 font-size: em(25px); 235 font-style: italic; 236 } 237 @media (max-width: 900px) { 238 blockquote { 239 margin: 1.5em 1em; 240 } 241 } 242 243 ul, 244 ol { 245 margin: 0 0 1.5em .75em; 246 } 247 /* 248 Press This TinyMCE editor styles :) 249 */ 250 251 252 /** 253 * Links 254 */ 255 @import url("//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,600,700"); 256 a { 257 color: #0074a2; 258 } 259 260 a:visited { 261 color: #0074a2; 262 } 263 264 a:hover, 265 a:focus, 266 a:active { 267 color: #2ea2cc; 268 } 269 270 271 /** 272 * Lists 273 */ 274 ul, 275 ol { 276 margin: 0 0 1.5em 3em; 277 } 278 279 ul { 280 list-style: disc; 281 } 282 283 ol { 284 list-style: decimal; 285 } 286 287 li > ul, 288 li > ol { 289 margin-bottom: 0; 290 margin-left: 1.5em; 291 } 292 293 dt { 294 font-weight: 700; 295 } 296 297 dd { 298 margin: 0 1.5em 1.5em; 299 } 300 301 302 /** 303 * Media 304 * 305 * Basic image and object styles 306 */ 307 img { 308 max-width: 100%; 309 height: auto; 310 } 311 312 /* Makes sure embeds and iframes fit inside their containers */ 313 embed, 314 iframe, 315 object { 316 max-width: 100%; 317 } 318 319 320 /** 321 * TinyMCE styles 322 * 323 * Pretty dang good. 324 */ 325 body { 326 color: #404040; 327 font-family: "Open Sans", Helvetica, Arial, sans-serif; 328 font-size: 20px; 329 font-weight: 400; 330 line-height: 1.6; 331 } 332 @media (max-width: 900px) { 333 body#tinymce { 334 padding-top: 30px !important; 335 } 336 } 337 @media (max-width: 640px) { 338 body { 339 font-size: 16px; 340 } 341 } 342 @media (max-width: 320px) { 343 body { 344 margin: 0 15px; 345 } 346 } 347 348 #tinymce b, 349 #tinymce strong { 350 /* overrides TinyMCE's !important. Woohoo. */ 351 font-weight: 700 !important; 352 } 353 354 blockquote { 355 margin: 1em 1.5em; 356 color: #9ea7af; 357 font-size: em(25px); 358 font-style: italic; 359 } 360 @media (max-width: 900px) { 361 blockquote { 362 margin: 1.5em 1em; 363 } 364 } 365 366 ul, 367 ol { 368 margin: 0 0 1.5em .75em; 369 } 370 /* 371 Press This TinyMCE editor styles :) 372 */ 373 374 375 /** 376 * Links 377 */ 378 @import url("//fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,600,700"); 379 a { 380 color: #0074a2; 381 } 382 383 a:visited { 384 color: #0074a2; 385 } 386 387 a:hover, 388 a:focus, 389 a:active { 390 color: #2ea2cc; 391 } 392 393 394 /** 395 * Lists 396 */ 397 ul, 398 ol { 399 margin: 0 0 1.5em 3em; 400 } 401 402 ul { 403 list-style: disc; 404 } 405 406 ol { 407 list-style: decimal; 408 } 409 410 li > ul, 411 li > ol { 412 margin-bottom: 0; 413 margin-left: 1.5em; 414 } 415 416 dt { 417 font-weight: 700; 418 } 419 420 dd { 421 margin: 0 1.5em 1.5em; 422 } 423 424 425 /** 426 * Media 427 * 428 * Basic image and object styles 429 */ 430 img { 431 max-width: 100%; 432 height: auto; 433 } 434 435 /* Makes sure embeds and iframes fit inside their containers */ 436 embed, 437 iframe, 438 object { 439 max-width: 100%; 440 } 441 442 443 /** 444 * TinyMCE styles 445 * 446 * Pretty dang good. 447 */ 448 body { 449 color: #404040; 450 font-family: "Open Sans", Helvetica, Arial, sans-serif; 451 font-size: 20px; 452 font-weight: 400; 453 line-height: 1.6; 454 } 455 @media (max-width: 900px) { 456 body#tinymce { 457 padding-top: 30px !important; 458 } 459 } 460 @media (max-width: 640px) { 461 body { 462 font-size: 16px; 463 } 464 } 465 @media (max-width: 320px) { 466 body { 467 margin: 0 15px; 468 } 469 } 470 471 #tinymce b, 472 #tinymce strong { 473 /* overrides TinyMCE's !important. Woohoo. */ 474 font-weight: 700 !important; 475 } 476 477 blockquote { 478 margin: 1em 1.5em; 479 color: #9ea7af; 480 font-size: em(25px); 481 font-style: italic; 482 } 483 @media (max-width: 900px) { 484 blockquote { 485 margin: 1.5em 1em; 486 } 487 } 488 489 ul, 490 ol { 491 margin: 0 0 1.5em .75em; 492 } -
src/wp-admin/css/press-this.css
1 .press-this #message { 2 border-left: 4px solid #7ad03a; 3 padding: 1px 12px; 4 background-color: #fff; 5 -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1); 6 box-shadow: 0 1px 1px 0 rgba(0,0,0,0.1); 1 /* 2 Press This styles :) 3 */ 4 5 6 /** 7 * Normalize 8 * 9 * normalize.css v3.0.0 | MIT License | git.io/normalize 10 */ 11 html { 12 font-family: sans-serif; 13 -ms-text-size-adjust: 100%; 14 -webkit-text-size-adjust: 100%; 7 15 } 8 16 9 .press-this #side-sortables .category-tabs li { 10 display: inline; 11 line-height: 1.35em; 17 body { 18 margin: 0; 12 19 } 13 20 14 body.press-this ul.category-tabs li.tabs a { 15 color: #32373c; 21 *, 22 *:before, 23 *:after { 24 -webkit-box-sizing: border-box; 25 -moz-box-sizing: border-box; 26 box-sizing: border-box; 16 27 } 28 @media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi) { 29 *, 30 *:before, 31 *:after { 32 -webkit-font-smoothing: antialiased; 33 } 34 } 17 35 18 .press-this #content-resize-handle { 19 bottom: 2px; 36 article, 37 aside, 38 details, 39 figcaption, 40 figure, 41 footer, 42 header, 43 hgroup, 44 main, 45 nav, 46 section, 47 summary { 48 display: block; 20 49 } 21 50 22 body.press-this { 23 color: #32373c; 24 margin: 0; 25 padding: 0; 26 min-width: 708px;27 min-height: 400px;51 audio, 52 canvas, 53 progress, 54 video { 55 display: inline-block; 56 vertical-align: baseline; 28 57 } 29 58 30 .press-this #titlediv #title { 31 font-size: 1.4em; 59 audio:not([controls]) { 60 display: none; 61 height: 0; 32 62 } 33 63 34 .press-this #site-heading:before { 35 top: 3px; 36 position: relative; 37 display: inline-block; 38 font: normal 18px/1 'dashicons'; 39 speak: none; 40 color: #727272; 41 content: '\f120'; 42 -webkit-font-smoothing: antialiased; 43 -moz-osx-font-smoothing: grayscale; 64 [hidden], 65 template { 66 display: none; 44 67 } 45 68 46 .press-this #wphead { 47 height: 32px; 48 margin-left: 0; 49 margin-right: 0; 50 margin-bottom: 5px; 69 a { 70 background: transparent; 51 71 } 52 72 53 .press-this #header-logo { 54 float: left; 55 margin: 7px 7px 0; 56 -webkit-user-select: none; 57 -moz-user-select: none; 58 -ms-user-select: none; 59 user-select: none; 73 a:active, 74 a:hover { 75 outline: 0; 60 76 } 61 77 62 .press-this #wphead h1 { 63 font-weight: normal; 64 font-size: 16px; 65 line-height: 32px; 66 margin: 0; 67 float: left; 78 abbr[title] { 79 border-bottom: 1px dotted; 68 80 } 69 81 70 .press-this #wphead h1 a { 71 text-decoration: none; 82 b, 83 strong { 84 font-weight: bold; 72 85 } 73 86 74 .press-this #wphead h1 a:hover{75 text-decoration: underline;87 dfn { 88 font-style: italic; 76 89 } 77 90 78 .press-this #message { 79 margin: 10px 0; 91 h1 { 92 font-size: 2em; 93 margin: 0.67em 0; 80 94 } 81 95 82 .press-this .posting { 83 margin-right: 250px; 96 mark { 97 background: #ff0; 98 color: #000; 84 99 } 85 100 86 .press-this-sidebar { 87 float: right; 88 width: 240px; 89 padding-top: 10px; 101 small { 102 font-size: 80%; 90 103 } 91 104 92 .press-this #title { 93 margin-left: 0; 94 margin-right: 0;95 -webkit-box-sizing: border-box;96 -moz-box-sizing: border-box;97 box-sizing: border-box;105 sub, 106 sup { 107 font-size: 75%; 108 line-height: 0; 109 position: relative; 110 vertical-align: baseline; 98 111 } 99 112 100 .press-this .tagchecklist{101 margin-top: 8px;113 sup { 114 top: -0.5em; 102 115 } 103 116 104 .press-this #titlediv{105 margin: 0;117 sub { 118 bottom: -0.25em; 106 119 } 107 120 108 .press-this #wp-content-wrap #wp-content-editor-tools { 109 padding: 0; 110 top: 3px; 121 img { 122 border: 0; 123 } 124 125 svg:not(:root) { 111 126 overflow: hidden; 112 127 } 113 128 114 .press-this .wp-media-buttons { 129 figure { 130 margin: 1em 40px; 131 } 132 133 hr { 134 -webkit-box-sizing: content-box; 135 -moz-box-sizing: content-box; 136 box-sizing: content-box; 137 height: 0; 138 } 139 140 pre { 141 overflow: auto; 142 } 143 144 code, 145 kbd, 146 pre, 147 samp { 148 font-family: monospace, monospace; 149 font-size: 1em; 150 } 151 152 button, 153 input, 154 optgroup, 155 select, 156 textarea { 157 color: inherit; 158 font: inherit; 159 margin: 0; 160 } 161 162 button { 163 overflow: visible; 164 } 165 166 button, 167 select { 168 text-transform: none; 169 } 170 171 button, 172 html input[type="button"], 173 input[type="reset"], 174 input[type="submit"] { 175 -webkit-appearance: button; 176 cursor: pointer; 177 } 178 179 button[disabled], 180 html input[disabled] { 115 181 cursor: default; 116 padding: 8px 8px 6px;117 182 } 118 183 119 .press-this #wp-content-wrap #wp-content-media-buttons a { 184 button::-moz-focus-inner, 185 input::-moz-focus-inner { 186 border: 0; 120 187 padding: 0; 188 } 189 190 input { 121 191 line-height: normal; 192 } 193 194 input[type="checkbox"], 195 input[type="radio"] { 196 -webkit-box-sizing: border-box; 197 -moz-box-sizing: border-box; 198 box-sizing: border-box; 199 padding: 0; 200 } 201 202 input[type="number"]::-webkit-inner-spin-button, 203 input[type="number"]::-webkit-outer-spin-button { 122 204 height: auto; 123 font-size: 16px;124 205 } 125 206 126 .press-this #wp-content-wrap .mce-toolbar .mce-btn-group .mce-btn { 127 margin: 0 1px; 207 input[type="search"] { 208 -webkit-appearance: textfield; 209 -webkit-box-sizing: content-box; 210 -moz-box-sizing: content-box; 211 box-sizing: content-box; 128 212 } 129 213 130 .press-this #wp-content-wrap .mce-toolbar .mce-btn button { 131 padding: 2px 3px; 214 input[type="search"]::-webkit-search-cancel-button, 215 input[type="search"]::-webkit-search-decoration { 216 -webkit-appearance: none; 132 217 } 133 218 134 .press-this #wp-content-wrap div.mce-toolbar-grp, 135 .press-this #wp-content-wrap .quicktags-toolbar { 136 padding-right: 3px; 219 fieldset { 220 border: 1px solid #c0c0c0; 221 margin: 0 2px; 222 padding: 0.35em 0.625em 0.75em; 137 223 } 138 224 139 .press-this .howto { 140 margin-top: 2px; 141 margin-bottom: 3px; 142 font-size: 12px; 143 font-style: italic; 144 display: block; 225 legend { 226 border: 0; 227 padding: 0; 145 228 } 146 229 147 .press-this #wp-content-editor-container{148 clear: none;230 textarea { 231 overflow: auto; 149 232 } 150 233 151 .press-this #poststuff .inside{152 margin-top: 18px;234 optgroup { 235 font-weight: bold; 153 236 } 154 237 155 .press-this .category-tabs { 156 margin-bottom: 3px; 238 table { 239 border-collapse: collapse; 240 border-spacing: 0; 157 241 } 158 242 159 /* Editor/Main Column */ 160 .press-this #poststuff { 161 margin: 0 8px; 243 td, 244 th { 162 245 padding: 0; 163 246 } 164 247 165 .press-this #photo-add-url-div input[type="text"] { 166 width: 220px; 248 .clearfix:before, 249 .clearfix:after { 250 content: ""; 251 display: table; 167 252 } 253 .clearfix:after { 254 clear: both; 255 } 168 256 169 #poststuff #editor-toolbar{170 height: 30px;257 .hide-if-js { 258 display: none; 171 259 } 172 260 173 .posting { 174 margin-right: 212px; 175 position: relative; 261 .screen-reader-text, 262 .taghint { 263 position: absolute; 264 margin: -1px; 265 padding: 0; 266 height: 1px; 267 width: 1px; 268 overflow: hidden; 269 clip: rect(0 0 0 0); 270 border: 0; 176 271 } 177 272 178 .press-this .inner-sidebar { 179 width: 200px; 273 274 /** 275 * Typography 276 * 277 * Base element typographic styles. 278 */ 279 body, 280 button, 281 input, 282 select, 283 textarea { 284 color: #404040; 285 font-family: "Open Sans", Helvetica, Arial, sans-serif; 286 font-size: 20px; 287 font-weight: 400; 288 line-height: 1.6; 180 289 } 181 290 182 .press-this .inner-sidebar .sleeve { 183 padding-top: 5px; 291 h1, 292 h2, 293 h3, 294 h4, 295 h5, 296 h6 { 297 clear: both; 184 298 } 185 299 186 .press-this #submitdiv p { 300 p { 301 margin-bottom: 1.5em; 302 } 303 304 b, 305 strong { 306 font-weight: 700; 307 } 308 309 310 /** 311 * Buttons 312 * 313 * Pushing buttons is what I do. 314 */ 315 .button-primary, 316 .button-subtle, 317 .scan-submit { 318 display: inline-block; 187 319 margin: 0; 188 padding: 6px; 320 padding: 0 10px 1px; 321 border-width: 1px; 322 border-style: solid; 323 -webkit-border-radius: 3px; 324 border-radius: 3px; 325 font-size: 13px; 326 line-height: 2; 327 text-decoration: none; 328 white-space: nowrap; 329 cursor: pointer; 330 -webkit-appearance: none; 189 331 } 190 332 191 .press-this #submitdiv #publishing-actions { 192 border-bottom: 1px solid #dfdfdf; 333 .button-primary { 334 background: #2ea2cc; 335 border-color: #2581a2; 336 color: #fff; 193 337 } 194 338 195 .press-this #publish { 196 float: right; 339 .button-primary:hover, 340 .button-primary:focus { 341 background: #2991b7; 342 border-color: #20708e; 343 color: #fff; 344 outline: 0; 197 345 } 198 346 199 . press-this #poststuff h2,200 .press-this #poststuff h3 { 201 font-size: 14px;202 line-height: 1;347 .button-primary:active { 348 background: #2581a2; 349 border-color: #20708e; 350 color: #fff; 203 351 } 204 352 205 .press-this #tagsdiv-post_tag h3, 206 .press-this #categorydiv h3 { 207 cursor: pointer; 353 .button-primary[disabled], 354 .button-primary:disabled { 355 color: #c7ced1 !important; 356 background: #2688ab !important; 357 border-color: #20708e !important; 208 358 } 209 359 210 . press-this #submitdiv h3{211 c ursor: default;360 .button-primary:visited { 361 color: #fff; 212 362 } 213 363 214 h3.tb{215 font-weight: 600;216 font-size: 12px;217 margin-left: 5px;364 .button-subtle { 365 background: none; 366 border: 0; 367 color: #0074a2; 218 368 } 219 369 220 .press-this .postbox, 221 .press-this .stuffbox { 222 margin-bottom: 10px; 223 min-width: 0; 370 .button-subtle:visited { 371 color: #0074a2; 224 372 } 225 373 226 .press-this #submitdiv:hover .handlediv { 374 .button-subtle:focus, 375 .button-subtle:hover, 376 .button-subtle:active { 377 color: #2ea2cc; 378 } 379 380 .button-subtle:focus, 381 .button-subtle:active { 382 outline: 0; 383 text-decoration: underline; 384 } 385 386 .button-reset { 387 margin: 0; 388 padding: 0; 389 border: 0; 227 390 background: none; 391 cursor: pointer; 392 -webkit-appearance: none; 228 393 } 229 394 230 .tbtitle { 231 font-size: 1.7em; 232 outline: none; 233 padding: 3px 4px; 234 border: 1px solid #dfdfdf; 395 .button-reset:focus { 396 outline: 0; 235 397 } 236 398 237 .press-this .actions { 238 float: right; 239 margin: -19px 0 0; 399 400 /** 401 * Forms 402 * 403 * So many input types. 404 */ 405 button, 406 input, 407 select, 408 textarea { 409 font-size: 100%; 410 margin: 0; 411 vertical-align: baseline; 412 *vertical-align: middle; 240 413 } 241 414 242 .press-this #extra-fields .actions { 243 margin: -32px -7px 0 0; 415 [type="checkbox"], 416 [type="radio"] { 417 padding: 0; 244 418 } 245 419 246 .press-this .actions li { 247 float: left; 248 list-style: none; 249 margin-right: 10px; 420 [type="search"] { 421 -webkit-appearance: textfield; 422 -webkit-box-sizing: content-box; 423 -moz-box-sizing: content-box; 424 box-sizing: content-box; 250 425 } 251 426 252 #extra-fields .button {253 margin-right: 5px;427 [type="search"]::-webkit-search-decoration { 428 -webkit-appearance: none; 254 429 } 255 430 256 /* Photo Styles */ 257 #photo_saving{258 margin: 0 8px 8px;259 vertical-align: middle;431 button::-moz-focus-inner, 432 input::-moz-focus-inner { 433 border: 0; 434 padding: 0; 260 435 } 261 436 262 #img_container_container { 437 [type="text"], 438 [type="email"], 439 [type="url"], 440 [type="password"], 441 [type="search"], 442 textarea { 443 padding: 0.4em 0.75em; 444 color: #333; 445 border: 1px solid #ccc; 446 } 447 448 [type="text"]:focus, 449 [type="email"]:focus, 450 [type="url"]:focus, 451 [type="password"]:focus, 452 [type="search"]:focus, 453 textarea:focus { 454 color: #333; 455 outline: 0; 456 } 457 458 textarea { 263 459 overflow: auto; 460 padding-left: 3px; 461 vertical-align: top; 264 462 } 265 463 266 #extra-fields { 267 margin-top: 10px; 464 465 /** 466 * Links 467 */ 468 a { 469 color: #0074a2; 470 } 471 472 a:visited { 473 color: #0074a2; 474 } 475 476 a:hover, 477 a:focus, 478 a:active { 479 color: #2ea2cc; 480 } 481 482 483 /** 484 * Lists 485 */ 486 ul, 487 ol { 488 margin: 0 0 1.5em 3em; 489 } 490 491 ul { 492 list-style: disc; 493 } 494 495 ol { 496 list-style: decimal; 497 } 498 499 li > ul, 500 li > ol { 501 margin-bottom: 0; 502 margin-left: 1.5em; 503 } 504 505 dt { 506 font-weight: 700; 507 } 508 509 dd { 510 margin: 0 1.5em 1.5em; 511 } 512 513 514 /** 515 * Post formats 516 * 517 * Complete styles for post formats UI 518 */ 519 /* TODO if we remove the <br> during merge, this can go. */ 520 #post-formats-select br { 521 display: none; 522 } 523 524 /* TODO Needed after merge? */ 525 .post-format { 526 width: 0; 527 height: 0; 528 position: absolute; 529 top: -9999px; 530 } 531 532 .lt-ie9 .post-format { 533 margin: 17px 12px 0 13px; 534 width: auto; 535 height: auto; 536 position: static; 537 top: auto; 538 float: left; 539 width: 16px; 540 height: 16px; 541 } 542 543 .post-format-icon { 268 544 position: relative; 545 display: block; 546 padding: 13px 2px 14px 13px; 547 cursor: pointer; 269 548 } 270 549 271 #extra-fields h2 { 272 margin: 12px; 550 .post-format-icon:before, 551 .post-format-icon:after { 552 content: ""; 553 display: inline-block; 554 width: 20px; 555 height: 20px; 556 margin-right: 10px; 557 font-size: 20px; 558 line-height: 1; 559 font-family: dashicons; 560 text-decoration: inherit; 561 color: #9ea7af; 562 font-weight: 400; 563 font-style: normal; 564 vertical-align: top; 565 text-align: center; 566 -webkit-transition: color .1s ease-in 0; 567 transition: color .1s ease-in 0; 568 -webkit-font-smoothing: antialiased; 569 -moz-osx-font-smoothing: grayscale; 273 570 } 274 571 275 #waiting { 276 margin-top: 10px; 277 overflow: hidden; 572 .post-format-icon:before { 573 content: "\f109"; 278 574 } 279 575 280 #waiting span { 576 .post-format-icon:after { 577 display: none; 578 content: "\f147"; 281 579 float: right; 282 margin: 0 0 0 5px;283 580 } 284 581 285 #waiting .spinner { 582 .post-format:checked + .post-format-icon { 583 -webkit-box-shadow: inset 6px 0 0 #2ea2cc; 584 box-shadow: inset 6px 0 0 #2ea2cc; 585 background: rgba(46, 162, 204, 0.1); 586 } 587 588 .post-format:checked + .post-format-icon:before, 589 .post-format:checked + .post-format-icon:after { 590 color: #333; 591 } 592 593 .post-format:focus + .post-format-icon { 594 background: #2ea2cc; 595 color: #fff; 596 } 597 598 .post-format:focus + .post-format-icon:before, 599 .post-format:focus + .post-format-icon:after { 600 color: #fff; 601 } 602 603 .post-format:checked + .post-format-icon:after { 286 604 display: block; 287 605 } 288 606 289 #extra-fields .postbox{290 margin- bottom: 5px;607 .lt-ie9 .post-format-icon { 608 margin-left: 16px; 291 609 } 292 610 293 #extra-fields .titlewrap { 611 .post-format-aside:before { 612 content: "\f123"; 613 } 614 615 .post-format-image:before { 616 content: "\f128"; 617 } 618 619 .post-format-video:before { 620 content: "\f126"; 621 } 622 623 .post-format-audio:before { 624 content: "\f127"; 625 } 626 627 .post-format-quote:before { 628 content: "\f122"; 629 } 630 631 .post-format-link:before { 632 content: "\f103"; 633 } 634 635 .post-format-gallery:before { 636 content: "\f161"; 637 } 638 639 640 /** 641 * Tags 642 * 643 * Complete styles for tags UI 644 */ 645 .tagsdiv p { 646 margin: 0; 647 } 648 649 .tagsdiv .ajaxtag { 650 position: relative; 651 } 652 653 .tagsdiv .newtag { 654 display: block; 655 position: relative; 656 padding: 11px 58px 11px 16px; 657 width: 100%; 658 border: 0; 659 border-bottom: 1px solid #e5e5e5; 660 font-size: 16px; 661 } 662 663 .tagsdiv .tagadd { 664 position: absolute; 665 top: 0; 666 right: 0; 667 bottom: 1px; 668 border: 0; 669 -webkit-border-radius: 0; 670 border-radius: 0; 671 padding: 0 16px; 672 background: #f7f7f7; 673 border-left: 1px solid #f1f1f1; 674 } 675 676 .tagsdiv .tagadd:hover, 677 .tagsdiv .tagadd:active, 678 .tagsdiv .tagadd:focus { 679 outline: 0; 680 background: #2991b7; 681 border-color: #20708e; 682 color: #fff; 683 } 684 685 .tagsdiv .howto { 686 color: #727272; 687 font-style: italic; 688 margin: 10px 0 6px 16px; 689 } 690 691 692 /* Tag hint TODO needed? */ 693 /* Tag suggestions */ 694 .ac_results { 294 695 padding: 0; 295 overflow: auto; 296 height: 120px; 696 margin: -1px 0 0 -1px; 697 list-style: none; 698 position: absolute; 699 z-index: 10000; 700 display: none; 701 border: 1px solid #d8d8d8; 702 background-color: #fff; 703 font-size: 14px; 297 704 } 298 705 299 #img_container a { 706 .ac_results li { 707 padding: 6px 16px; 708 white-space: nowrap; 709 color: #101010; 710 text-align: left; 711 } 712 713 .ac_results .ac_over { 714 background-color: #e5e5e5; 715 background-color: #2ea2cc; 716 color: #fff; 717 cursor: pointer; 718 } 719 720 .ac_match { 721 text-decoration: underline; 722 } 723 724 /* Tags */ 725 .tagchecklist { 726 padding: 16px 28px 5px; 727 } 728 729 .tagchecklist:before, 730 .tagchecklist:after { 731 content: ""; 732 display: table; 733 } 734 735 .tagchecklist:after { 736 clear: both; 737 } 738 739 .tagchecklist span { 300 740 display: block; 741 margin-right: 25px; 301 742 float: left; 743 font-size: 13px; 744 line-height: 1.8; 745 white-space: nowrap; 746 cursor: default; 747 } 748 749 @media (max-width: 600px) { 750 .tagchecklist span { 751 margin-bottom: 15px; 752 font-size: 16px; 753 line-height: 1.3; 754 } 755 } 756 757 .tagchecklist .ntdelbutton { 758 margin: 1px 0 0 -17px; 759 cursor: pointer; 760 width: 20px; 761 height: 20px; 762 display: block; 763 float: left; 764 text-indent: 0; 302 765 overflow: hidden; 766 position: absolute; 767 outline: 0; 303 768 } 304 769 305 #img_container img, 306 #img_container a { 307 width: 68px; 308 height: 68px; 770 .tagchecklist .ntdelbutton:before { 771 content: '\f153'; 772 display: block; 773 margin: 2px 0; 774 height: 20px; 775 width: 20px; 776 background: 0 0; 777 color: #9ea7af; 778 font: 400 16px/1 dashicons; 779 text-align: center; 780 speak: none; 781 -webkit-font-smoothing: antialiased; 309 782 } 310 783 311 #img_container img { 784 .tagchecklist .ntdelbutton:focus:before { 785 color: #2ea2cc; 786 } 787 788 789 /* THE TAG CLOUD. */ 790 .tagsdiv + p { 791 margin: 0; 792 } 793 794 .tagcloud-link { 795 display: block; 796 padding: 0 16px; 797 text-decoration: none; 798 outline: 0; 799 } 800 801 .tagcloud-link:focus { 802 text-decoration: underline; 803 } 804 805 .popular-tags { 312 806 border: none; 313 background-color: #f4f4f4; 807 line-height: 2em; 808 padding: 8px 12px 12px; 809 text-align: justify; 810 } 811 812 .popular-tags a { 813 padding: 0 3px; 814 } 815 816 .the-tagcloud { 817 margin: 0; 818 padding: 16px; 819 } 820 821 .the-tagcloud a { 822 text-decoration: none; 823 outline: 0; 824 } 825 826 .the-tagcloud a:focus { 827 text-decoration: underline; 828 } 829 830 .tagcloud h3 { 831 margin: 2px 0 12px; 832 } 833 834 835 /** 836 * Categories 837 * 838 * Complete styles for post categories UI 839 */ 840 input[type="search"].categories-search, 841 .add-category-name { 842 display: block; 843 width: 100%; 844 padding: 0.85714em 1.07143em; 845 border: 0; 846 -webkit-border-radius: 0; 847 border-radius: 0; 848 border-bottom: 1px solid #e5e5e5; 849 font-size: 14px; 850 -webkit-appearance: none; 851 appearance: none; 852 } 853 854 @media (max-width: 600px) { 855 input[type="search"].categories-search, 856 .add-category-name { 857 /* Needs to be 16px to prevent zooming on iOS. Guh. */ 858 font-size: 16px; 859 } 860 } 861 862 .add-cat-toggle { 863 float: right; 864 margin-top: -33px; 865 } 866 867 .add-cat-toggle:focus { 868 text-decoration: none; 869 color: #2ea2cc; 870 } 871 872 .add-cat-toggle.is-toggled { 873 margin-top: -36px; 874 } 875 876 .add-cat-toggle.is-toggled .dashicons:before { 877 content: "\f179"; 878 } 879 880 .add-category { 881 position: relative; 882 border-bottom: 1px solid #e5e5e5; 883 } 884 885 .add-category.is-hidden { 886 display: none; 887 } 888 889 .add-category .add-cat-submit { 890 position: absolute; 891 top: 0; 892 right: 0; 893 border: 0; 894 -webkit-border-radius: 0; 895 border-radius: 0; 896 padding: 12px 16px; 897 background: #f7f7f7; 898 border-left: 1px solid #f1f1f1; 899 } 900 901 .add-category .add-cat-submit:hover, 902 .add-category .add-cat-submit:active, 903 .add-category .add-cat-submit:focus { 904 outline: 0; 905 background: #2991b7; 906 border-color: #20708e; 907 color: #fff; 908 } 909 910 /* Parent category select */ 911 .postform-wrapper { 912 padding: 12px; 913 } 914 915 .postform { 916 display: block; 917 margin: 0; 918 width: 100%; 919 height: 34px; 920 border: 0; 921 -webkit-border-radius: 0; 922 border-radius: 0; 923 border: 1px solid #e5e5e5; 924 background: #fff; 925 -webkit-background-size: 20px 20px; 926 background-size: 20px 20px; 927 overflow: hidden; 928 line-height: 21px; 929 text-overflow: ellipsis; 930 text-decoration: none; 931 vertical-align: top; 932 white-space: nowrap; 314 933 cursor: pointer; 934 outline: 0; 315 935 } 316 936 317 #img_container a, 318 #img_container a:link, 319 #img_container a:visited { 320 border: 1px solid #ccc; 937 .postform:focus { 938 border-color: #0074a2; 939 -webkit-box-shadow: 0 0 0 3px #2ea2cc; 940 box-shadow: 0 0 0 3px #2ea2cc; 941 outline: 0; 942 -moz-outline: none; 943 -moz-user-focus: ignore; 944 } 945 946 .postform::-ms-expand { 947 display: none; 948 } 949 950 .postform::-ms-value { 951 background: none; 952 color: #727272; 953 } 954 955 .postform:-moz-focusring { 956 color: transparent; 957 text-shadow: 0 0 0 #727272; 958 } 959 960 /* Category list */ 961 .categories-select { 962 margin: 0; 963 padding: 0; 964 list-style: none; 965 } 966 967 .categories-select ul { 968 margin: 0; 969 padding: 0; 970 list-style: none; 971 } 972 973 .categories-select input { 974 clear: none; 975 position: absolute; 976 top: 0; 977 left: 0; 321 978 display: block; 979 line-height: 0; 980 width: 100%; 981 height: 100%; 982 outline: 0; 983 padding: 0; 984 border: 0; 985 -webkit-border-radius: 0; 986 border-radius: 0; 987 text-align: center; 988 vertical-align: middle; 989 -webkit-appearance: none; 990 appearance: none; 991 cursor: pointer; 992 } 993 994 .categories-select input:checked { 995 -webkit-box-shadow: inset 6px 0 0 #2ea2cc; 996 box-shadow: inset 6px 0 0 #2ea2cc; 997 background: rgba(46, 162, 204, 0.1); 998 } 999 1000 .categories-select input:checked:after { 1001 display: inline-block; 1002 content: "\f147"; 1003 position: absolute; 1004 top: 13px; 1005 right: 0; 1006 width: 20px; 1007 height: 20px; 1008 margin-right: 10px; 1009 font-size: 20px; 1010 line-height: 1; 1011 font-family: dashicons; 1012 text-decoration: inherit; 1013 color: #222; 1014 font-weight: 400; 1015 font-style: normal; 1016 vertical-align: top; 1017 text-align: center; 1018 -webkit-transition: color .1s ease-in 0; 1019 transition: color .1s ease-in 0; 1020 -webkit-font-smoothing: antialiased; 1021 -moz-osx-font-smoothing: grayscale; 1022 } 1023 1024 .categories-select input:focus { 1025 -webkit-box-shadow: inset 6px 0 0 #2ea2cc; 1026 box-shadow: inset 6px 0 0 #2ea2cc; 1027 background: rgba(46, 162, 204, 0.05); 1028 } 1029 1030 .categories-select label { 322 1031 position: relative; 1032 display: block; 1033 padding: 13px 16px 14px 16px; 1034 cursor: pointer; 1035 background: #fff; 323 1036 } 324 1037 325 #img_container a:hover, 326 #img_container a:active { 327 border-color: #000; 328 z-index: 1000; 329 border-width: 1px; 1038 .categories-select ul label { 1039 padding-left: 24px; 330 1040 } 331 1041 332 /* Video */ 333 #embed-code { 1042 .categories-select ul ul label { 1043 padding-left: 32px; 1044 } 1045 1046 .categories-select ul ul ul label { 1047 padding-left: 40px; 1048 } 1049 1050 .categories-select ul ul ul ul label { 1051 padding-left: 48px; 1052 } 1053 1054 .categories-select ul ul ul ul ul label { 1055 padding-left: 56px; 1056 } 1057 1058 .categories-select ul ul ul ul ul ul label { 1059 padding-left: 64px; 1060 } 1061 1062 .categories-select .is-hidden { 1063 display: none; 1064 } 1065 1066 .categories-select .is-hidden.searched-parent { 1067 display: block; 1068 } 1069 1070 .lt-ie9 .categories-select input { 1071 top: 50%; 1072 right: 10px; 1073 left: auto; 1074 margin-top: -8px; 1075 width: 16px; 1076 height: 16px; 1077 } 1078 1079 /* TODO Reformats checkbox on Firefox until we remove checkbox in merge */ 1080 @-moz-document url-prefix() { 1081 .categories-select input { 1082 top: 50%; 1083 right: 10px; 1084 left: auto; 1085 margin-top: -8px; 1086 width: 16px; 1087 height: 16px; 1088 } 1089 } 1090 1091 /* Category search */ 1092 .categories-search-wrapper { 1093 position: relative; 1094 } 1095 1096 .categories-search-wrapper.is-hidden { 1097 display: none; 1098 } 1099 1100 .categories-search-wrapper label { 1101 position: absolute; 1102 top: 50%; 1103 right: 10px; 1104 margin-top: -10px; 1105 color: #9ea7af; 1106 } 1107 1108 1109 /** 1110 * Main 1111 */ 1112 html, 1113 body { 1114 overflow-x: hidden; 1115 } 1116 1117 @media (min-width: 901px) { 1118 html, 1119 body { 1120 height: 100%; 1121 } 1122 } 1123 1124 html { 1125 background: #fff; 1126 -webkit-box-shadow: -10px 0 0 rgba(0, 0, 0, 0.3); 1127 box-shadow: -10px 0 0 rgba(0, 0, 0, 0.3); 1128 } 1129 1130 @media (max-width: 900px) { 1131 body { 1132 font-size: 16px; 1133 } 1134 } 1135 1136 @media (max-width: 320px) { 1137 body { 1138 font-size: 14px; 1139 } 1140 } 1141 1142 .lt-ie9 { 1143 overflow: visible; 1144 } 1145 1146 .adminbar { 1147 position: relative; 334 1148 width: 100%; 335 height: 98px; 1149 padding: 0 0.8em; 1150 min-height: 3.2em; 1151 background: #222; 1152 color: #fff; 1153 z-index: 9999; 336 1154 } 337 1155 338 /* Categories */ 339 .press-this .categorydiv div.tabs-panel { 340 height: 100px; 1156 .adminbar:before, 1157 .adminbar:after { 1158 content: ""; 1159 display: table; 341 1160 } 342 1161 343 /* Tags */ 344 .press-this .tagsdiv .newtag { 345 width: 120px; 1162 .adminbar:after { 1163 clear: both; 346 1164 } 347 1165 348 .press-this #content { 349 margin: 5px 0; 350 padding: 0 5px; 351 border: 0 none; 352 height: 340px; 353 font-family: Consolas, Monaco, monospace; 354 font-size: 13px; 355 line-height: 19px; 356 background: transparent; 1166 .adminbar .dashicons { 1167 color: #999; 357 1168 } 358 1169 359 /* Submit */ 360 .press-this #publishing-actions .spinner { 361 display: inline; 1170 .adminbar button { 1171 position: absolute; 1172 top: 50%; 1173 right: 6px; 1174 margin-top: -13px; 1175 } 1176 1177 @media (max-width: 320px) { 1178 .adminbar { 1179 min-height: 45px; 1180 } 1181 } 1182 1183 .current-site { 1184 margin-top: 0.5625em; 1185 font-size: 16px; 1186 line-height: 44px; 1187 font-weight: 400; 1188 overflow: hidden; 1189 white-space: nowrap; 1190 text-overflow: ellipsis; 1191 } 1192 1193 @media (max-width: 600px) { 1194 .current-site { 1195 margin: 3px 0 0; 1196 } 1197 } 1198 1199 @media (max-width: 320px) { 1200 .current-site { 1201 margin: 0; 1202 font-size: 14px; 1203 } 1204 } 1205 1206 .current-site span:nth-child(2) { 1207 color: #ededed; 1208 } 1209 1210 @media (max-width: 320px) { 1211 .current-site span:nth-child(2) { 1212 font-weight: 600; 1213 } 1214 } 1215 1216 .current-site .dashicons-wordpress { 1217 position: relative; 1218 top: -1px; 1219 margin-right: 10px; 362 1220 vertical-align: middle; 363 1221 } 364 1222 365 /* =Media Queries 366 -------------------------------------------------------------- */ 1223 .options-open, 1224 .options-close { 1225 display: none; 1226 } 367 1227 368 /* Reset responsive styles in Press This */ 369 @media screen and ( max-width: 782px ) { 370 . press-this ul.category-tabs li.tabs{371 padding: 3px 5px 5px; /* Reset tabs in Press This to standard size */1228 @media (max-width: 900px) { 1229 .options-open, 1230 .options-close { 1231 display: block; 372 1232 } 1233 } 373 1234 374 .press-this a.wp-switch-editor { 375 font: 13px/19px "Open Sans", sans-serif; 376 margin: 5px 0 0 5px; 377 padding: 3px 8px 4px; 1235 .options-open.is-hidden, 1236 .options-close.is-hidden { 1237 display: none; 1238 } 1239 1240 .options-open:focus .dashicons { 1241 color: #fff; 1242 text-decoration: none; 1243 } 1244 1245 .options-open .dashicons { 1246 margin-top: 3px; 1247 } 1248 1249 .options-close { 1250 color: #2ea2cc; 1251 } 1252 1253 .alert { 1254 position: relative; 1255 margin: 0; 1256 padding: 16px 50px; 1257 border-bottom: 1px solid #e5e5e5; 1258 font-size: 14px; 1259 } 1260 1261 .alert:before { 1262 content: ''; 1263 position: absolute; 1264 top: 50%; 1265 left: 30px; 1266 width: 8px; 1267 height: 8px; 1268 margin-top: -4px; 1269 -webkit-border-radius: 50%; 1270 border-radius: 50%; 1271 background: #2ea2cc; 1272 } 1273 1274 @media (max-width: 600px) { 1275 .alert { 1276 padding: 16px 35px; 378 1277 } 1278 .alert:before { 1279 left: 15px; 1280 } 1281 } 379 1282 380 .press-this #wp-content-media-buttons a { 381 padding: 0; 382 line-height: normal; 383 height: auto; 1283 .alert.is-hidden { 1284 display: none; 1285 } 1286 .alert.is-error:before { 1287 background: red; 1288 } 1289 1290 .scan { 1291 position: relative; 1292 border-bottom: 1px solid #e5e5e5; 1293 } 1294 1295 @media (max-width: 900px) { 1296 .scan form { 1297 -webkit-transition: opacity .3s ease-in-out; 1298 transition: opacity .3s ease-in-out; 384 1299 } 1300 .scan.is-hidden form { 1301 opacity: .2; 1302 pointer-events: none; 1303 } 1304 } 385 1305 386 .press-this #wp-content-editor-tools { 387 padding: 0; 388 top: 3px; 1306 .scan-url { 1307 display: block; 1308 border: 0; 1309 padding: 0.85714em 1.07143em; 1310 font-size: 14px; 1311 width: 100%; 1312 } 1313 1314 @media (max-width: 600px) { 1315 .scan-url { 1316 font-size: 16px; 389 1317 } 1318 } 390 1319 391 .press-this .category-tabs { 392 margin-top: 0; 1320 .scan-submit { 1321 position: absolute; 1322 top: 0; 1323 right: 0; 1324 bottom: 0; 1325 padding: 0.85714em 1.07143em; 1326 background: #f7f7f7; 1327 border-color: #dedede; 1328 border-bottom: 0; 1329 border-left: 1px solid #f1f1f1; 1330 -webkit-border-radius: 0; 1331 border-radius: 0; 1332 color: #555; 1333 font-size: 14px; 1334 line-height: 1.6; 1335 } 1336 1337 .scan-submit:hover, 1338 .scan-submit:focus { 1339 background: #2991b7; 1340 border-color: #20708e; 1341 color: #fff; 1342 outline: 0; 1343 } 1344 1345 .scan-submit:active { 1346 background: #2581a2; 1347 border-color: #20708e; 1348 color: #fff; 1349 } 1350 1351 .scan-submit:visited { 1352 color: #555; 1353 } 1354 1355 .wrapper { 1356 position: relative; 1357 margin-bottom: 60px; 1358 margin-right: 320px; 1359 } 1360 1361 .wrapper:before, 1362 .wrapper:after { 1363 content: ""; 1364 display: table; 1365 } 1366 1367 .wrapper:after { 1368 clear: both; 1369 } 1370 1371 @media (max-width: 900px) { 1372 .wrapper { 1373 margin: 0; 1374 width: 100%; 393 1375 } 1376 } 394 1377 395 .press-this .tagsdiv .newtag { 396 width: 120px; 397 padding: 3px 5px; 398 margin-bottom: 0; 1378 .editor-wrapper { 1379 overflow: auto; 1380 float: left; 1381 width: 100%; 1382 } 1383 1384 .editor-wrapper:before, 1385 .editor-wrapper:after { 1386 content: ""; 1387 display: table; 1388 } 1389 1390 .editor-wrapper:after { 1391 clear: both; 1392 } 1393 1394 .editor { 1395 padding: 0 1.5em 4.75em; 1396 max-width: 700px; 1397 margin: 0 auto; 1398 } 1399 1400 @media (min-width: 901px) { 1401 .editor { 1402 max-width: 760px; 399 1403 } 1404 } 400 1405 401 .press-this .tagchecklist { 1406 @media (max-width: 320px) { 1407 .editor { 402 1408 padding: 0; 403 margin-bottom: 0;404 1409 } 1410 } 405 1411 406 .press-this .wp_themeSkin a.mceButton { 407 width: 20px; 408 height: 20px; 1412 .post-title, 1413 .post-title-placeholder { 1414 margin: 0; 1415 padding: .83em 0; 1416 width: 100%; 1417 border-bottom: 1px solid #e5e5e5; 1418 font-size: 32px; 1419 line-height: 1.4; 1420 font-weight: 700; 1421 } 1422 1423 .post-title:active, 1424 .post-title:focus, 1425 .post-title-placeholder:active, 1426 .post-title-placeholder:focus { 1427 outline: 0; 1428 -webkit-box-shadow: inset 0px -3px 0 #2ea2cc; 1429 box-shadow: inset 0px -3px 0 #2ea2cc; 1430 border-color: #2ea2cc; 1431 } 1432 1433 @media (max-width: 900px) { 1434 .post-title, 1435 .post-title-placeholder { 1436 font-size: 24px; 409 1437 } 1438 } 410 1439 411 .press-this .wp_themeSkin .mceButton .mceIcon { 412 margin: 0; 1440 @media (max-height: 400px) { 1441 .post-title, 1442 .post-title-placeholder { 1443 padding: 15px 0; 1444 font-size: 16px; 413 1445 } 1446 } 414 1447 415 .press-this #poststuff h3, 416 .press-this .metabox-holder h3 { 417 padding: 7px 12px; 1448 @media (max-width: 320px) { 1449 .post-title, 1450 .post-title-placeholder { 1451 font-size: 16px; 1452 font-weight: 600; 1453 padding: 1.14286em 1.42857em; 418 1454 } 1455 } 419 1456 420 .press-this input[type=checkbox], 421 .press-this input[type=radio] { 422 height: 16px; 423 width: 16px; 1457 .post-title { 1458 /* IE8 fallback */ 1459 background: url(data:image/gif;base64,R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEHAAIALAAAAAABAAEAAAICVAEAOw==); 1460 background: none, none; 1461 } 1462 1463 .post-title:before { 1464 /* Keeps empty container from collapsing */ 1465 content: '\a0'; 1466 display: inline-block; 1467 width: 0; 1468 speak: none; 1469 } 1470 1471 .post-title-placeholder { 1472 position: absolute; 1473 border: 0; 1474 color: #9ea7af; 1475 z-index: -1; 1476 } 1477 1478 .post-title-placeholder.is-hidden { 1479 display: none; 1480 } 1481 1482 /* Suggested images */ 1483 .featured-container { 1484 position: relative; 1485 padding: 2px 0; 1486 border-bottom: 1px solid #e5e5e5; 1487 } 1488 1489 .all-media { 1490 display: none; 1491 overflow: auto; 1492 max-height: 150px; 1493 max-height: 40vw; 1494 } 1495 1496 .all-media:before, .all-media:after { 1497 content: ""; 1498 display: table; 1499 } 1500 1501 .all-media:after { 1502 clear: both; 1503 } 1504 1505 @media (min-width: 321px) { 1506 .all-media { 1507 max-height: 250px; 1508 max-height: 40vw; 424 1509 } 1510 } 425 1511 426 .press-this input[type=checkbox]:checked:before{427 width: 16px;428 font: normal 21px/1 'dashicons';429 ma rgin: -3px 0 0 -4px;1512 @media (min-width: 601px) { 1513 .all-media { 1514 max-height: 200px; 1515 max-height: 18.75vw; 430 1516 } 1517 } 431 1518 432 .press-this input[type=radio]:checked:before { 433 font: normal 21px/1 'dashicons'; 434 width: 6px; 435 height: 6px; 436 margin: 4px; 1519 .wppt-all-media-list { 1520 list-style: none; 1521 margin: 0; 1522 padding: 0; 1523 } 1524 1525 .suggested-media-thumbnail:focus, 1526 .suggested-media-embed:focus { 1527 outline: 0; 1528 -webkit-box-shadow: inset 0 0 0 3px #2ea2cc; 1529 box-shadow: inset 0 0 0 3px #2ea2cc; 1530 } 1531 1532 .suggested-media-thumbnail { 1533 position: relative; 1534 display: block; 1535 float: left; 1536 width: 16.66%; 1537 padding: 16.66% 0 0 16.66%; 1538 background-position: center; 1539 background-repeat: no-repeat; 1540 -webkit-background-size: cover; 1541 background-size: cover; 1542 background-color: #d8d8d8; 1543 color: #fff; 1544 color: rgba(255, 255, 255, 0.6); 1545 cursor: pointer; 1546 } 1547 1548 .suggested-media-thumbnail:hover, 1549 .suggested-media-thumbnail:active, 1550 .suggested-media-thumbnail:focus { 1551 color: #fff; 1552 } 1553 1554 .suggested-media-thumbnail:before, 1555 .suggested-media-thumbnail:after { 1556 display: inline-block; 1557 position: absolute; 1558 font-size: 20px; 1559 line-height: 1; 1560 font-family: dashicons; 1561 text-decoration: inherit; 1562 font-weight: 400; 1563 font-style: normal; 1564 -webkit-transition: color .1s ease-in 0; 1565 transition: color .1s ease-in 0; 1566 -webkit-font-smoothing: antialiased; 1567 -moz-osx-font-smoothing: grayscale; 1568 } 1569 1570 .suggested-media-thumbnail:before { 1571 left: 50%; 1572 top: 50%; 1573 margin: -20px 0 0 -20px; 1574 font-size: 40px; 1575 } 1576 1577 .suggested-media-thumbnail:after { 1578 content: "\f132"; 1579 right: 3%; 1580 bottom: 2%; 1581 } 1582 1583 @media (min-width: 601px) { 1584 .suggested-media-thumbnail { 1585 width: 12.5%; 1586 padding: 12.5% 0 0 12.5%; 437 1587 } 1588 } 438 1589 439 .press-this ul.categorychecklist ul, 440 .press-this ul.categorychecklist li { 441 margin-top: 0; 442 margin-bottom: 0; 1590 .suggested-media-embed:before { 1591 content: "\f104"; 1592 color: #fff; 1593 color: rgba(255, 255, 255, 0.9); 1594 } 1595 1596 .suggested-media-embed.is-audio:hover:before, 1597 .suggested-media-embed.is-audio:active:before, 1598 .suggested-media-embed.is-audio:focus:before, 1599 .suggested-media-embed.is-tweet:hover:before, 1600 .suggested-media-embed.is-tweet:active:before, 1601 .suggested-media-embed.is-tweet:focus:before { 1602 color: #fff; 1603 } 1604 1605 .suggested-media-embed.is-video { 1606 background-color: #222; 1607 } 1608 1609 .suggested-media-embed.is-video:hover:before, 1610 .suggested-media-embed.is-video:active:before, 1611 .suggested-media-embed.is-video:focus:before { 1612 color: rgba(255, 255, 255, 0.2); 1613 } 1614 1615 .suggested-media-embed.is-video:before { 1616 content: "\f236"; 1617 } 1618 1619 .suggested-media-embed.is-audio { 1620 background-color: #ff7d44; 1621 } 1622 1623 .suggested-media-embed.is-audio:before { 1624 content: "\f127"; 1625 } 1626 1627 .suggested-media-embed.is-tweet { 1628 background-color: #55acee; 1629 } 1630 1631 .suggested-media-embed.is-tweet:before { 1632 content: "\f301"; 1633 } 1634 1635 .all-media-visible .all-media { 1636 display: block; 1637 } 1638 1639 .no-media { 1640 margin: 0; 1641 padding: 0; 1642 border: 0; 1643 } 1644 1645 /* Actions bar */ 1646 .press-this-actions { 1647 position: fixed; 1648 bottom: 0; 1649 left: 0; 1650 width: 100%; 1651 background: #f1f1f1; 1652 background: rgba(241, 241, 241, 0.9); 1653 border-top: 1px solid #e5e5e5; 1654 } 1655 1656 @media (max-width: 900px) { 1657 .press-this-actions { 1658 -webkit-transform: translateY(0); 1659 -ms-transform: translateY(0); 1660 transform: translateY(0); 1661 -webkit-transition: -webkit-transform .3s ease-in-out; 1662 transition: transform .3s ease-in-out; 443 1663 } 1664 .press-this-actions.is-hidden { 1665 -webkit-transform: translateY(100%); 1666 -ms-transform: translateY(100%); 1667 transform: translateY(100%); 1668 } 1669 } 444 1670 445 .press-this div.quicktags-toolbar input { 446 padding: 2px 4px; 1671 .add-media { 1672 float: left; 1673 margin: 14px 0 14px 30px; 1674 font-size: 0; 1675 } 1676 1677 @media (max-width: 320px) { 1678 .add-media { 1679 margin: 10px 0 10px 10px; 447 1680 } 1681 } 448 1682 449 .press-this textarea, 450 .press-this input { 451 font-size: 14px; 1683 .insert-media { 1684 color: #9ea7af; 1685 float: left; 1686 margin: 0; 1687 padding: 0; 1688 border: 0; 1689 border-right: 1px solid #e5e5e5; 1690 -webkit-border-radius: 0; 1691 border-radius: 0; 1692 background: none; 1693 -webkit-box-shadow: none; 1694 box-shadow: none; 1695 overflow: hidden; 1696 } 1697 1698 .insert-media:hover, 1699 .insert-media:focus, 1700 .insert-media:active { 1701 margin: 0; 1702 background: none; 1703 border-color: #e5e5e5; 1704 color: #222; 1705 } 1706 1707 .insert-media:focus, 1708 .insert-media:active { 1709 outline: 0; 1710 color: #2ea2cc; 1711 text-decoration: none; 1712 } 1713 1714 .insert-media .dashicons { 1715 padding: 11px; 1716 width: 63px; 1717 height: 58px; 1718 font-size: 40px; 1719 } 1720 1721 @media (max-width: 320px) { 1722 .insert-media .dashicons { 1723 width: 55px; 1724 height: 49px; 1725 padding: 14px; 1726 font-size: 20px; 452 1727 } 1728 } 453 1729 454 .press-this .tagchecklist span { 455 font-size: 13px; 456 line-height: 1.8em; 1730 .post-actions { 1731 float: right; 1732 margin: 14px 30px 14px 0; 1733 font-size: 0; 1734 } 1735 1736 @media (max-width: 320px) { 1737 .post-actions { 1738 margin: 10px 10px 10px 0; 457 1739 } 458 1740 } 1741 1742 /* TinyMCE styles */ 1743 .editor .wp-media-buttons { 1744 float: none; 1745 } 1746 1747 .editor div.mce-toolbar-grp { 1748 padding: 0.71429em 0; 1749 background: none; 1750 border: 0; 1751 } 1752 1753 @media (max-height: 400px), (max-width: 320px) { 1754 .editor div.mce-toolbar-grp { 1755 padding: 0; 1756 } 1757 } 1758 1759 .mce-stack-layout:before, 1760 .mce-stack-layout:after { 1761 content: ""; 1762 display: table; 1763 } 1764 1765 .mce-stack-layout:after { 1766 clear: both; 1767 } 1768 1769 .mce-container.mce-toolbar { 1770 float: left; 1771 } 1772 1773 .mce-container.mce-toolbar:nth-child(2) { 1774 float: right; 1775 } 1776 1777 @media (max-width: 600px) { 1778 #mceu_11, 1779 #mceu_12 { 1780 position: absolute; 1781 margin: -1px; 1782 padding: 0; 1783 height: 1px; 1784 width: 1px; 1785 overflow: hidden; 1786 clip: rect(0 0 0 0); 1787 border: 0; 1788 } 1789 1790 #mceu_11:focus, 1791 #mceu_12:focus { 1792 position: static; 1793 margin: 1px; 1794 padding: inherit; 1795 height: auto; 1796 width: auto; 1797 overflow: visible; 1798 clip: auto; 1799 border: 1px solid #999; 1800 } 1801 } 1802 1803 #wp-link-wrap.search-panel-visible { 1804 font-size: 13px; 1805 } 1806 1807 /* Options panel (sidebar) */ 1808 .options-panel { 1809 position: relative; 1810 float: right; 1811 margin-right: -320px; 1812 width: 320px; 1813 border-left: 1px solid #e5e5e5; 1814 font-size: 14px; 1815 /* Keeps background the full height of the screen */ 1816 -webkit-box-shadow: 5001px 5000px 0 5000px #fff, 5000px 5000px 0 5000px #e5e5e5; 1817 box-shadow: 5001px 5000px 0 5000px #fff, 5000px 5000px 0 5000px #e5e5e5; 1818 } 1819 1820 @media (max-width: 900px) { 1821 .options-panel { 1822 background: #fff; 1823 -webkit-transform: translateX(-100%); 1824 -ms-transform: translateX(-100%); 1825 transform: translateX(-100%); 1826 -webkit-transition: -webkit-transform .3s ease-in-out; 1827 transition: transform .3s ease-in-out; 1828 } 1829 1830 .options-panel.is-hidden { 1831 visibility: hidden; 1832 } 1833 1834 .options-panel.is-off-screen { 1835 -webkit-transform: translateX(0); 1836 -ms-transform: translateX(0); 1837 transform: translateX(0); 1838 } 1839 } 1840 1841 @media (max-width: 320px) { 1842 .options-panel { 1843 margin-right: -100%; 1844 width: 100%; 1845 border: 0; 1846 -webkit-box-shadow: 5001px 5000px 0 5000px #fff; 1847 box-shadow: 5001px 5000px 0 5000px #fff; 1848 } 1849 } 1850 1851 .post-options { 1852 background: #fff; 1853 position: absolute; 1854 right: 0; 1855 width: 100%; 1856 overflow-x: hidden; 1857 } 1858 1859 .post-options .post-option-contents { 1860 margin-left: 3px; 1861 color: #333; 1862 } 1863 1864 .post-options .dashicons-arrow-right-alt2 { 1865 position: absolute; 1866 top: 50%; 1867 right: 8px; 1868 margin-top: -10px; 1869 } 1870 1871 .lt-ie9 .options-panel, 1872 .lt-ie9 .post-options { 1873 border-left: 1px solid #e5e5e5; 1874 } 1875 1876 .lt-ie9 .post-options.is-off-screen { 1877 border: 0; 1878 } 1879 1880 .post-option { 1881 position: relative; 1882 } 1883 1884 .post-options .post-option { 1885 display: block; 1886 width: 100%; 1887 padding: 13px 37px 13px 14px; 1888 border-bottom: 1px solid #e5e5e5; 1889 text-decoration: none; 1890 text-align: left; 1891 color: #9ea7af; 1892 text-overflow: ellipsis; 1893 white-space: nowrap; 1894 overflow: hidden; 1895 -webkit-transition: -webkit-transform .3s ease-in-out; 1896 transition: transform .3s ease-in-out; 1897 } 1898 1899 .post-options .post-option:focus { 1900 outline: 0; 1901 -webkit-box-shadow: inset 5px 0 0 #2ea2cc; 1902 box-shadow: inset 5px 0 0 #2ea2cc; 1903 } 1904 1905 .is-off-screen > .post-option { 1906 right: 100%; 1907 } 1908 1909 .is-hidden > .post-option { 1910 visibility: hidden; 1911 } 1912 1913 @media (min-width: 1px) { 1914 .is-off-screen > .post-option { 1915 right: auto; 1916 -webkit-transform: translateX(-100%); 1917 -ms-transform: translateX(-100%); 1918 transform: translateX(-100%); 1919 } 1920 } 1921 1922 .post-option-title { 1923 display: inline-block; 1924 margin: 0 0 0 8px; 1925 font-size: 14px; 1926 font-weight: normal; 1927 } 1928 1929 .setting-modal { 1930 position: relative; 1931 top: 0; 1932 left: 0; 1933 width: 100%; 1934 overflow: hidden; 1935 -webkit-transition: -webkit-transform .3s ease-in-out; 1936 transition: transform .3s ease-in-out; 1937 } 1938 1939 .setting-modal.is-hidden { 1940 visibility: hidden; 1941 height: 0; 1942 } 1943 1944 .setting-modal.is-off-screen { 1945 left: 100%; 1946 } 1947 1948 @media (min-width: 1px) { 1949 .setting-modal.is-off-screen { 1950 left: 0; 1951 -webkit-transform: translateX(100%); 1952 -ms-transform: translateX(100%); 1953 transform: translateX(100%); 1954 } 1955 } 1956 1957 .modal-close { 1958 display: block; 1959 width: 100%; 1960 padding: 13px 14px; 1961 border-bottom: 1px solid #e5e5e5; 1962 color: #2ea2cc; 1963 text-decoration: none; 1964 text-align: left; 1965 } 1966 1967 .modal-close:focus { 1968 outline: 0; 1969 -webkit-box-shadow: inset 5px 0 0 #2ea2cc; 1970 box-shadow: inset 5px 0 0 #2ea2cc; 1971 } 1972 1973 .setting-title { 1974 position: relative; 1975 top: -1px; 1976 margin-left: 11px; 1977 } -
src/wp-admin/css/wp-admin.css
7 7 @import url(revisions.css); 8 8 @import url(media.css); 9 9 @import url(themes.css); 10 @import url(press-this.css);11 10 @import url(about.css); 12 11 @import url(nav-menus.css); 13 12 @import url(widgets.css); -
src/wp-admin/includes/ajax-actions.php
2954 2954 2955 2955 wp_send_json_success( $status ); 2956 2956 } 2957 2958 /** 2959 * AJAX handler for saving a post from Ptrss This. 2960 * 2961 * @since 4.2.0 2962 */ 2963 function wp_ajax_press_this_save_post() { 2964 if ( empty( $GLOBALS['wp_press_this'] ) ) { 2965 include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' ); 2966 } 2967 2968 $GLOBALS['wp_press_this']->save_post(); 2969 } 2970 2971 /** 2972 * AJAX handler for creating new category from Ptrss This. 2973 * 2974 * @since 4.2.0 2975 */ 2976 function wp_ajax_press_this_add_category() { 2977 if ( empty( $GLOBALS['wp_press_this'] ) ) { 2978 include( ABSPATH . 'wp-admin/includes/class-wp-press-this.php' ); 2979 } 2980 2981 $GLOBALS['wp_press_this']->add_category(); 2982 } -
src/wp-admin/includes/class-wp-press-this.php
1 <?php 2 /** 3 * Press This class and display functionality 4 * 5 * @package WordPress 6 * @subpackage Press_This 7 * @since 4.2.0 8 */ 9 10 /** 11 * Press This class 12 * 13 * @since 4.2.0 14 */ 15 class WP_Press_This { 16 17 /** 18 * Constructor. 19 * 20 * @since 4.2.0 21 * @access public 22 */ 23 public function __construct() {} 24 25 /** 26 * App and site settings data, including i18n strings for the client-side. 27 * 28 * @since 4.2.0 29 * @access public 30 * 31 * @return array Site settings. 32 */ 33 public function site_settings() { 34 $supported_formats = get_theme_support( 'post-formats' ); 35 $post_formats = array(); 36 37 if ( ! empty( $supported_formats[0] ) && is_array( $supported_formats[0] ) ) { 38 $post_formats[0] = __( 'Standard' ); 39 foreach ( $supported_formats[0] as $post_format ) { 40 $post_formats[ $post_format ] = esc_html( get_post_format_string( $post_format ) ); 41 } 42 } 43 44 return array( 45 'version' => 5, 46 'post_formats' => $post_formats, 47 48 /** 49 * Filter whether Press This should redirect the user in the parent window instead of the popup, upon save. 50 * 51 * @since 4.2.0 52 * 53 * @param bool $redir_in_parent Whether to redirect in parent window or not. Default false. 54 */ 55 'redir_in_parent' => apply_filters( 'press_this_redirect_in_parent', __return_false() ), 56 ); 57 } 58 59 /** 60 * Get the sources images and save them locally, fr posterity, unless we can't. 61 * 62 * @since 4.2.0 63 * @access public 64 * 65 * @param int $post_id Post ID. 66 * @param string $content Optional. Current expected markup for Press This. Default empty. 67 * @return string New markup with old image URLs replaced with the local attachment ones if swapped. 68 */ 69 public function side_load_images( $post_id, $content = '' ) { 70 $new_content = $content; 71 72 preg_match_all( '/<img [^>]+>/', $content, $matches ); 73 74 if ( ! empty( $matches ) && current_user_can( 'upload_files' ) ) { 75 foreach ( (array) $matches[0] as $key => $image ) { 76 preg_match( '/src=["\']{1}([^"\']+)["\']{1}/', stripslashes( $image ), $url_matches ); 77 78 if ( empty( $url_matches[1] ) ) { 79 continue; 80 } 81 82 $image_url = $url_matches[1]; 83 84 // Don't try to sideload a file without a file extension, leads to WP upload error. 85 if ( ! preg_match( '/[^\?]+\.(jpe?g|jpe|gif|png)\b/i', $image_url ) ) 86 continue; 87 88 // See if files exist in content - we don't want to upload non-used selected files. 89 if ( false !== strpos( $new_content, htmlspecialchars( $image_url ) ) ) { 90 91 // Sideload image, which ives us a new image tag, strip the empty alt that comes with it. 92 $upload = str_replace( ' alt=""', '', media_sideload_image( $image_url, $post_id ) ); 93 94 // Preserve assigned class, id, width, height and alt attributes. 95 if ( preg_match_all( '/(class|width|height|id|alt)=\\\?(\"|\')[^"\']+\\\?(\2)/', $image, $attr_matches ) 96 && is_array( $attr_matches[0] ) 97 ) { 98 foreach ( $attr_matches[0] as $attr ) { 99 $upload = str_replace( '<img', '<img ' . $attr, $upload ); 100 } 101 } 102 103 /* 104 * Replace the POSTED content <img> with correct uploaded ones. 105 * Regex contains fix for Magic Quotes. 106 */ 107 if ( ! is_wp_error( $upload ) ) { 108 $new_content = str_replace( $image, $upload, $new_content ); 109 } 110 } 111 } 112 } 113 114 // Error handling for media_sideload, send original content back. 115 if ( is_wp_error( $new_content ) ) { 116 return $content; 117 } 118 119 return $new_content; 120 } 121 122 /** 123 * AJAX handler for saving the post as draft or published. 124 * 125 * @since 4.2.0 126 * @access public 127 */ 128 public function save_post() { 129 if ( empty( $_POST['pressthis-nonce'] ) || ! wp_verify_nonce( $_POST['pressthis-nonce'], 'press-this' ) ) { 130 wp_send_json_error( array( 'errorMessage' => __( 'Cheatin’ uh?' ) ) ); 131 } 132 133 if ( empty( $_POST['post_ID'] ) || ! $post_id = (int) $_POST['post_ID'] ) { 134 wp_send_json_error( array( 'errorMessage' => __( 'Missing post ID.' ) ) ); 135 } 136 137 if ( ! current_user_can( 'edit_post', $post_id ) ) { 138 wp_send_json_error( array( 'errorMessage' => __( 'Cheatin’ uh?' ) ) ); 139 } 140 141 $post = array( 142 'ID' => $post_id, 143 'post_title' => ( ! empty( $_POST['title'] ) ) ? sanitize_text_field( trim( $_POST['title'] ) ) : '', 144 'post_content' => ( ! empty( $_POST['pressthis'] ) ) ? trim( $_POST['pressthis'] ) : '', 145 'post_type' => 'post', 146 'post_status' => 'draft', 147 'post_format' => ( ! empty( $_POST['post_format'] ) ) ? sanitize_text_field( $_POST['post_format'] ) : '', 148 'tax_input' => ( ! empty( $_POST['tax_input'] ) ) ? $_POST['tax_input'] : array(), 149 'post_category' => ( ! empty( $_POST['post_category'] ) ) ? $_POST['post_category'] : array(), 150 ); 151 152 if ( ! empty( $_POST['post_status'] ) && 'publish' === $_POST['post_status'] ) { 153 if ( current_user_can( 'publish_posts' ) ) { 154 $post['post_status'] = 'publish'; 155 } else { 156 $post['post_status'] = 'pending'; 157 } 158 } 159 160 $new_content = $this->side_load_images( $post_id, $post['post_content'] ); 161 162 if ( ! is_wp_error( $new_content ) ) { 163 $post['post_content'] = $new_content; 164 } 165 166 $updated = wp_update_post( $post, true ); 167 168 if ( is_wp_error( $updated ) || intval( $updated ) < 1 ) { 169 wp_send_json_error( array( 'errorMessage' => __( 'Error while saving the post. Please try again later.' ) ) ); 170 } else { 171 if ( isset( $post['post_format'] ) ) { 172 if ( current_theme_supports( 'post-formats', $post['post_format'] ) ) { 173 set_post_format( $post_id, $post['post_format'] ); 174 } elseif ( $post['post_format'] ) { 175 set_post_format( $post_id, false ); 176 } 177 } 178 179 if ( 'publish' === get_post_status( $post_id ) ) { 180 /** 181 * Filter the URL to redirect to when Press This saves. 182 * 183 * @since 4.2.0 184 * 185 * @param string $url Redirect URL. If `$status` is 'publish', this will be the post permalink. 186 * Otherwise, the post edit URL will be used. 187 * @param int $post_id Post ID. 188 * @param string $status Post status. 189 */ 190 $redirect = apply_filters( 'press_this_save_redirect', get_post_permalink( $post_id ), $post_id, $post['post_status'] ); 191 } else { 192 /** This filter is documented in wp-admin/includes/class-wp-press-this.php */ 193 $redirect = apply_filters( 'press_this_save_redirect', get_edit_post_link( $post_id, 'raw' ), $post_id, $post['post_status'] ); 194 } 195 196 wp_send_json_success( array( 'redirect' => $redirect ) ); 197 } 198 } 199 200 /** 201 * AJAX handler for adding a new category. 202 * 203 * @since 4.2.0 204 * @access public 205 */ 206 public function add_category() { 207 if ( false === wp_verify_nonce( $_POST['new_cat_nonce'], 'add-category' ) ) { 208 wp_send_json_error(); 209 } 210 211 $taxonomy = get_taxonomy( 'category' ); 212 213 if ( ! current_user_can( $taxonomy->cap->edit_terms ) || empty( $_POST['name'] ) ) { 214 wp_send_json_error(); 215 } 216 217 $parent = isset( $_POST['parent'] ) && (int) $_POST['parent'] > 0 ? (int) $_POST['parent'] : 0; 218 $names = explode( ',', $_POST['name'] ); 219 $added = $data = array(); 220 221 foreach ( $names as $cat_name ) { 222 $cat_name = trim( $cat_name ); 223 $cat_nicename = sanitize_title( $cat_name ); 224 225 if ( empty( $cat_nicename ) ) { 226 continue; 227 } 228 229 // @todo Find a more performant to check existence, maybe get_term() with a separate parent check. 230 if ( ! $cat_id = term_exists( $cat_name, $taxonomy->name, $parent ) ) { 231 $cat_id = wp_insert_term( $cat_name, $taxonomy->name, array( 'parent' => $parent ) ); 232 } 233 234 if ( is_wp_error( $cat_id ) ) { 235 continue; 236 } elseif ( is_array( $cat_id ) ) { 237 $cat_id = $cat_id['term_id']; 238 } 239 240 $added[] = $cat_id; 241 } 242 243 if ( empty( $added ) ) { 244 wp_send_json_error( array( 'errorMessage' => __( 'This category cannot be added. Please change the name and try again.' ) ) ); 245 } 246 247 foreach ( $added as $new_cat_id ) { 248 $new_cat = get_category( $new_cat_id ); 249 250 if ( is_wp_error( $new_cat ) ) { 251 wp_send_json_error( array( 'errorMessage' => __( 'Error while adding the category. Please try again later.' ) ) ); 252 } 253 254 $data[] = array( 255 'term_id' => $new_cat->term_id, 256 'name' => $new_cat->name, 257 'parent' => $new_cat->parent, 258 ); 259 } 260 wp_send_json_success( $data ); 261 } 262 263 /** 264 * Downloads the source's HTML via server-side call for the given URL. 265 * 266 * @since 4.2.0 267 * @access public 268 * 269 * @param string $url URL to scan. 270 * @return string Source's HTML sanitized markup 271 */ 272 public function fetch_source_html( $url ) { 273 // Download source page to tmp file. 274 $source_tmp_file = ( ! empty( $url ) ) ? download_url( $url ) : ''; 275 $source_content = ''; 276 277 if ( ! is_wp_error( $source_tmp_file ) && file_exists( $source_tmp_file ) ) { 278 // Get the content of the source page from the tmp file.. 279 280 $source_content = wp_kses( 281 file_get_contents( $source_tmp_file ), 282 array( 283 'img' => array( 284 'src' => array(), 285 ), 286 'iframe' => array( 287 'src' => array(), 288 ), 289 'link' => array( 290 'rel' => array(), 291 'itemprop' => array(), 292 'href' => array(), 293 ), 294 'meta' => array( 295 'property' => array(), 296 'name' => array(), 297 'content' => array(), 298 ) 299 ) 300 ); 301 302 // All done with backward compatibility. Let's do some cleanup, for good measure :) 303 unlink( $source_tmp_file ); 304 305 } else if ( is_wp_error( $source_tmp_file ) ) { 306 $source_content = new WP_Error( 'upload-error', sprintf( __( 'Error: %s' ), sprintf( __( 'Could not download the source URL (native error: %s).' ), $source_tmp_file->get_error_message() ) ) ); 307 } else if ( ! file_exists( $source_tmp_file ) ) { 308 $source_content = new WP_Error( 'no-local-file', sprintf( __( 'Error: %s' ), __( 'Could not save or locate the temporary download file for the source URL.' ) ) ); 309 } 310 311 return $source_content; 312 } 313 314 /** 315 * Fetches and parses _meta, _img, and _links data from the source. 316 * 317 * @since 4.2.0 318 * @access public 319 * 320 * @param string $url URL to scan. 321 * @param array $data Optional. Existing data array if you have one. Default empty array. 322 * @return array New data array. 323 */ 324 public function source_data_fetch_fallback( $url, $data = array() ) { 325 if ( empty( $url ) ) { 326 return array(); 327 } 328 329 // Download source page to tmp file. 330 $source_content = $this->fetch_source_html( $url ); 331 if ( is_wp_error( $source_content ) ) { 332 return array( 'errors' => $source_content->get_error_messages() ); 333 } 334 335 // Fetch and gather <img> data. 336 if ( empty( $data['_img'] ) ) { 337 $data['_img'] = array(); 338 } 339 340 if ( preg_match_all( '/<img (.+)[\s]?\/>/', $source_content, $matches ) ) { 341 if ( ! empty( $matches[0] ) ) { 342 foreach ( $matches[0] as $value ) { 343 if ( preg_match( '/<img[^>]+src="([^"]+)"[^>]+\/>/', $value, $new_matches ) ) { 344 if ( ! in_array( $new_matches[1], $data['_img'] ) ) { 345 $data['_img'][] = $new_matches[1]; 346 } 347 } 348 } 349 } 350 } 351 352 // Fetch and gather <iframe> data. 353 if ( empty( $data['_embed'] ) ) { 354 $data['_embed'] = array(); 355 } 356 357 if ( preg_match_all( '/<iframe (.+)[\s][^>]*>/', $source_content, $matches ) ) { 358 if ( ! empty( $matches[0] ) ) { 359 foreach ( $matches[0] as $value ) { 360 if ( preg_match( '/<iframe[^>]+src=(\'|")([^"]+)(\'|")/', $value, $new_matches ) ) { 361 if ( ! in_array( $new_matches[2], $data['_embed'] ) ) { 362 if ( preg_match( '/\/\/www\.youtube\.com\/embed\/([^\?]+)\?.+$/', $new_matches[2], $src_matches ) ) { 363 $data['_embed'][] = 'https://www.youtube.com/watch?v=' . $src_matches[1]; 364 } else if ( preg_match( '/\/\/player\.vimeo\.com\/video\/([\d]+)([\?\/]{1}.*)?$/', $new_matches[2], $src_matches ) ) { 365 $data['_embed'][] = 'https://vimeo.com/' . (int) $src_matches[1]; 366 } else if ( preg_match( '/\/\/vine\.co\/v\/([^\/]+)\/embed/', $new_matches[2], $src_matches ) ) { 367 $data['_embed'][] = 'https://vine.co/v/' . $src_matches[1]; 368 } 369 } 370 } 371 } 372 } 373 } 374 375 // Fetch and gather <meta> data. 376 if ( empty( $data['_meta'] ) ) { 377 $data['_meta'] = array(); 378 } 379 380 if ( preg_match_all( '/<meta ([^>]+)[\s]?\/?>/ ', $source_content, $matches ) ) { 381 if ( ! empty( $matches[0] ) ) { 382 foreach ( $matches[0] as $key => $value ) { 383 if ( preg_match( '/<meta[^>]+(property|name)="(.+)"[^>]+content="(.+)"/', $value, $new_matches ) ) { 384 if ( empty( $data['_meta'][ $new_matches[2] ] ) ) { 385 if ( preg_match( '/:?(title|description|keywords)$/', $new_matches[2] ) ) { 386 $data['_meta'][ $new_matches[2] ] = str_replace( ''', "'", str_replace( '"', '', html_entity_decode( $new_matches[3] ) ) ); 387 } else { 388 $data['_meta'][ $new_matches[2] ] = $new_matches[3]; 389 if ( 'og:url' == $new_matches[2] ) { 390 if ( false !== strpos( $new_matches[3], '//www.youtube.com/watch?' ) 391 || false !== strpos( $new_matches[3], '//www.dailymotion.com/video/' ) 392 || preg_match( '/\/\/vimeo\.com\/[\d]+$/', $new_matches[3] ) 393 || preg_match( '/\/\/soundcloud\.com\/.+$/', $new_matches[3] ) 394 || preg_match( '/\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/', $new_matches[3] ) 395 || preg_match( '/\/\/vine\.co\/v\/[^\/]+/', $new_matches[3] ) ) { 396 if ( ! in_array( $new_matches[3], $data['_embed'] ) ) { 397 $data['_embed'][] = $new_matches[3]; 398 } 399 } 400 } else if ( 'og:video' == $new_matches[2] || 'og:video:secure_url' == $new_matches[2] ) { 401 if ( preg_match( '/\/\/www\.youtube\.com\/v\/([^\?]+)/', $new_matches[3], $src_matches ) ) { 402 if ( ! in_array( 'https://www.youtube.com/watch?v=' . $src_matches[1], $data['_embed'] ) ) { 403 $data['_embed'][] = 'https://www.youtube.com/watch?v=' . $src_matches[1]; 404 } 405 } else if ( preg_match( '/\/\/vimeo.com\/moogaloop\.swf\?clip_id=([\d]+)$/', $new_matches[3], $src_matches ) ) { 406 if ( ! in_array( 'https://vimeo.com/' . $src_matches[1], $data['_embed'] ) ) { 407 $data['_embed'][] = 'https://vimeo.com/' . $src_matches[1]; 408 } 409 } 410 } else if ( 'og:image' == $new_matches[2] || 'og:image:secure_url' == $new_matches[2] ) { 411 if ( ! in_array( $new_matches[3], $data['_img'] ) ) { 412 $data['_img'][] = $new_matches[3]; 413 } 414 } 415 } 416 } 417 } 418 } 419 } 420 } 421 422 // Fetch and gather <link> data 423 if ( empty( $data['_links'] ) ) { 424 $data['_links'] = array(); 425 } 426 427 if ( preg_match_all( '/<link ([^>]+)[\s]?\/>/', $source_content, $matches ) ) { 428 if ( ! empty( $matches[0] ) ) { 429 foreach ( $matches[0] as $key => $value ) { 430 if ( preg_match( '/<link[^>]+(rel|itemprop)="([^"]+)"[^>]+href="([^"]+)"[^>]+\/>/', $value, $new_matches ) ) { 431 if ( 'alternate' == $new_matches[2] || 'thumbnailUrl' == $new_matches[2] || 'url' == $new_matches[2] ) { 432 if ( empty( $data['_links'][ $new_matches[2] ] ) ) { 433 $data['_links'][ $new_matches[2] ] = $new_matches[3]; 434 } 435 } 436 } 437 } 438 } 439 } 440 441 return $data; 442 } 443 444 /** 445 * Handles backward-compat with the legacy version of Press This by supporting its query string params. 446 * 447 * @since 4.2.0 448 * @access public 449 * 450 * @return array 451 */ 452 public function merge_or_fetch_data() { 453 // Merge $_POST and $_GET, as appropriate ($_POST > $_GET), to remain backward compatible. 454 $data = array_merge_recursive( $_POST, $_GET ); 455 456 // Get the legacy QS params, or equiv POST data 457 $data['u'] = ( ! empty( $data['u'] ) && preg_match( '/^https?:/', $data['u'] ) ) ? $data['u'] : ''; 458 $data['s'] = ( ! empty( $data['s'] ) ) ? $data['s'] : ''; 459 $data['t'] = ( ! empty( $data['t'] ) ) ? $data['t'] : ''; 460 461 /** 462 * Filter whether to enable in-source media discovery in Press This. 463 * 464 * @since 4.2.0 465 * 466 * @param bool $enable Whether to enable media discovery. 467 */ 468 if ( apply_filters( 'enable_press_this_media_discovery', __return_true() ) ) { 469 /* 470 * If no _meta (a new thing) was passed via $_POST, fetch data from source as fallback, 471 * makes PT fully backward compatible 472 */ 473 if ( empty( $data['_meta'] ) && ! empty( $data['u'] ) ) { 474 $data = $this->source_data_fetch_fallback( $data['u'], $data ); 475 } 476 } else { 477 if ( ! empty( $data['_img'] ) ) { 478 $data['_img'] = array(); 479 } 480 if ( ! empty( $data['_embed'] ) ) { 481 $data['_embed'] = array(); 482 } 483 if ( ! empty( $data['_meta'] ) ) { 484 $data['_meta'] = array(); 485 } 486 } 487 488 /** 489 * Filter the Press This data array. 490 * 491 * @since 4.2.0 492 * 493 * @param array $data Press This Data array. 494 */ 495 return apply_filters( 'press_this_data', $data ); 496 } 497 498 /** 499 * Adds another stylesheet inside TinyMCE. 500 * 501 * @since 4.2.0 502 * @access public 503 * 504 * @param string $styles URL to editor stylesheet. 505 * @return string Possibly modified stylesheets list. 506 */ 507 public function add_editor_style( $styles ) { 508 if ( ! empty( $styles ) ) { 509 $styles .= ','; 510 } 511 return $styles . admin_url( 'css/press-this-editor.css' ); 512 } 513 514 /** 515 * Outputs the post format selection HTML. 516 * 517 * @since 4.2.0 518 * @access public 519 * 520 * @param WP_Post $post Post object. 521 */ 522 function post_formats_html( $post ) { 523 if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) ) { 524 $post_formats = get_theme_support( 'post-formats' ); 525 526 if ( is_array( $post_formats[0] ) ) { 527 $post_format = get_post_format( $post->ID ); 528 529 if ( ! $post_format ) { 530 $post_format = '0'; 531 } 532 533 // Add in the current one if it isn't there yet, in case the current theme doesn't support it. 534 if ( $post_format && ! in_array( $post_format, $post_formats[0] ) ) { 535 $post_formats[0][] = $post_format; 536 } 537 538 ?> 539 <div id="post-formats-select"> 540 <input type="radio" name="post_format" class="post-format" id="post-format-0" value="0" <?php checked( $post_format, '0' ); ?> /> 541 <label for="post-format-0" class="post-format-icon post-format-standard"><?php echo get_post_format_string( 'standard' ); ?></label> 542 <?php 543 544 foreach ( $post_formats[0] as $format ) { 545 $attr_format = esc_attr( $format ); 546 ?> 547 <br /> 548 <input type="radio" name="post_format" class="post-format" id="post-format-<?php echo $attr_format; ?>" value="<?php echo $attr_format; ?>" <?php checked( $post_format, $format ); ?> /> 549 <label for="post-format-<?php echo $attr_format ?>" class="post-format-icon post-format-<?php echo $attr_format; ?>"><?php echo esc_html( get_post_format_string( $format ) ); ?></label> 550 <?php 551 } 552 ?> 553 </div> 554 <?php 555 } 556 } 557 } 558 559 /** 560 * Outputs the categories HTML. 561 * 562 * @since 4.2.0 563 * @access public 564 * 565 * @param WP_Post $post Post object. 566 */ 567 function categories_html( $post ) { 568 $taxonomy = get_taxonomy( 'category' ); 569 570 if ( current_user_can( $taxonomy->cap->edit_terms ) ) { 571 ?> 572 <button type="button" class="add-cat-toggle button-subtle"> 573 <span class="dashicons dashicons-plus"></span> 574 </button> 575 <div class="add-category is-hidden"> 576 <label class="screen-reader-text" for="new-category"><?php echo $taxonomy->labels->add_new_item; ?></label> 577 <input type="text" id="new-category" class="add-category-name" placeholder="<?php echo esc_attr( $taxonomy->labels->new_item_name ); ?>" value="" aria-required="true"> 578 <label class="screen-reader-text" for="new-category-parent"><?php echo $taxonomy->labels->parent_item_colon; ?></label> 579 <div class="postform-wrapper"> 580 <?php 581 wp_dropdown_categories( array( 582 'taxonomy' => 'category', 583 'hide_empty' => 0, 584 'name' => 'new-category-parent', 585 'orderby' => 'name', 586 'hierarchical' => 1, 587 'show_option_none' => '— ' . $taxonomy->labels->parent_item . ' —' 588 ) ); 589 ?> 590 </div> 591 <button type="button" class="button add-cat-submit"><?php _e( 'Add' ); ?></button> 592 </div> 593 <?php } ?> 594 <div class="categories-search-wrapper"> 595 <input id="categories-search" type="search" class="categories-search" placeholder="<?php esc_attr_e( 'Search categories' ) ?>"> 596 <label for="categories-search"> 597 <span class="dashicons dashicons-search"></span> 598 </label> 599 </div> 600 <ul class="categories-select"> 601 <?php wp_terms_checklist( $post->ID, array( 'taxonomy' => 'category' ) ); ?> 602 </ul> 603 <?php 604 } 605 606 /** 607 * Outputs the tags HTML. 608 * 609 * @since 4.2.0 610 * @access public 611 * 612 * @param WP_Post $post Post object. 613 */ 614 function tags_html( $post ) { 615 $taxonomy = get_taxonomy( 'post_tag' ); 616 $user_can_assign_terms = current_user_can( $taxonomy->cap->assign_terms ); 617 $esc_tags = get_terms_to_edit( $post->ID, 'post_tag' ); 618 619 if ( ! $esc_tags || is_wp_error( $esc_tags ) ) { 620 $esc_tags = ''; 621 } 622 ?> 623 <div class="tagsdiv" id="post_tag"> 624 <div class="jaxtag"> 625 <input type="hidden" name="tax_input[post_tag]" class="the-tags" value="<?php echo $esc_tags; // escaped in get_terms_to_edit() ?>"> 626 627 <?php 628 if ( $user_can_assign_terms ) { 629 ?> 630 <div class="ajaxtag hide-if-no-js"> 631 <label class="screen-reader-text" for="new-tag-post_tag"><?php _e( 'Tags' ); ?></label> 632 <div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div> 633 <p> 634 <input type="text" id="new-tag-post_tag" name="newtag[post_tag]" class="newtag form-input-tip" size="16" autocomplete="off" value="" /> 635 <button type="button" class="button tagadd"><?php _e( 'Add' ); ?></button> 636 </p> 637 </div> 638 <p class="howto"> 639 <?php echo $taxonomy->labels->separate_items_with_commas; ?> 640 </p> 641 <?php } ?> 642 </div> 643 <div class="tagchecklist"></div> 644 </div> 645 <?php 646 if ( $user_can_assign_terms ) { 647 ?> 648 <p> 649 <a href="#titlediv" class="tagcloud-link" id="link-post_tag"><?php echo $taxonomy->labels->choose_from_most_used; ?></a> 650 </p> 651 <?php 652 } 653 } 654 655 /** 656 * Serves the app's base HTML, which in turns calls the load script. 657 * 658 * @since 4.2.0 659 * @access public 660 */ 661 public function html() { 662 global $wp_locale, $hook_suffix; 663 664 // Get data, new (POST) and old (GET). 665 $data = $this->merge_or_fetch_data(); 666 667 // Get site settings array/data. 668 $site_settings = $this->site_settings(); 669 670 // Set the passed data. 671 $data['_version'] = $site_settings['version']; 672 673 // Add press-this-editor.css and remove theme's editor-style.css, if any. 674 remove_editor_styles(); 675 676 add_filter( 'mce_css', array( $this, 'add_editor_style' ) ); 677 678 if ( ! empty( $GLOBALS['is_IE'] ) ) { 679 @header( 'X-UA-Compatible: IE=edge' ); 680 } 681 682 @header( 'Content-Type: ' . get_option( 'html_type' ) . '; charset=' . get_option( 'blog_charset' ) ); 683 684 ?> 685 <!DOCTYPE html> 686 <!--[if IE 7]> <html class="lt-ie9 lt-ie8" <?php language_attributes(); ?>> <![endif]--> 687 <!--[if IE 8]> <html class="lt-ie9" <?php language_attributes(); ?>> <![endif]--> 688 <!--[if gt IE 8]><!--> <html <?php language_attributes(); ?>> <!--<![endif]--> 689 <head> 690 <meta http-equiv="Content-Type" content="<?php esc_attr( bloginfo( 'html_type' ) ); ?>; charset=<?php echo esc_attr( get_option( 'blog_charset' ) ); ?>" /> 691 <meta name="viewport" content="width=device-width"> 692 <title><?php esc_html_e( 'Press This!' ) ?></title> 693 694 <script> 695 window.wpPressThisData = <?php echo json_encode( $data ) ?>; 696 window.wpPressThisConfig = <?php echo json_encode( $site_settings ) ?>; 697 </script> 698 699 <script type="text/javascript"> 700 var ajaxurl = '<?php echo esc_js( admin_url( 'admin-ajax.php', 'relative' ) ); ?>', 701 pagenow = 'press-this', 702 typenow = 'post', 703 adminpage = 'press-this-php', 704 thousandsSeparator = '<?php echo addslashes( $wp_locale->number_format['thousands_sep'] ); ?>', 705 decimalPoint = '<?php echo addslashes( $wp_locale->number_format['decimal_point'] ); ?>', 706 isRtl = <?php echo esc_js( (int) is_rtl() ); ?>; 707 </script> 708 709 <?php 710 /* 711 * $post->ID is needed for the embed shortcode so we can show oEmbed previews in the editor. 712 * Maybe find a way without it. 713 */ 714 $post = get_default_post_to_edit( 'post', true ); 715 $post_ID = (int) $post->ID; 716 717 wp_enqueue_style( 'press-this' ); 718 wp_enqueue_script( 'press-this' ); 719 wp_enqueue_script( 'json2' ); 720 wp_enqueue_media( array( 'post' => $post->ID ) ); 721 wp_enqueue_script( 'editor' ); 722 723 $supports_formats = false; 724 $post_format = 0; 725 726 if ( current_theme_supports( 'post-formats' ) && post_type_supports( $post->post_type, 'post-formats' ) ) { 727 $supports_formats = true; 728 729 if ( ! ( $post_format = get_post_format( $post->ID ) ) ) { 730 $post_format = 0; 731 } 732 } 733 734 /** This action is documented in wp-admin/admin-header.php */ 735 do_action( 'admin_enqueue_scripts', $hook_suffix ); 736 737 /** This action is documented in wp-admin/admin-header.php */ 738 do_action( 'admin_print_styles' ); 739 740 /** This action is documented in wp-admin/admin-header.php */ 741 do_action( 'admin_print_scripts' ); 742 743 ?> 744 </head> 745 <body> 746 <div id="adminbar" class="adminbar"> 747 <h1 id="current-site" class="current-site"> 748 <span class="dashicons dashicons-wordpress"></span> 749 <span><?php bloginfo( 'name' ); ?></span> 750 </h1> 751 <button type="button" class="options-open button-subtle"> 752 <span class="dashicons dashicons-tag"></span><span class="screen-reader-text"><?php _e( 'Show post options' ); ?></span> 753 </button> 754 <button type="button" class="options-close button-subtle is-hidden"><?php _e( 'Done' ); ?></button> 755 </div> 756 757 <div id="scanbar" class="scan"> 758 <form method="GET"> 759 <input type="url" name="u" id="url-scan" class="scan-url" value="" placeholder="<?php esc_attr_e( 'Enter a URL to scan' ) ?>" /> 760 <input type="submit" name="url-scan-submit" id="url-scan-submit" class="scan-submit" value="<?php esc_attr_e( 'Scan' ) ?>" /> 761 </form> 762 </div> 763 764 <form id="pressthis-form" name="pressthis-form" method="POST" autocomplete="off"> 765 <input type="hidden" name="post_ID" id="post_ID" value="<?php echo esc_attr( $post_ID ); ?>" /> 766 <input type="hidden" name="action" value="press-this-save-post" /> 767 <input type="hidden" name="post_status" id="post_status" value="draft" /> 768 <?php 769 wp_nonce_field( 'press-this', 'pressthis-nonce', false ); 770 wp_nonce_field( 'add-category', '_ajax_nonce-add-category', false ); 771 ?> 772 <input type="hidden" name="title" id="title-field" value="" /> 773 774 <div class="wrapper"> 775 <div class="editor-wrapper"> 776 <div class="alerts"> 777 <p class="alert is-notice is-hidden should-upgrade-bookmarklet"> 778 <?php printf( __( 'You should upgrade <a href="%s" target="_blank">your bookmarklet</a> to the latest version!' ), admin_url( 'tools.php?page=press_this_options' ) ); ?> 779 </p> 780 </div> 781 782 <div id='app-container' class="editor"> 783 <span id="title-container-label" class="post-title-placeholder" aria-hidden="true"><?php _e( 'Post title' ); ?></span> 784 <h2 id="title-container" class="post-title" contenteditable="true" spellcheck="true" aria-label="<?php esc_attr_e( 'Post title' ); ?>" tabindex="0"></h2> 785 <div id='featured-media-container' class="featured-container no-media"> 786 <div id='all-media-widget' class="all-media"> 787 <div id='all-media-container'></div> 788 </div> 789 </div> 790 791 <?php 792 wp_editor( '', 'pressthis', array( 793 'drag_drop_upload' => true, 794 'editor_height' => 600, 795 'media_buttons' => false, 796 'teeny' => true, 797 'tinymce' => array( 798 'resize' => false, 799 'wordpress_adv_hidden' => false, 800 'add_unload_trigger' => false, 801 'statusbar' => false, 802 'autoresize_min_height' => 600, 803 'wp_autoresize_on' => true, 804 'plugins' => 'lists,media,paste,tabfocus,fullscreen,wordpress,wpautoresize,wpeditimage,wpgallery,wplink,wpview', 805 'toolbar1' => 'bold,italic,bullist,numlist,blockquote,link,unlink', 806 'toolbar2' => 'undo,redo', 807 ), 808 'quicktags' => false, 809 ) ); 810 811 ?> 812 </div> 813 </div> 814 815 <div class="options-panel is-off-screen is-hidden"> 816 <div class="post-options"> 817 818 <?php if ( $supports_formats ) : ?> 819 <button type="button" class="button-reset post-option"> 820 <span class="dashicons dashicons-admin-post"></span> 821 <span class="post-option-title"><?php _e( 'Format' ); ?></span> 822 <span class="post-option-contents" id="post-option-post-format"><?php echo esc_html( get_post_format_string( $post_format ) ); ?></span> 823 <span class="dashicons dashicons-arrow-right-alt2"></span> 824 </button> 825 <?php endif; ?> 826 827 <button type="button" class="button-reset post-option"> 828 <span class="dashicons dashicons-category"></span> 829 <span class="post-option-title"><?php _e( 'Categories' ); ?></span> 830 <span class="post-option-contents" id="post-option-category"></span> 831 <span class="dashicons dashicons-arrow-right-alt2"></span> 832 </button> 833 834 <button type="button" class="button-reset post-option"> 835 <span class="dashicons dashicons-tag"></span> 836 <span class="post-option-title"><?php _e( 'Tags' ); ?></span> 837 <span class="post-option-contents" id="post-option-tags"></span> 838 <span class="dashicons dashicons-arrow-right-alt2"></span> 839 </button> 840 </div> 841 842 <?php if ( $supports_formats ) : ?> 843 <div class="setting-modal is-off-screen is-hidden"> 844 <button type="button" class="button-reset modal-close"> 845 <span class="dashicons dashicons-arrow-left-alt2"></span><span class="setting-title"><?php _e( 'Post format' ); ?></span> 846 </button> 847 <?php $this->post_formats_html( $post ); ?> 848 </div> 849 <?php endif; ?> 850 851 <div class="setting-modal is-off-screen is-hidden"> 852 <button type="button" class="button-reset modal-close"><span class="dashicons dashicons-arrow-left-alt2"></span><span class="setting-title"><?php _e( 'Categories' ); ?></span></button> 853 <?php $this->categories_html( $post ); ?> 854 </div> 855 856 <div class="setting-modal tags is-off-screen is-hidden"> 857 <button type="button" class="button-reset modal-close"><span class="dashicons dashicons-arrow-left-alt2"></span><span class="setting-title"><?php _e( 'Tags' ); ?></span></button> 858 <?php $this->tags_html( $post ); ?> 859 </div> 860 </div><!-- .options-panel --> 861 </div><!-- .wrapper --> 862 863 <div class="press-this-actions"> 864 <div class="pressthis-media-buttons"> 865 <button type="button" class="insert-media button-subtle" data-editor="pressthis"> 866 <span class="dashicons dashicons-admin-media"></span> 867 <span class="screen-reader-text"><?php _e( 'Add Media' ); ?></span> 868 </button> 869 </div> 870 <div class="post-actions"> 871 <button type="button" class="button-subtle" id="draft-field"><?php _e( 'Save Draft' ); ?></button> 872 <button type="button" class="button-primary" id="publish-field"><?php _e( 'Publish' ); ?></button> 873 </div> 874 </div> 875 </form> 876 877 <?php 878 879 // TODO: consider running "special" press-this hooks here? 880 // Maybe better so we don't output stuff accidentaly added by plugins. Would probably prevent some errors. 881 do_action( 'admin_footer', '' ); 882 do_action( 'admin_print_footer_scripts' ); 883 884 ?> 885 </body> 886 </html> 887 <?php 888 die(); 889 } 890 } 891 $GLOBALS['wp_press_this'] = new WP_Press_This; -
src/wp-admin/js/bookmarklet.js
1 ( function( window, document, href, pt_url ) { 2 var encodeURI = window.encodeURIComponent, 3 form = document.createElement( 'form' ), 4 head = document.getElementsByTagName( 'head' )[0], 5 img = new Image(), 6 target = '_press_this_app', 7 windowWidth, windowHeight, 8 metas, links, content, imgs, ifrs, 9 vid, selection; 10 11 if ( ! pt_url ) { 12 return; 13 } 14 15 if ( window.getSelection ) { 16 selection = window.getSelection() + ''; 17 } else if ( document.getSelection ) { 18 selection = document.getSelection() + ''; 19 } else if ( document.selection ) { 20 selection = document.selection.createRange().text; 21 } 22 23 pt_url += ( pt_url.indexOf( '?' ) > -1 ? '&' : '?' ) + 'buster=' + ( new Date().getTime() ); 24 25 if ( document.title.length && document.title.length <= 512 ) { 26 pt_url += '&t=' + encodeURI( document.title ); 27 } 28 29 if ( selection && selection.length <= 512 ) { 30 pt_url += '&s=' + encodeURI( selection ); 31 } 32 33 if ( href.match( /^https?:/ ) ) { 34 pt_url += '&u=' + encodeURI( href ); 35 } else { 36 top.location.href = pt_url; 37 return; 38 } 39 40 function add( name, value ) { 41 if ( typeof value === 'undefined' ) { 42 return; 43 } 44 45 var input = document.createElement( 'input' ); 46 47 input.name = name; 48 input.value = value; 49 input.type = 'hidden'; 50 51 form.appendChild( input ); 52 } 53 54 if ( href.match( /\/\/www\.youtube\.com\/watch/ ) ) { 55 add( '_embed[]', href ); 56 } else if ( href.match( /\/\/vimeo\.com\/(.+\/)?([\d]+)$/ ) ) { 57 add( '_embed[]', href ); 58 } else if ( href.match( /\/\/(www\.)?dailymotion\.com\/video\/.+$/ ) ) { 59 add( '_embed[]', href ); 60 } else if ( href.match( /\/\/soundcloud\.com\/.+$/ ) ) { 61 add( '_embed[]', href ); 62 } else if ( href.match( /\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/ ) ) { 63 add( '_embed[]', href ); 64 } else if ( href.match( /\/\/vine\.co\/v\/[^\/]+/ ) ) { 65 add( '_embed[]', href ); 66 } 67 68 metas = head.getElementsByTagName( 'meta' ) || []; 69 70 for ( var m = 0; m < metas.length; m++ ) { 71 if ( m >= 50 ) { 72 break; 73 } 74 75 var q = metas[ m ], 76 q_name = q.getAttribute( 'name' ), 77 q_prop = q.getAttribute( 'property' ), 78 q_cont = q.getAttribute( 'content' ); 79 80 if ( q_name ) { 81 add( '_meta[' + q_name + ']', q_cont ); 82 } else if ( q_prop ) { 83 add( '_meta[' + q_prop + ']', q_cont ); 84 } 85 } 86 87 links = head.getElementsByTagName( 'link' ) || []; 88 89 for ( var y = 0; y < links.length; y++ ) { 90 if ( y >= 50 ) { 91 break; 92 } 93 94 var g = links[ y ], 95 g_rel = g.getAttribute( 'rel' ); 96 97 if ( g_rel ) { 98 switch ( g_rel ) { 99 case 'canonical': 100 case 'icon': 101 case 'shortlink': 102 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 103 break; 104 case 'alternate': 105 if ( 'application/json+oembed' === g.getAttribute( 'type' ) ) { 106 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 107 } else if ( 'handheld' === g.getAttribute( 'media' ) ) { 108 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 109 } 110 } 111 } 112 } 113 114 if ( document.body.getElementsByClassName ) { 115 content = document.body.getElementsByClassName( 'hfeed' )[0]; 116 } 117 118 content = document.getElementById( 'content' ) || content || document.body; 119 imgs = content.getElementsByTagName( 'img' ) || []; 120 121 for ( var n = 0; n < imgs.length; n++ ) { 122 if ( n >= 100 ) { 123 break; 124 } 125 126 if ( imgs[ n ].src.indexOf( 'avatar' ) > -1 || imgs[ n ].className.indexOf( 'avatar' ) > -1 ) { 127 continue; 128 } 129 130 img.src = imgs[ n ].src; 131 132 if ( img.width >= 256 && img.height >= 128 ) { 133 add( '_img[]', img.src ); 134 } 135 } 136 137 ifrs = document.body.getElementsByTagName( 'iframe' ) || []; 138 139 for ( var p = 0; p < ifrs.length; p++ ) { 140 if ( p >= 100 ) { 141 break; 142 } 143 144 vid = ifrs[ p ].src.match(/\/\/www\.youtube\.com\/embed\/([^\?]+)\?.+$/); 145 146 if ( vid && 2 === vid.length ) { 147 add( '_embed[]', 'https://www.youtube.com/watch?v=' + vid[1] ); 148 } 149 150 vid = ifrs[ p ].src.match( /\/\/player\.vimeo\.com\/video\/([\d]+)$/ ); 151 152 if ( vid && 2 === vid.length ) { 153 add( '_embed[]', 'https://vimeo.com/' + vid[1] ); 154 } 155 156 vid = ifrs[ p ].src.match( /\/\/vine\.co\/v\/([^\/]+)\/embed/ ); 157 158 if ( vid && 2 === vid.length ) { 159 add( '_embed[]', 'https://vine.co/v/' + vid[1] ); 160 } 161 } 162 163 if ( document.title && document.title > 512 ) { 164 add( 't', document.title ); 165 } 166 167 if ( selection && selection.length > 512 ) { 168 add( 's', selection ); 169 } 170 171 form.setAttribute( 'method', 'POST' ); 172 form.setAttribute( 'action', pt_url ); 173 form.setAttribute( 'target', target ); 174 form.setAttribute( 'style', 'display: none;' ); 175 176 windowWidth = window.outerWidth || document.documentElement.clientWidth || 600; 177 windowHeight = window.outerHeight || document.documentElement.clientHeight || 700; 178 179 windowWidth = ( windowWidth < 800 || windowWidth > 5000 ) ? 600 : ( windowWidth * 0.7 ); 180 windowHeight = ( windowHeight < 800 || windowHeight > 3000 ) ? 700 : ( windowHeight * 0.9 ); 181 182 window.open( 'about:blank', target, 'width=' + windowWidth + ',height=' + windowHeight ); 183 184 document.body.appendChild( form ); 185 186 form.submit(); 187 } )( window, document, top.location.href, window.pt_url ); 188 ( function( window, document, href, pt_url ) { 189 var encodeURI = window.encodeURIComponent, 190 form = document.createElement( 'form' ), 191 head = document.getElementsByTagName( 'head' )[0], 192 img = new Image(), 193 target = '_press_this_app', 194 windowWidth, windowHeight, 195 metas, links, content, imgs, ifrs, 196 vid, selection; 197 198 if ( ! pt_url ) { 199 return; 200 } 201 202 if ( window.getSelection ) { 203 selection = window.getSelection() + ''; 204 } else if ( document.getSelection ) { 205 selection = document.getSelection() + ''; 206 } else if ( document.selection ) { 207 selection = document.selection.createRange().text; 208 } 209 210 pt_url += ( pt_url.indexOf( '?' ) > -1 ? '&' : '?' ) + 'buster=' + ( new Date().getTime() ); 211 212 if ( document.title.length && document.title.length <= 512 ) { 213 pt_url += '&t=' + encodeURI( document.title ); 214 } 215 216 if ( selection && selection.length <= 512 ) { 217 pt_url += '&s=' + encodeURI( selection ); 218 } 219 220 if ( href.match( /^https?:/ ) ) { 221 pt_url += '&u=' + encodeURI( href ); 222 } else { 223 top.location.href = pt_url; 224 return; 225 } 226 227 function add( name, value ) { 228 if ( typeof value === 'undefined' ) { 229 return; 230 } 231 232 var input = document.createElement( 'input' ); 233 234 input.name = name; 235 input.value = value; 236 input.type = 'hidden'; 237 238 form.appendChild( input ); 239 } 240 241 if ( href.match( /\/\/www\.youtube\.com\/watch/ ) ) { 242 add( '_embed[]', href ); 243 } else if ( href.match( /\/\/vimeo\.com\/(.+\/)?([\d]+)$/ ) ) { 244 add( '_embed[]', href ); 245 } else if ( href.match( /\/\/(www\.)?dailymotion\.com\/video\/.+$/ ) ) { 246 add( '_embed[]', href ); 247 } else if ( href.match( /\/\/soundcloud\.com\/.+$/ ) ) { 248 add( '_embed[]', href ); 249 } else if ( href.match( /\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/ ) ) { 250 add( '_embed[]', href ); 251 } else if ( href.match( /\/\/vine\.co\/v\/[^\/]+/ ) ) { 252 add( '_embed[]', href ); 253 } 254 255 metas = head.getElementsByTagName( 'meta' ) || []; 256 257 for ( var m = 0; m < metas.length; m++ ) { 258 if ( m >= 50 ) { 259 break; 260 } 261 262 var q = metas[ m ], 263 q_name = q.getAttribute( 'name' ), 264 q_prop = q.getAttribute( 'property' ), 265 q_cont = q.getAttribute( 'content' ); 266 267 if ( q_name ) { 268 add( '_meta[' + q_name + ']', q_cont ); 269 } else if ( q_prop ) { 270 add( '_meta[' + q_prop + ']', q_cont ); 271 } 272 } 273 274 links = head.getElementsByTagName( 'link' ) || []; 275 276 for ( var y = 0; y < links.length; y++ ) { 277 if ( y >= 50 ) { 278 break; 279 } 280 281 var g = links[ y ], 282 g_rel = g.getAttribute( 'rel' ); 283 284 if ( g_rel ) { 285 switch ( g_rel ) { 286 case 'canonical': 287 case 'icon': 288 case 'shortlink': 289 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 290 break; 291 case 'alternate': 292 if ( 'application/json+oembed' === g.getAttribute( 'type' ) ) { 293 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 294 } else if ( 'handheld' === g.getAttribute( 'media' ) ) { 295 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 296 } 297 } 298 } 299 } 300 301 if ( document.body.getElementsByClassName ) { 302 content = document.body.getElementsByClassName( 'hfeed' )[0]; 303 } 304 305 content = document.getElementById( 'content' ) || content || document.body; 306 imgs = content.getElementsByTagName( 'img' ) || []; 307 308 for ( var n = 0; n < imgs.length; n++ ) { 309 if ( n >= 100 ) { 310 break; 311 } 312 313 if ( imgs[ n ].src.indexOf( 'avatar' ) > -1 || imgs[ n ].className.indexOf( 'avatar' ) > -1 ) { 314 continue; 315 } 316 317 img.src = imgs[ n ].src; 318 319 if ( img.width >= 256 && img.height >= 128 ) { 320 add( '_img[]', img.src ); 321 } 322 } 323 324 ifrs = document.body.getElementsByTagName( 'iframe' ) || []; 325 326 for ( var p = 0; p < ifrs.length; p++ ) { 327 if ( p >= 100 ) { 328 break; 329 } 330 331 vid = ifrs[ p ].src.match(/\/\/www\.youtube\.com\/embed\/([^\?]+)\?.+$/); 332 333 if ( vid && 2 === vid.length ) { 334 add( '_embed[]', 'https://www.youtube.com/watch?v=' + vid[1] ); 335 } 336 337 vid = ifrs[ p ].src.match( /\/\/player\.vimeo\.com\/video\/([\d]+)$/ ); 338 339 if ( vid && 2 === vid.length ) { 340 add( '_embed[]', 'https://vimeo.com/' + vid[1] ); 341 } 342 343 vid = ifrs[ p ].src.match( /\/\/vine\.co\/v\/([^\/]+)\/embed/ ); 344 345 if ( vid && 2 === vid.length ) { 346 add( '_embed[]', 'https://vine.co/v/' + vid[1] ); 347 } 348 } 349 350 if ( document.title && document.title > 512 ) { 351 add( 't', document.title ); 352 } 353 354 if ( selection && selection.length > 512 ) { 355 add( 's', selection ); 356 } 357 358 form.setAttribute( 'method', 'POST' ); 359 form.setAttribute( 'action', pt_url ); 360 form.setAttribute( 'target', target ); 361 form.setAttribute( 'style', 'display: none;' ); 362 363 windowWidth = window.outerWidth || document.documentElement.clientWidth || 600; 364 windowHeight = window.outerHeight || document.documentElement.clientHeight || 700; 365 366 windowWidth = ( windowWidth < 800 || windowWidth > 5000 ) ? 600 : ( windowWidth * 0.7 ); 367 windowHeight = ( windowHeight < 800 || windowHeight > 3000 ) ? 700 : ( windowHeight * 0.9 ); 368 369 window.open( 'about:blank', target, 'width=' + windowWidth + ',height=' + windowHeight ); 370 371 document.body.appendChild( form ); 372 373 form.submit(); 374 } )( window, document, top.location.href, window.pt_url ); 375 ( function( window, document, href, pt_url ) { 376 var encodeURI = window.encodeURIComponent, 377 form = document.createElement( 'form' ), 378 head = document.getElementsByTagName( 'head' )[0], 379 img = new Image(), 380 target = '_press_this_app', 381 windowWidth, windowHeight, 382 metas, links, content, imgs, ifrs, 383 vid, selection; 384 385 if ( ! pt_url ) { 386 return; 387 } 388 389 if ( window.getSelection ) { 390 selection = window.getSelection() + ''; 391 } else if ( document.getSelection ) { 392 selection = document.getSelection() + ''; 393 } else if ( document.selection ) { 394 selection = document.selection.createRange().text; 395 } 396 397 pt_url += ( pt_url.indexOf( '?' ) > -1 ? '&' : '?' ) + 'buster=' + ( new Date().getTime() ); 398 399 if ( document.title.length && document.title.length <= 512 ) { 400 pt_url += '&t=' + encodeURI( document.title ); 401 } 402 403 if ( selection && selection.length <= 512 ) { 404 pt_url += '&s=' + encodeURI( selection ); 405 } 406 407 if ( href.match( /^https?:/ ) ) { 408 pt_url += '&u=' + encodeURI( href ); 409 } else { 410 top.location.href = pt_url; 411 return; 412 } 413 414 function add( name, value ) { 415 if ( typeof value === 'undefined' ) { 416 return; 417 } 418 419 var input = document.createElement( 'input' ); 420 421 input.name = name; 422 input.value = value; 423 input.type = 'hidden'; 424 425 form.appendChild( input ); 426 } 427 428 if ( href.match( /\/\/www\.youtube\.com\/watch/ ) ) { 429 add( '_embed[]', href ); 430 } else if ( href.match( /\/\/vimeo\.com\/(.+\/)?([\d]+)$/ ) ) { 431 add( '_embed[]', href ); 432 } else if ( href.match( /\/\/(www\.)?dailymotion\.com\/video\/.+$/ ) ) { 433 add( '_embed[]', href ); 434 } else if ( href.match( /\/\/soundcloud\.com\/.+$/ ) ) { 435 add( '_embed[]', href ); 436 } else if ( href.match( /\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/ ) ) { 437 add( '_embed[]', href ); 438 } else if ( href.match( /\/\/vine\.co\/v\/[^\/]+/ ) ) { 439 add( '_embed[]', href ); 440 } 441 442 metas = head.getElementsByTagName( 'meta' ) || []; 443 444 for ( var m = 0; m < metas.length; m++ ) { 445 if ( m >= 50 ) { 446 break; 447 } 448 449 var q = metas[ m ], 450 q_name = q.getAttribute( 'name' ), 451 q_prop = q.getAttribute( 'property' ), 452 q_cont = q.getAttribute( 'content' ); 453 454 if ( q_name ) { 455 add( '_meta[' + q_name + ']', q_cont ); 456 } else if ( q_prop ) { 457 add( '_meta[' + q_prop + ']', q_cont ); 458 } 459 } 460 461 links = head.getElementsByTagName( 'link' ) || []; 462 463 for ( var y = 0; y < links.length; y++ ) { 464 if ( y >= 50 ) { 465 break; 466 } 467 468 var g = links[ y ], 469 g_rel = g.getAttribute( 'rel' ); 470 471 if ( g_rel ) { 472 switch ( g_rel ) { 473 case 'canonical': 474 case 'icon': 475 case 'shortlink': 476 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 477 break; 478 case 'alternate': 479 if ( 'application/json+oembed' === g.getAttribute( 'type' ) ) { 480 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 481 } else if ( 'handheld' === g.getAttribute( 'media' ) ) { 482 add( '_links[' + g_rel + ']', g.getAttribute( 'href' ) ); 483 } 484 } 485 } 486 } 487 488 if ( document.body.getElementsByClassName ) { 489 content = document.body.getElementsByClassName( 'hfeed' )[0]; 490 } 491 492 content = document.getElementById( 'content' ) || content || document.body; 493 imgs = content.getElementsByTagName( 'img' ) || []; 494 495 for ( var n = 0; n < imgs.length; n++ ) { 496 if ( n >= 100 ) { 497 break; 498 } 499 500 if ( imgs[ n ].src.indexOf( 'avatar' ) > -1 || imgs[ n ].className.indexOf( 'avatar' ) > -1 ) { 501 continue; 502 } 503 504 img.src = imgs[ n ].src; 505 506 if ( img.width >= 256 && img.height >= 128 ) { 507 add( '_img[]', img.src ); 508 } 509 } 510 511 ifrs = document.body.getElementsByTagName( 'iframe' ) || []; 512 513 for ( var p = 0; p < ifrs.length; p++ ) { 514 if ( p >= 100 ) { 515 break; 516 } 517 518 vid = ifrs[ p ].src.match(/\/\/www\.youtube\.com\/embed\/([^\?]+)\?.+$/); 519 520 if ( vid && 2 === vid.length ) { 521 add( '_embed[]', 'https://www.youtube.com/watch?v=' + vid[1] ); 522 } 523 524 vid = ifrs[ p ].src.match( /\/\/player\.vimeo\.com\/video\/([\d]+)$/ ); 525 526 if ( vid && 2 === vid.length ) { 527 add( '_embed[]', 'https://vimeo.com/' + vid[1] ); 528 } 529 530 vid = ifrs[ p ].src.match( /\/\/vine\.co\/v\/([^\/]+)\/embed/ ); 531 532 if ( vid && 2 === vid.length ) { 533 add( '_embed[]', 'https://vine.co/v/' + vid[1] ); 534 } 535 } 536 537 if ( document.title && document.title > 512 ) { 538 add( 't', document.title ); 539 } 540 541 if ( selection && selection.length > 512 ) { 542 add( 's', selection ); 543 } 544 545 form.setAttribute( 'method', 'POST' ); 546 form.setAttribute( 'action', pt_url ); 547 form.setAttribute( 'target', target ); 548 form.setAttribute( 'style', 'display: none;' ); 549 550 windowWidth = window.outerWidth || document.documentElement.clientWidth || 600; 551 windowHeight = window.outerHeight || document.documentElement.clientHeight || 700; 552 553 windowWidth = ( windowWidth < 800 || windowWidth > 5000 ) ? 600 : ( windowWidth * 0.7 ); 554 windowHeight = ( windowHeight < 800 || windowHeight > 3000 ) ? 700 : ( windowHeight * 0.9 ); 555 556 window.open( 'about:blank', target, 'width=' + windowWidth + ',height=' + windowHeight ); 557 558 document.body.appendChild( form ); 559 560 form.submit(); 561 } )( window, document, top.location.href, window.pt_url ); -
src/wp-admin/js/post.js
7 7 8 8 window.wp = window.wp || {}; 9 9 10 // return an array with any duplicate, whitespace or values removed 11 function array_unique_noempty(a) { 12 var out = []; 13 jQuery.each( a, function(key, val) { 14 val = jQuery.trim(val); 15 if ( val && jQuery.inArray(val, out) == -1 ) 16 out.push(val); 17 } ); 18 return out; 19 } 20 21 ( function($) { 10 ( function( $ ) { 22 11 var titleHasFocus = false; 23 12 24 tagBox = {25 clean : function(tags) {26 var comma = postL10n.comma;27 if ( ',' !== comma )28 tags = tags.replace(new RegExp(comma, 'g'), ',');29 tags = tags.replace(/\s*,\s*/g, ',').replace(/,+/g, ',').replace(/[,\s]+$/, '').replace(/^[,\s]+/, '');30 if ( ',' !== comma )31 tags = tags.replace(/,/g, comma);32 return tags;33 },34 35 parseTags : function(el) {36 var id = el.id, num = id.split('-check-num-')[1], taxbox = $(el).closest('.tagsdiv'),37 thetags = taxbox.find('.the-tags'), comma = postL10n.comma,38 current_tags = thetags.val().split(comma), new_tags = [];39 delete current_tags[num];40 41 $.each( current_tags, function(key, val) {42 val = $.trim(val);43 if ( val ) {44 new_tags.push(val);45 }46 });47 48 thetags.val( this.clean( new_tags.join(comma) ) );49 50 this.quickClicks(taxbox);51 return false;52 },53 54 quickClicks : function(el) {55 var thetags = $('.the-tags', el),56 tagchecklist = $('.tagchecklist', el),57 id = $(el).attr('id'),58 current_tags, disabled;59 60 if ( !thetags.length )61 return;62 63 disabled = thetags.prop('disabled');64 65 current_tags = thetags.val().split(postL10n.comma);66 tagchecklist.empty();67 68 $.each( current_tags, function( key, val ) {69 var span, xbutton;70 71 val = $.trim( val );72 73 if ( ! val )74 return;75 76 // Create a new span, and ensure the text is properly escaped.77 span = $('<span />').text( val );78 79 // If tags editing isn't disabled, create the X button.80 if ( ! disabled ) {81 xbutton = $( '<a id="' + id + '-check-num-' + key + '" class="ntdelbutton">X</a>' );82 xbutton.click( function(){ tagBox.parseTags(this); });83 span.prepend(' ').prepend( xbutton );84 }85 86 // Append the span to the tag list.87 tagchecklist.append( span );88 });89 },90 91 flushTags : function(el, a, f) {92 var tagsval, newtags, text,93 tags = $('.the-tags', el),94 newtag = $('input.newtag', el),95 comma = postL10n.comma;96 a = a || false;97 98 text = a ? $(a).text() : newtag.val();99 tagsval = tags.val();100 newtags = tagsval ? tagsval + comma + text : text;101 102 newtags = this.clean( newtags );103 newtags = array_unique_noempty( newtags.split(comma) ).join(comma);104 tags.val(newtags);105 this.quickClicks(el);106 107 if ( !a )108 newtag.val('');109 if ( 'undefined' == typeof(f) )110 newtag.focus();111 112 return false;113 },114 115 get : function(id) {116 var tax = id.substr(id.indexOf('-')+1);117 118 $.post(ajaxurl, {'action':'get-tagcloud', 'tax':tax}, function(r, stat) {119 if ( 0 === r || 'success' != stat )120 r = wpAjax.broken;121 122 r = $('<p id="tagcloud-'+tax+'" class="the-tagcloud">'+r+'</p>');123 $('a', r).click(function(){124 tagBox.flushTags( $(this).closest('.inside').children('.tagsdiv'), this);125 return false;126 });127 128 $('#'+id).after(r);129 });130 },131 132 init : function() {133 var t = this, ajaxtag = $('div.ajaxtag');134 135 $('.tagsdiv').each( function() {136 tagBox.quickClicks(this);137 });138 139 $('input.tagadd', ajaxtag).click(function(){140 t.flushTags( $(this).closest('.tagsdiv') );141 });142 143 $('div.taghint', ajaxtag).click(function(){144 $(this).css('visibility', 'hidden').parent().siblings('.newtag').focus();145 });146 147 $('input.newtag', ajaxtag).blur(function() {148 if ( '' === this.value )149 $(this).parent().siblings('.taghint').css('visibility', '');150 }).focus(function(){151 $(this).parent().siblings('.taghint').css('visibility', 'hidden');152 }).keyup(function(e){153 if ( 13 == e.which ) {154 tagBox.flushTags( $(this).closest('.tagsdiv') );155 return false;156 }157 }).keypress(function(e){158 if ( 13 == e.which ) {159 e.preventDefault();160 return false;161 }162 }).each(function(){163 var tax = $(this).closest('div.tagsdiv').attr('id');164 $(this).suggest( ajaxurl + '?action=ajax-tag-search&tax=' + tax, { delay: 500, minchars: 2, multiple: true, multipleSep: postL10n.comma + ' ' } );165 });166 167 // save tags on post save/publish168 $('#post').submit(function(){169 $('div.tagsdiv').each( function() {170 tagBox.flushTags(this, false, 1);171 });172 });173 174 // tag cloud175 $('a.tagcloud-link').click(function(){176 tagBox.get( $(this).attr('id') );177 $(this).unbind().click(function(){178 $(this).siblings('.the-tagcloud').toggle();179 return false;180 });181 return false;182 });183 }184 };185 186 13 commentsBox = { 187 14 st : 0, 188 15 … … 572 399 573 400 // multi-taxonomies 574 401 if ( $('#tagsdiv-post_tag').length ) { 575 tagBox.init();402 window.tagBox && window.tagBox.init(); 576 403 } else { 577 404 $('#side-sortables, #normal-sortables, #advanced-sortables').children('div.postbox').each(function(){ 578 405 if ( this.id.indexOf('tagsdiv-') === 0 ) { 579 tagBox.init();406 window.tagBox && window.tagBox.init(); 580 407 return false; 581 408 } 582 409 }); -
src/wp-admin/js/press-this.js
1 /** 2 * PressThis App 3 * 4 */ 5 ( function( $, window ) { 6 var PressThis = function() { 7 var editor, 8 saveAlert = false, 9 $div = $( '<div>' ), 10 siteConfig = window.wpPressThisConfig || {}, 11 data = window.wpPressThisData || {}, 12 smallestWidth = 128, 13 interestingImages = getInterestingImages( data ) || [], 14 interestingEmbeds = getInterestingEmbeds( data ) || [], 15 hasEmptyTitleStr = false, 16 suggestedTitleStr = getSuggestedTitle( data ), 17 suggestedContentStr = getSuggestedContent( data ), 18 hasSetFocus = false, 19 catsCache = [], 20 transitionEndEvent = ( function() { 21 var style = document.documentElement.style; 22 23 if ( typeof style.transition !== 'undefined' ) { 24 return 'transitionend'; 25 } 26 27 if ( typeof style.WebkitTransition !== 'undefined' ) { 28 return 'webkitTransitionEnd'; 29 } 30 31 return false; 32 }() ); 33 34 /* *************************************************************** 35 * HELPER FUNCTIONS 36 *************************************************************** */ 37 38 /** 39 * Emulates our PHP __() gettext function, powered by the strings exported in pressThisL10n. 40 * 41 * @param key string Key of the string to be translated, as found in pressThisL10n. 42 * @returns string Original or translated string, or empty string if no key. 43 */ 44 function __( key ) { 45 if ( key && window.pressThisL10n ) { 46 return window.pressThisL10n[key] || key; 47 } 48 49 return key || ''; 50 } 51 52 /** 53 * Strips HTML tags 54 * 55 * @param string string Text to have the HTML tags striped out of. 56 * @returns string Stripped text. 57 */ 58 function stripTags( string ) { 59 string = string || ''; 60 61 return string 62 .replace( /<!--[\s\S]*?(-->|$)/g, '' ) 63 .replace( /<(script|style)[^>]*>[\s\S]*?(<\/\1>|$)/ig, '' ) 64 .replace( /<\/?[a-z][^>]*>/ig, '' ); 65 } 66 67 // TODO: needed? 68 function entityEncode( text ) { 69 return $div.text( text ).html(); 70 } 71 72 /** 73 * Strip HTML tags and entity encode some of the HTML special chars. 74 * 75 * @param text string Text. 76 * @returns string Sanitized text. 77 */ 78 function sanitizeText( text ) { 79 text = stripTags( text ); 80 81 return text 82 .replace( /\\/, '' ) 83 .replace( /</g, '<' ) 84 .replace( />/g, '>' ) 85 .replace( /"/g, '"' ) 86 .replace( /'/g, ''' ); 87 } 88 89 /** 90 * Allow only HTTP or protocol relative URLs. 91 * 92 * @param url string The URL. 93 * @returns string Processed URL. 94 */ 95 function checkUrl( url ) { 96 url = $.trim( url || '' ); 97 98 if ( /^(?:https?:)?\/\//.test( url ) ) { 99 url = stripTags( url ); 100 return url.replace( /["\\]+/g, '' ); 101 } 102 103 return ''; 104 } 105 106 /** 107 * Gets the source page's canonical link, based on passed location and meta data. 108 * 109 * @param data object Usually WpPressThis_App.data 110 * @returns string Discovered canonical URL, or empty 111 */ 112 function getCanonicalLink( data ) { 113 if ( ! data || data.length ) { 114 return ''; 115 } 116 117 var link = ''; 118 119 if ( data._links ) { 120 if ( data._links.canonical && data._links.canonical.length ) { 121 link = data._links.canonical; 122 } 123 } 124 125 if ( ! link.length && data.u ) { 126 link = data.u; 127 } 128 129 if ( ! link.length && data._meta ) { 130 if ( data._meta['twitter:url'] && data._meta['twitter:url'].length ) { 131 link = data._meta['twitter:url']; 132 } else if ( data._meta['og:url'] && data._meta['og:url'].length ) { 133 link = data._meta['og:url']; 134 } 135 } 136 137 return decodeURI( link ); 138 } 139 140 /** 141 * Gets the source page's site name, based on passed meta data. 142 * 143 * @param data object Usually WpPressThis_App.data 144 * @returns string Discovered site name, or empty 145 */ 146 function getSourceSiteName( data ) { 147 if ( ! data || data.length ) { 148 return ''; 149 } 150 151 var name=''; 152 153 if ( data._meta ) { 154 if ( data._meta['og:site_name'] && data._meta['og:site_name'].length ) { 155 name = data._meta['og:site_name']; 156 } else if ( data._meta['application-name'] && data._meta['application-name'].length ) { 157 name = data._meta['application-name']; 158 } 159 } 160 161 return name.replace( /\\/g, '' ); 162 } 163 164 /** 165 * Gets the source page's title, based on passed title and meta data. 166 * 167 * @param data object Usually WpPressThis_App.data 168 * @returns string Discovered page title, or empty 169 */ 170 function getSuggestedTitle( data ) { 171 if ( ! data || data.length ) { 172 return __( 'newPost' ); 173 } 174 175 var title = ''; 176 177 if ( data.t ) { 178 title = data.t; 179 } 180 181 if ( ! title.length && data._meta ) { 182 if ( data._meta['twitter:title'] && data._meta['twitter:title'].length ) { 183 title = data._meta['twitter:title']; 184 } else if ( data._meta['og:title'] && data._meta['og:title'].length ) { 185 title = data._meta['og:title']; 186 } else if ( data._meta.title && data._meta.title.length ) { 187 title = data._meta.title; 188 } 189 } 190 191 if ( ! title.length ) { 192 title = __( 'newPost' ); 193 hasEmptyTitleStr = true; 194 } 195 196 return title.replace( /\\/g, '' ); 197 } 198 199 /** 200 * Gets the source page's suggested content, based on passed data (description, selection, etc). 201 * Features a blockquoted excerpt, as well as content attribution, if any. 202 * 203 * @param data object Usually WpPressThis_App.data 204 * @returns string Discovered content, or empty 205 */ 206 function getSuggestedContent( data ) { 207 if ( ! data || data.length ) { 208 return ''; 209 } 210 211 var content = '', 212 title = getSuggestedTitle( data ), 213 url = getCanonicalLink( data ), 214 siteName = getSourceSiteName( data ); 215 216 if ( data.s && data.s.length ) { 217 content = data.s; 218 } else if ( data._meta ) { 219 if ( data._meta['twitter:description'] && data._meta['twitter:description'].length ) { 220 content = data._meta['twitter:description']; 221 } else if ( data._meta['og:description'] && data._meta['og:description'].length ) { 222 content = data._meta['og:description']; 223 } else if ( data._meta.description && data._meta.description.length ) { 224 content = data._meta.description; 225 } 226 } 227 228 // Wrap suggested content in blockquote tag, if we have any. 229 content = ( content.length ? '<blockquote class="press-this-suggested-content">' + sanitizeText( content ) + '</blockquote>' : '' ); 230 231 // Add a source attribution if there is one available. 232 if ( ( ( title.length && __( 'newPost' ) !== title ) || siteName.length ) && url.length ) { 233 content += '<p class="press-this-suggested-source">'; 234 content += __( 'source' ); 235 content += ' <cite>'; 236 content += __( 'sourceLink').replace( '%1$s', encodeURI( url ) ).replace( '%2$s', sanitizeText( title || siteName ) ); 237 content += '</cite></p>'; 238 } 239 240 if ( ! content ) { 241 content = ''; 242 } 243 244 return content.replace( /\\/g, '' ); 245 } 246 247 /** 248 * Tests if what was passed as an embed URL is deemed to be embeddable in the editor. 249 * 250 * @param url string Passed URl, usually from WpPressThis_App.data._embed 251 * @returns boolean 252 */ 253 function isEmbeddable( url ) { 254 if ( ! url ) { 255 return false; 256 } else if ( url.match( /\/\/(m\.|www\.)?youtube\.com\/watch\?/ ) || url.match( /\/youtu\.be\/.+$/ ) ) { 257 return true; 258 } else if ( url.match( /\/\/vimeo\.com\/(.+\/)?[\d]+$/ ) ) { 259 return true; 260 } else if ( url.match( /\/\/(www\.)?dailymotion\.com\/video\/.+$/ ) ) { 261 return true; 262 } else if ( url.match( /\/\/soundcloud\.com\/.+$/ ) ) { 263 return true; 264 } else if ( url.match( /\/\/twitter\.com\/[^\/]+\/status\/[\d]+$/ ) ) { 265 return true; 266 } else if ( url.match( /\/\/vine\.co\/v\/[^\/]+/ ) ) { 267 return true; 268 } 269 270 return false; 271 } 272 273 /** 274 * Tests if what was passed as an image URL is deemed to be interesting enough to offer to the user for selection. 275 * 276 * @param src string Passed URl, usually from WpPressThis_App.data._ing 277 * @returns boolean Test for false 278 */ 279 function isSrcUninterestingPath( src ) { 280 if ( src.match( /\/ad[sx]{1}?\// ) ) { 281 // Ads 282 return true; 283 } else if ( src.match( /(\/share-?this[^\.]+?\.[a-z0-9]{3,4})(\?.*)?$/ ) ) { 284 // Share-this type button 285 return true; 286 } else if ( src.match( /\/(spinner|loading|spacer|blank|rss)\.(gif|jpg|png)/ ) ) { 287 // Loaders, spinners, spacers 288 return true; 289 } else if ( src.match( /\/([^\.\/]+[-_]{1})?(spinner|loading|spacer|blank)s?([-_]{1}[^\.\/]+)?\.[a-z0-9]{3,4}/ ) ) { 290 // Fancy loaders, spinners, spacers 291 return true; 292 } else if ( src.match( /([^\.\/]+[-_]{1})?thumb[^.]*\.(gif|jpg|png)$/ ) ) { 293 // Thumbnails, too small, usually irrelevant to context 294 return true; 295 } else if ( src.match( /\/wp-includes\// ) ) { 296 // Classic WP interface images 297 return true; 298 } else if ( src.match( /[^\d]{1}\d{1,2}x\d+\.(gif|jpg|png)$/ ) ) { 299 // Most often tiny buttons/thumbs (< 100px wide) 300 return true; 301 } else if ( src.indexOf( '/g.gif' ) > -1 ) { 302 // Classic WP stats gif 303 return true; 304 } else if ( src.indexOf( '/pixel.mathtag.com' ) > -1 ) { 305 // See mathtag.com 306 return true; 307 } 308 return false; 309 } 310 311 /** 312 * Get a list of valid embeds from what was passed via WpPressThis_App.data._embed on page load. 313 * 314 * @returns array 315 */ 316 function getInterestingEmbeds() { 317 var embeds = data._embed || [], 318 interestingEmbeds = [], 319 alreadySelected = []; 320 321 if ( embeds.length ) { 322 $.each( embeds, function ( i, src ) { 323 if ( !src || !src.length ) { 324 // Skip: no src value 325 return; 326 } else if ( !isEmbeddable( src ) ) { 327 // Skip: not deemed embeddable 328 return; 329 } 330 331 var schemelessSrc = src.replace( /^https?:/, '' ); 332 333 if ( $.inArray( schemelessSrc, alreadySelected ) > -1 ) { 334 // Skip: already shown 335 return; 336 } 337 338 interestingEmbeds.push( src ); 339 alreadySelected.push( schemelessSrc ); 340 } ); 341 } 342 343 return interestingEmbeds; 344 } 345 346 /** 347 * Get what is likely the most valuable image from what was passed via WpPressThis_App.data._img and WpPressThis_App.data._meta on page load. 348 * 349 * @returns array 350 */ 351 function getFeaturedImage( data ) { 352 var featured = ''; 353 354 if ( ! data || ! data._meta ) { 355 return ''; 356 } 357 358 if ( data._meta['twitter:image0:src'] && data._meta['twitter:image0:src'].length ) { 359 featured = data._meta['twitter:image0:src']; 360 } else if ( data._meta['twitter:image0'] && data._meta['twitter:image0'].length ) { 361 featured = data._meta['twitter:image0']; 362 } else if ( data._meta['twitter:image:src'] && data._meta['twitter:image:src'].length ) { 363 featured = data._meta['twitter:image:src']; 364 } else if ( data._meta['twitter:image'] && data._meta['twitter:image'].length ) { 365 featured = data._meta['twitter:image']; 366 } else if ( data._meta['og:image'] && data._meta['og:image'].length ) { 367 featured = data._meta['og:image']; 368 } else if ( data._meta['og:image:secure_url'] && data._meta['og:image:secure_url'].length ) { 369 featured = data._meta['og:image:secure_url']; 370 } 371 372 featured = checkUrl( featured ); 373 374 return ( isSrcUninterestingPath( featured ) ) ? '' : featured; 375 } 376 377 /** 378 * Get a list of valid images from what was passed via WpPressThis_App.data._img and WpPressThis_App.data._meta on page load. 379 * 380 * @returns array 381 */ 382 function getInterestingImages( data ) { 383 var imgs = data._img || [], 384 featuredPict = getFeaturedImage( data ) || '', 385 interestingImgs = [], 386 alreadySelected = []; 387 388 if ( featuredPict.length ) { 389 interestingImgs.push( featuredPict ); 390 alreadySelected.push( featuredPict.replace(/^https?:/, '') ); 391 } 392 393 if ( imgs.length ) { 394 $.each( imgs, function ( i, src ) { 395 src = src.replace( /http:\/\/[\d]+\.gravatar\.com\//, 'https://secure.gravatar.com/' ); 396 src = checkUrl( src ); 397 398 if ( ! src || ! src.length ) { 399 // Skip: no src value 400 return; 401 } 402 403 var schemelessSrc = src.replace( /^https?:/, '' ); 404 405 if ( Array.prototype.indexOf && alreadySelected.indexOf( schemelessSrc ) > -1 ) { 406 // Skip: already shown 407 return; 408 } else if ( isSrcUninterestingPath( src ) ) { 409 // Skip: spinner, stat, ad, or spacer pict 410 return; 411 } else if ( src.indexOf( 'avatar' ) > -1 && interestingImgs.length >= 15 ) { 412 // Skip: some type of avatar and we've already gathered more than 23 diff images to show 413 return; 414 } 415 416 interestingImgs.push( src ); 417 alreadySelected.push( schemelessSrc ); 418 } ); 419 } 420 421 return interestingImgs; 422 } 423 424 /** 425 * Show UX spinner 426 */ 427 function showSpinner() { 428 $( '#spinner' ).addClass( 'show' ); 429 $( '.post-actions button' ).each( function() { 430 $( this ).attr( 'disabled', 'disabled' ); 431 } ); 432 } 433 434 /** 435 * Hide UX spinner 436 */ 437 function hideSpinner() { 438 $( '#spinner' ).removeClass( 'show' ); 439 $( '.post-actions button' ).each( function() { 440 $( this ).removeAttr( 'disabled' ); 441 } ); 442 } 443 444 /** 445 * Submit the post form via AJAX, and redirect to the proper screen if published vs saved as a draft. 446 * 447 * @param action string publish|draft 448 */ 449 function submitPost( action ) { 450 saveAlert = false; 451 showSpinner(); 452 453 var $form = $( '#pressthis-form' ); 454 455 if ( 'publish' === action ) { 456 $( '#post_status' ).val( 'publish' ); 457 } 458 459 editor && editor.save(); 460 461 $( '#title-field' ).val( sanitizeText( $( '#title-container' ).text() ) ); 462 463 // Make sure to flush out the tags with tagBox before saving 464 if ( window.tagBox ) { 465 $( 'div.tagsdiv' ).each( function() { 466 window.tagBox.flushTags( this, false, 1 ); 467 } ); 468 } 469 470 var data = $form.serialize(); 471 472 $.ajax( { 473 type: 'post', 474 url: window.ajaxurl, 475 data: data, 476 success: function( response ) { 477 if ( ! response.success ) { 478 renderError( response.data.errorMessage ); 479 hideSpinner(); 480 } else if ( response.data.redirect ) { 481 if ( window.opener && siteConfig.redir_in_parent ) { 482 try { 483 window.opener.location.href = response.data.redirect; 484 } catch( er ) {} 485 486 window.self.close(); 487 } else { 488 window.location.href = response.data.redirect; 489 } 490 } 491 } 492 } ); 493 } 494 495 /** 496 * Inserts the media a user has selected from the presented list inside the editor, as an image or embed, based on type 497 * 498 * @param type string img|embed 499 * @param src string Source URL 500 * @param link string Optional destination link, for images (defaults to src) 501 */ 502 function insertSelectedMedia( type, src, link ) { 503 var newContent = ''; 504 505 if ( ! editor ) { 506 return; 507 } 508 509 src = checkUrl( src ); 510 link = checkUrl( link ); 511 512 if ( 'img' === type ) { 513 if ( ! link || ! link.length ) { 514 link = src; 515 } 516 517 newContent = '<a href="' + link + '"><img class="alignnone size-full" src="' + src + '" /></a>\n'; 518 } else { 519 newContent = '[embed]' + src + '[/embed]\n'; 520 } 521 522 if ( ! hasSetFocus ) { 523 // Append to top of content on 1st media insert 524 editor.setContent( newContent + editor.getContent() ); 525 } else { 526 // Or add where the cursor was last positioned in TinyMCE 527 editor.execCommand( 'mceInsertContent', false, newContent ); 528 } 529 530 hasSetFocus = true; 531 } 532 533 /** 534 * Adds the currently selected post format next to the option, in the options panel. 535 * 536 * @param format string Post format to be displayed 537 */ 538 function setPostFormatString( format ) { 539 if ( ! format || ! siteConfig || ! siteConfig.post_formats || ! siteConfig.post_formats[ format ] ) { 540 return; 541 } 542 $( '#post-option-post-format' ).text( siteConfig.post_formats[ format ] ); 543 } 544 545 /** 546 * Save a new user-generated category via AJAX 547 */ 548 function saveNewCategory() { 549 var data = { 550 action: 'press-this-add-category', 551 post_id: $( '#post_ID' ).val() || 0, 552 name: $( '#new-category' ).val() || '', 553 new_cat_nonce: $( '#_ajax_nonce-add-category' ).val() || '', 554 parent: $( '#new-category-parent' ).val() || 0 555 }; 556 557 $.post( window.ajaxurl, data, function( response ) { 558 if ( ! response.success ) { 559 renderError( response.data.errorMessage ); 560 } else { 561 // TODO: change if/when the html changes. 562 var $parent, $ul, 563 $wrap = $( 'ul.categories-select' ); 564 565 $.each( response.data, function( i, newCat ) { 566 var $node = $( '<li>' ).attr( 'id', 'category-' + newCat.term_id ) 567 .append( $( '<label class="selectit">' ).text( newCat.name ) 568 .append( $( '<input type="checkbox" name="post_category[]" checked>' ).attr( 'value', newCat.term_id ) ) ); 569 570 if ( newCat.parent ) { 571 if ( ! $ul || ! $ul.length ) { 572 $parent = $wrap.find( '#category-' + newCat.parent ); 573 $ul = $parent.find( 'ul.children:first' ); 574 575 if ( ! $ul.length ) { 576 $ul = $( '<ul class="children">' ).appendTo( $parent ); 577 } 578 } 579 580 $ul.append( $node ); 581 // TODO: set focus on 582 } else { 583 $wrap.prepend( $node ); 584 } 585 } ); 586 587 refreshCatsCache(); 588 } 589 } ); 590 } 591 592 /* *************************************************************** 593 * RENDERING FUNCTIONS 594 *************************************************************** */ 595 596 /** 597 * Hide the form letting users enter a URL to be scanned, if a URL was already passed. 598 */ 599 function renderToolsVisibility() { 600 if ( data.u && data.u.match( /^https?:/ ) ) { 601 $( '#scanbar' ).hide(); 602 } 603 } 604 605 /** 606 * Render error notice 607 * 608 * @param msg string Notice/error message 609 * @param error string error|notice CSS class for display 610 */ 611 function renderNotice( msg, error ) { 612 var $alerts = $( '.editor-wrapper div.alerts' ), 613 className = error ? 'is-error' : 'is-notice'; 614 615 $alerts.append( $( '<p class="' + className + '">' ).text( msg ) ); 616 } 617 618 /** 619 * Render error notice 620 * 621 * @param msg string Error message 622 */ 623 function renderError( msg ) { 624 renderNotice( msg, true ); 625 } 626 627 /** 628 * Render notices on page load, if any already 629 */ 630 function renderStartupNotices() { 631 // Render errors sent in the data, if any 632 if ( data.errors && data.errors.length ) { 633 $.each( data.errors, function( i, msg ) { 634 renderError( msg ); 635 } ); 636 } 637 638 // Prompt user to upgrade their bookmarklet if there is a version mismatch. 639 if ( data.v && data._version && data.v !== data._version ) { 640 $( '.should-upgrade-bookmarklet' ).removeClass( 'is-hidden' ); 641 } 642 } 643 644 /** 645 * Render the suggested title, if any 646 */ 647 function renderSuggestedTitle() { 648 var suggestedTitle = suggestedTitleStr || '', 649 $title = $( '#title-container' ); 650 651 if ( ! hasEmptyTitleStr ) { 652 $( '#title-field' ).val( suggestedTitle ); 653 $title.text( suggestedTitle ); 654 $( '.post-title-placeholder' ).addClass( 'is-hidden' ); 655 } 656 657 $title.on( 'keyup', function() { 658 saveAlert = true; 659 }).on( 'paste', function() { 660 saveAlert = true; 661 662 setTimeout( function() { 663 $title.text( $title.text() ); 664 }, 100 ); 665 } ); 666 667 } 668 669 /** 670 * Render the suggested content, if any 671 */ 672 function renderSuggestedContent() { 673 if ( ! suggestedContentStr || ! suggestedContentStr.length ) { 674 return; 675 } 676 677 if ( ! editor ) { 678 editor = window.tinymce.get( 'pressthis' ); 679 } 680 681 if ( editor ) { 682 editor.setContent( suggestedContentStr ); 683 editor.on( 'focus', function() { 684 hasSetFocus = true; 685 } ); 686 } 687 688 } 689 690 /** 691 * Render the detected images and embed for selection, if any 692 */ 693 function renderDetectedMedia() { 694 var mediaContainer = $( '#featured-media-container'), 695 listContainer = $( '#all-media-container' ), 696 found = 0; 697 698 listContainer.empty(); 699 700 if ( ( interestingEmbeds && interestingEmbeds.length ) || ( interestingImages && interestingImages.length ) ) { 701 listContainer.append( '<h2 class="screen-reader-text">' + __( 'allMediaHeading' ) + '</h2><ul class="wppt-all-media-list"/>' ); 702 } 703 704 if ( interestingEmbeds && interestingEmbeds.length ) { 705 $.each( interestingEmbeds, function ( i, src ) { 706 src = checkUrl( src ); 707 708 if ( ! isEmbeddable( src ) ) { 709 return; 710 } 711 712 var displaySrc = '', 713 cssClass = 'suggested-media-thumbnail suggested-media-embed'; 714 715 if ( src.indexOf( 'youtube.com/' ) > -1 ) { 716 displaySrc = 'https://i.ytimg.com/vi/' + src.replace( /.+v=([^&]+).*/, '$1' ) + '/hqdefault.jpg'; 717 cssClass += ' is-video'; 718 } else if ( src.indexOf( 'youtu.be/' ) > -1 ) { 719 displaySrc = 'https://i.ytimg.com/vi/' + src.replace( /\/([^\/])$/, '$1' ) + '/hqdefault.jpg'; 720 cssClass += ' is-video'; 721 } else if ( src.indexOf( 'dailymotion.com' ) > -1 ) { 722 displaySrc = src.replace( '/video/', '/thumbnail/video/' ); 723 cssClass += ' is-video'; 724 } else if ( src.indexOf( 'soundcloud.com' ) > -1 ) { 725 cssClass += ' is-audio'; 726 } else if ( src.indexOf( 'twitter.com' ) > -1 ) { 727 cssClass += ' is-tweet'; 728 } else { 729 cssClass += ' is-video'; 730 } 731 732 $( '<li></li>', { 733 'id': 'embed-' + i + '-container', 734 'class': cssClass, 735 'tabindex': '0' 736 } ).css( { 737 'background-image': ( displaySrc.length ) ? 'url(' + displaySrc + ')' : null 738 } ).html( 739 '<span class="screen-reader-text">' + __( 'suggestedEmbedAlt' ).replace( '%d', i + 1 ) + '</span>' 740 ).on( 'click keypress', function ( e ) { 741 if ( e.type === 'click' || e.which === 13 ) { 742 insertSelectedMedia( 'embed',src ); 743 } 744 } ).appendTo( '.wppt-all-media-list', listContainer ); 745 746 found++; 747 } ); 748 } 749 750 if ( interestingImages && interestingImages.length ) { 751 $.each( interestingImages, function ( i, src ) { 752 src = checkUrl( src ); 753 754 var displaySrc = src.replace(/^(http[^\?]+)(\?.*)?$/, '$1'); 755 if ( src.indexOf( 'files.wordpress.com/' ) > -1 ) { 756 displaySrc = displaySrc.replace(/\?.*$/, '') + '?w=' + smallestWidth; 757 } else if ( src.indexOf( 'gravatar.com/' ) > -1 ) { 758 displaySrc = displaySrc.replace( /\?.*$/, '' ) + '?s=' + smallestWidth; 759 } else { 760 displaySrc = src; 761 } 762 763 $( '<li></li>', { 764 'id': 'img-' + i + '-container', 765 'class': 'suggested-media-thumbnail is-image', 766 'tabindex': '0' 767 } ).css( { 768 'background-image': 'url(' + displaySrc + ')' 769 } ).html( 770 '<span class="screen-reader-text">' +__( 'suggestedImgAlt' ).replace( '%d', i + 1 ) + '</span>' 771 ).on( 'click keypress', function ( e ) { 772 if ( e.type === 'click' || e.which === 13 ) { 773 insertSelectedMedia( 'img', src, data.u ); 774 } 775 } ).appendTo( '.wppt-all-media-list', listContainer ); 776 777 found++; 778 } ); 779 } 780 781 if ( ! found ) { 782 mediaContainer.removeClass( 'all-media-visible' ).addClass( 'no-media'); 783 return; 784 } 785 786 mediaContainer.removeClass( 'no-media' ).addClass( 'all-media-visible' ); 787 } 788 789 /* *************************************************************** 790 * MONITORING FUNCTIONS 791 *************************************************************** */ 792 793 /** 794 * Interactive navigation behavior for the options modal (post format, tags, categories) 795 */ 796 function monitorOptionsModal() { 797 var isOffScreen = 'is-off-screen', 798 isHidden = 'is-hidden', 799 $postOptions = $( '.post-options' ), 800 $postOption = $( '.post-option' ), 801 $settingModal = $( '.setting-modal' ), 802 $modalClose = $( '.modal-close' ); 803 804 $postOption.on( 'click', function( event ) { 805 var index = $( this ).index(), 806 $targetSettingModal = $settingModal.eq( index ); 807 808 event.preventDefault(); 809 810 $postOptions 811 .addClass( isOffScreen ) 812 .one( transitionEndEvent, function() { 813 $( this ).addClass( isHidden ); 814 } ); 815 816 $targetSettingModal 817 .removeClass( isOffScreen + ' ' + isHidden ) 818 .one( transitionEndEvent, function() { 819 $( this ).find( $modalClose ).focus(); 820 } ); 821 } ); 822 823 $modalClose.on( 'click', function( event ) { 824 var $targetSettingModal = $( this ).parent(), 825 index = $targetSettingModal.index(); 826 827 event.preventDefault(); 828 829 $postOptions 830 .removeClass( isOffScreen + ' ' + isHidden ); 831 832 $targetSettingModal 833 .addClass( isOffScreen ) 834 .one( transitionEndEvent, function() { 835 $( this ).addClass( isHidden ); 836 } ); 837 838 // For browser that don't support transitionend. 839 if ( ! transitionEndEvent ) { 840 setTimeout( function() { 841 $targetSettingModal.addClass( isHidden ); 842 }, 350 ); 843 } 844 845 $postOption.eq( index - 1 ).focus(); 846 } ); 847 } 848 849 /** 850 * Interactive behavior for the sidebar toggle, to show the options modals 851 */ 852 function monitorSidebarToggle() { 853 var $optOpen = $( '.options-open' ), 854 $optClose = $( '.options-close' ), 855 $postOption = $( '.post-option' ), 856 $sidebar = $( '.options-panel' ), 857 $postActions = $( '.press-this-actions' ), 858 $scanbar = $( '#scanbar' ), 859 isOffScreen = 'is-off-screen', 860 isHidden = 'is-hidden', 861 ifOffHidden = isOffScreen + ' ' + isHidden; 862 863 $optOpen.on( 'click', function(){ 864 $optOpen.addClass( isHidden ); 865 $optClose.removeClass( isHidden ); 866 $postActions.addClass( isHidden ); 867 $scanbar.addClass( isHidden ); 868 869 $sidebar 870 .removeClass( ifOffHidden ) 871 .one( 'transitionend', function() { 872 $postOption.eq( 0 ).focus(); 873 } ); 874 } ); 875 876 $optClose.on( 'click', function(){ 877 $optClose.addClass( isHidden ); 878 $optOpen.removeClass( isHidden ); 879 $postActions.removeClass( isHidden ); 880 $scanbar.removeClass( isHidden ); 881 882 $sidebar 883 .addClass( isOffScreen ) 884 .one( 'transitionend', function() { 885 $( this ).addClass( isHidden ); 886 // Reset to options list 887 $( '.post-options' ).removeClass( ifOffHidden ); 888 $( '.setting-modal').addClass( ifOffHidden ); 889 } ); 890 } ); 891 } 892 893 /** 894 * Interactive behavior for the post title's field placeholder 895 */ 896 function monitorPlaceholder() { 897 var $selector = $( '#title-container'), 898 $placeholder = $('.post-title-placeholder'); 899 900 $selector.on( 'focus', function() { 901 $placeholder.addClass('is-hidden'); 902 } ); 903 904 $selector.on( 'blur', function() { 905 var textLength = $( this ).text().length; 906 907 if ( ! textLength ) { 908 $placeholder.removeClass('is-hidden'); 909 } 910 } ); 911 } 912 913 /* *************************************************************** 914 * PROCESSING FUNCTIONS 915 *************************************************************** */ 916 917 /** 918