Make WordPress Core

Ticket #28673: 28673.2.diff

File 28673.2.diff, 81.2 KB (added by paulwilde, 9 years ago)

Clean patch which applies on latest trunk

  • trunk/src/wp-admin/admin-ajax.php

     
    6060        'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
    6161        'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
    6262        'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
    63         'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail'
     63        'save-user-color-scheme', 'update-widget', 'query-themes', 'query-plugins', 'parse-embed',
     64        'set-attachment-thumbnail'
    6465);
    6566
    6667// Register core Ajax calls.
     
    7374add_action( 'wp_ajax_nopriv_heartbeat', 'wp_ajax_nopriv_heartbeat', 1 );
    7475
    7576if ( is_user_logged_in() ) {
     77
    7678        /**
    7779         * Fires authenticated AJAX actions for logged-in users.
    7880         *
  • trunk/src/wp-admin/css/colors/_admin.scss

     
    434434        background: $highlight-color;
    435435}
    436436
    437 .theme-section.current,
    438 .theme-filter.current {
    439         border-bottom-color: $menu-background;
    440 }
    441 
    442 body.more-filters-opened .more-filters {
    443         color: $menu-text;
    444         background-color: $menu-background;
    445 }
    446 
    447 body.more-filters-opened .more-filters:before {
    448         color: $menu-text;
    449 }
    450 
    451 body.more-filters-opened .more-filters:hover,
    452 body.more-filters-opened .more-filters:focus {
    453         background-color: $menu-highlight-background;
    454         color: $menu-highlight-text;
    455 }
    456 
    457 body.more-filters-opened .more-filters:hover:before,
    458 body.more-filters-opened .more-filters:focus:before {
    459         color: $menu-highlight-text;
    460 }
    461 
    462437.theme-install-overlay .close-full-overlay:hover,
    463438.theme-install-overlay .close-full-overlay:focus,
    464439.theme-install-overlay .previous-theme:hover,
     
    469444        color: $menu-highlight-text;
    470445}
    471446
     447/* Filter */
     448
     449.wp-filter-link.current {
     450        border-bottom-color: $menu-background;
     451}
     452
     453body.show-filter-drawer {
     454        .wp-filter-drawer-toggle {
     455                background-color: $menu-background;
     456                color: $menu-text;
     457        }
     458        .wp-filter-drawer-toggle:before {
     459                color: $menu-text;
     460        }
     461        .wp-filter-drawer-toggle:hover,
     462        .wp-filter-drawer-toggle:focus {
     463                background-color: $menu-highlight-background;
     464                color: $menu-highlight-text;   
     465        }
     466        .wp-filter-drawer-toggle:hover:before,
     467        .wp-filter-drawer-toggle:focus:before {
     468                color: $menu-highlight-text;   
     469        }
     470}
     471
    472472/* Widgets */
    473473
    474474.widgets-chooser li.widgets-chooser-selected {
     
    529529        background: $menu-highlight-background;
    530530}
    531531
    532 .star-rating .star {
     532.star-rating .star,
     533.rating span:before {
    533534        color: $highlight-color;
    534535}
    535536
  • trunk/src/wp-admin/css/common.css

     
    627627        padding-right: 0;
    628628}
    629629
     630.wp-title-count {
     631        display: inline;
     632        padding: 4px 10px;
     633        -webkit-border-radius: 30px;
     634        border-radius: 30px;
     635        background: #777;
     636        font-size: 14px;
     637        font-weight: 600;
     638        color: #fff;
     639        position: relative;
     640        top: -3px;
     641        margin-left: 5px;
     642        margin-right: 20px;
     643}
     644
    630645.wp-dialog {
    631646        background-color: #fff;
    632647}
     
    18001815        margin: 6px 0 0;
    18011816}
    18021817
     1818.rating span:before {
     1819        content: "\f154";
     1820        display: inline-block;
     1821        -webkit-font-smoothing: antialiased;
     1822        font: normal 20px/1 'dashicons';
     1823        vertical-align: top;
     1824        color: #0074a2;
     1825}
     1826/* Half stars */
     1827.rating-10 span.one:before,
     1828.rating-30 span.two:before,
     1829.rating-50 span.three:before,
     1830.rating-70 span.four:before,
     1831.rating-90 span.five:before {
     1832        content: "\f459";
     1833}
     1834/* Full stars */
     1835.rating-20 span.one:before {
     1836        content: "\f155";
     1837}
     1838.rating-30 span.one:before,
     1839.rating-40 span.one:before,
     1840.rating-40 span.two:before {
     1841        content: "\f155";
     1842}
     1843.rating-50 span.one:before,
     1844.rating-50 span.two:before,
     1845.rating-60 span.one:before,
     1846.rating-60 span.two:before,
     1847.rating-60 span.three:before {
     1848        content: "\f155";
     1849}
     1850.rating-70 span.one:before,
     1851.rating-70 span.two:before,
     1852.rating-70 span.three:before,
     1853.rating-80 span.one:before,
     1854.rating-80 span.two:before,
     1855.rating-80 span.three:before,
     1856.rating-80 span.four:before {
     1857        content: "\f155";
     1858}
     1859.rating-90 span.one:before,
     1860.rating-90 span.two:before,
     1861.rating-90 span.three:before,
     1862.rating-90 span.four:before,
     1863.rating-100 span.one:before,
     1864.rating-100 span.two:before,
     1865.rating-100 span.three:before,
     1866.rating-100 span.four:before,
     1867.rating-100 span.five:before {
     1868        content: "\f155";
     1869}
     1870.rating .ratings {
     1871        display: inline;
     1872        margin-left: 10px;
     1873        line-height: 20px;
     1874        color: #999;
     1875}
     1876
    18031877/* Plugin install thickbox */
    18041878#plugin-information {
    18051879        background: #fcfcfc;
  • trunk/src/wp-admin/css/filter.css

     
     1.wp-filter {
     2        background: #fff;
     3        border: 1px solid #e5e5e5;
     4        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     5        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     6        -webkit-box-sizing: border-box;
     7        -moz-box-sizing: border-box;
     8        box-sizing: border-box;
     9        color: #555;
     10        display: inline-block;
     11        font-size: 13px;
     12        margin: 12px 0 22px;
     13        padding: 0 20px;
     14        position: relative;
     15        width: 100%;
     16}
     17.wp-filter a {
     18        text-decoration: none;
     19}
     20
     21.wp-filter-count {
     22        display: inline-block;
     23        vertical-align: middle;
     24        min-width: 4em;
     25}
     26.wp-filter-count .count {
     27        display: inline-block;
     28        padding: 4px 10px;
     29        -webkit-border-radius: 30px;
     30        border-radius: 30px;
     31        background: #777;
     32        font-size: 14px;
     33        font-weight: 600;
     34        color: #fff;
     35        position: relative;
     36        top: -1px;
     37}
     38
     39.wp-filter-links {
     40        margin: 0;
     41        display: inline-block;
     42}
     43.wp-filter-links li {
     44        margin: 0;
     45        display: inline-block;
     46}
     47.wp-filter-link {
     48        border-bottom: 4px solid #fff;
     49        color: #666;
     50        cursor: pointer;
     51        display: inline-block;
     52        margin: 0 10px;
     53        padding: 15px 0;
     54}
     55.wp-filter-links .current {
     56        border-bottom: 4px solid #666;
     57        color: #222;
     58}
     59
     60.wp-filter-search {
     61        position: absolute;
     62        right: 10px;
     63        top: 9px;
     64        left: auto;
     65        font-size: 16px;
     66        font-weight: 300;
     67        line-height: 1.5;
     68        width: 280px;
     69        padding: 3px 5px;
     70}
     71
     72.wp-filter-drawer-toggle {
     73        color: #666;
     74        cursor: pointer;
     75        display: inline-block;
     76        margin: 0 10px;
     77        padding: 4px 6px;
     78}
     79.wp-filter-drawer-toggle:before {
     80        margin: 0 2px 0 0;
     81        width: 16px;
     82        height: 16px;
     83        font-size: 16px;
     84        -webkit-transition: none;
     85        transition: none;
     86}
     87
     88.wp-filter-drawer {
     89        display: none;
     90        padding: 20px;
     91        border-top: 1px solid #eee;
     92        margin: 0 -20px;
     93        background: #fafafa;
     94}
     95
     96body.show-filter-drawer .wp-filter-drawer {
     97        display: block;
     98        overflow: hidden;
     99}
     100
     101body.show-filter-drawer .wp-filter-drawer-toggle {
     102        background: #777;
     103        -webkit-border-radius: 2px;
     104        border-radius: 2px;
     105        border: none;
     106        color: #fff;
     107}
     108
     109body.show-filter-drawer .wp-filter-drawer-toggle:hover,
     110body.show-filter-drawer .wp-filter-drawer-toggle:focus {
     111        background: rgb(46, 162, 204);
     112}
     113
     114body.show-filter-drawer .wp-filter-drawer-toggle:before {
     115        color: #fff;
     116}
     117
     118body.show-filter-drawer .wp-filter-link.current {
     119        border-bottom: none;
     120}
     121
     122.wp-filter-group {
     123        -webkit-box-sizing: border-box;
     124        -moz-box-sizing: border-box;
     125        box-sizing: border-box;
     126        float: left;
     127        width: 19%;
     128        background: #fff;
     129        margin: 0 1% 0 0;
     130        border: 1px solid #e5e5e5;
     131        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     132        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     133        padding: 10px;
     134}
     135.wp-filter-group-wide {
     136        width: 38%;
     137}
     138.wp-filter-group-title {
     139        margin: 0;
     140        position: relative;
     141}
     142
     143.wp-filter-drawer ol {
     144        list-style-type: none;
     145        margin: 20px 0 0;
     146        font-size: 12px;
     147}
     148.wp-filter-drawer li {
     149        display: inline-block;
     150        vertical-align: top;
     151        list-style-type: none;
     152        margin: 5px 0;
     153        padding-right: 25px;
     154        width: 160px;
     155}
     156
     157.wp-filter .button.wp-filter-drawer-apply {
     158        margin: 0 0 20px;
     159}
     160.wp-filter .button.wp-filter-drawer-apply span {
     161        display: inline-block;
     162        font-size: 12px;
     163        text-indent: 10px;
     164        opacity: 0.8;
     165}
     166.wp-filter .button.wp-filter-drawer-clear {
     167        display: none;
     168        margin: 0 0 20px 10px;
     169}
     170
     171.wp-filter-by {
     172        display: none;
     173        margin: 0;
     174}
     175.wp-filter-by > span {
     176        font-weight: 600;
     177}
     178.wp-filter-by a {
     179        margin-left: 10px;
     180}
     181.wp-filter-by .tags {
     182        display: inline;
     183}
     184.wp-filter-by .tag {
     185        background: #fff;
     186        border: 1px solid #e5e5e5;
     187        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     188        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     189        font-size: 11px;
     190        margin: 0 5px;
     191        padding: 4px 8px;
     192}
     193
     194body.filters-applied .wp-filter-group,
     195body.filters-applied .wp-filter-drawer a.button,
     196body.filters-applied .wp-filter-drawer br {
     197        display: none !important;
     198}
     199body.filters-applied .wp-filter-by {
     200        display: block;
     201}
     202body.filters-applied .wp-filter-drawer {
     203        padding: 20px;
     204}
     205
     206body.show-filter-drawer .wp-filter-content,
     207body.show-filter-drawer.filters-applied.loading-content .wp-filter-content {
     208        display: none;
     209}
     210body.show-filter-drawer.filters-applied .wp-filter-content {
     211        display: block;
     212}
     213
     214.loading-content .wp-filter-content,
     215.error .wp-filter-content {
     216        display: none;
     217}
     218.loading-content .spinner {
     219        display: block;
     220        margin: 40px auto 0;
     221        float: none;
     222}
     223
     224.wp-filter-notice {
     225        color: #999;
     226        font-size: 18px;
     227        font-style: normal;
     228        margin: 0;
     229        padding: 0;
     230        text-align: center;
     231        display: none;
     232}
     233body.no-results .wp-filter-notice {
     234        display: block;
     235}
     236
     237@media only screen and (max-width: 1120px) {
     238
     239        .wp-filter-search {
     240                margin: 20px 0;
     241                position: static;
     242                width: 100%;
     243        }
     244       
     245        .wp-filter-drawer {
     246                border-bottom: 1px solid #eee;
     247        }
     248        .wp-filter-group {
     249                margin-bottom: 0;
     250                margin-top: 5px;
     251                width: 100%;
     252        }
     253        .wp-filter-group li {
     254                margin: 10px 0;
     255        }
     256}
     257
     258@media only screen and (max-width: 782px) {
     259
     260        .wp-filter-group,
     261        .wp-filter-group li {
     262                width: 100%;
     263        }
     264
     265}
     266 No newline at end of file
  • trunk/src/wp-admin/css/forms.css

     
    751751        margin: -3px 3px;
    752752}
    753753
     754/*------------------------------------------------------------------------------
     755  21.0 - Upload File
     756------------------------------------------------------------------------------*/
     757
     758.wp-upload-container {
     759        -webkit-box-sizing: border-box;
     760        -moz-box-sizing: border-box;
     761        box-sizing: border-box;
     762        margin: 0px 0 0;
     763        padding: 0;
     764        width: 100%;
     765        overflow: hidden;
     766        position: relative;
     767        top: 10px;
     768}
     769.wp-upload-container-hidden {
     770        display: none;
     771}
     772.wp-upload-container .wp-upload-form {
     773        background: #fafafa;
     774        border: 1px solid #e5e5e5;
     775        padding: 30px;
     776        margin: 30px auto;
     777        max-width: 380px;
     778}
     779.wp-upload-container .install-help {
     780        color: #999;
     781        font-size: 18px;
     782        font-style: normal;
     783        margin: 0;
     784        padding: 40px 0 0;
     785        text-align: center;
     786}
     787
     788body.show-upload-container .hide-on-upload,
     789body.show-upload-container .wp-upload-show {
     790        display: none;
     791}
     792body.show-upload-container .wp-upload-container-hidden {
     793        display: block;
     794}
     795
     796.wp-upload-hide {
     797        display: none;
     798}
     799body.show-upload-container .wp-upload-hide {
     800        display: inline;
     801}
     802
    754803/* =Media Queries
    755804-------------------------------------------------------------- */
    756805
     806@media only screen and (max-width: 1120px) {
     807        .wp-upload-container .wp-upload-form {
     808                margin: 20px 0;
     809                max-width: 100%;
     810        }
     811        .wp-upload-container .install-help {
     812                font-size: 15px;
     813                padding: 20px 0 0;
     814                text-align: left;
     815        }
     816}
     817
    757818@media screen and ( max-width: 782px ) {
    758819        /* Input Elements */
    759820        textarea {
  • trunk/src/wp-admin/css/list-tables.css

     
    12161216}
    12171217
    12181218/* Plugin card table view */
     1219
     1220.plugin-browser .plugins {
     1221        clear: both;
     1222        padding: 0 0 100px;
     1223}
     1224
    12191225.plugin-card {
    12201226        float: left;
    12211227        margin: 0 8px 16px;
     
    12231229        width: -webkit-calc( 50% - 8px );
    12241230        width: calc( 50% - 8px );
    12251231        background-color: #fff;
    1226         border: 1px solid #dedede;
     1232        border: 1px solid #e5e5e5;
     1233        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     1234        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    12271235        -webkit-box-sizing: border-box;
    12281236        -moz-box-sizing: border-box;
    12291237        box-sizing: border-box;
    12301238}
    12311239
     1240.plugin-card .column-hidden {
     1241        display: none;
     1242}
     1243
     1244.plugin-card .column-visible {
     1245        display: block;
     1246}
     1247
     1248.plugin-card a {
     1249        text-decoration: none;
     1250}
     1251
    12321252@media screen and ( max-width: 782px ) {
    12331253        .plugin-card {
    12341254                margin-left: 0;
     
    12371257        }
    12381258}
    12391259
    1240 .plugin-card:nth-child(odd) {
     1260.plugins .plugin:nth-child(odd) .plugin-card {
    12411261        clear: both;
    12421262        margin-left: 0;
    12431263}
    12441264
    1245 .plugin-card:nth-child(even) {
     1265.plugins .plugin:nth-child(even) .plugin-card {
    12461266        margin-right: 0
    12471267}
    12481268
     
    12801300        clear: both;
    12811301        padding: 12px 20px;
    12821302        background-color: #fafafa;
    1283         border-top: 1px solid #dedede;
     1303        border-top: 1px solid #e5e5e5;
    12841304        overflow: hidden;
    12851305}
    12861306
    1287 .plugin-card-bottom .star-rating {
     1307.plugin-card-bottom .rating {
    12881308        display: inline;
     1309        margin-right: .35em;
    12891310}
     1311.plugin-card-bottom .rating span:before {
     1312        float: left;
     1313}
    12901314
    12911315.plugin-card .column-rating {
    12921316        line-height: 23px;
  • trunk/src/wp-admin/css/themes.css

     
    2525        margin-left: 20px;
    2626}
    2727
    28 .themes-php .wrap .theme-count,
    29 .theme-navigation .theme-count {
    30         color: #fff;
    31         -webkit-border-radius: 30px;
    32         border-radius: 30px;
    33         background: #777;
    34         font-size: 14px;
    35         padding: 4px 10px;
    36         font-weight: 600;
    37         margin-left: 5px;
    38         margin-right: 20px;
    39         position: relative;
    40         top: -3px;
    41 }
    42 
    43 .theme-navigation a {
    44         text-decoration:none;
    45 }
    46 
    4728/* Position admin messages */
    4829.themes-php div.updated,
    4930.themes-php div.error {
     
    5132        clear: both;
    5233}
    5334
     35/*
     36 * The search form
     37 */
     38.themes-php .wp-filter-search {
     39        position: relative;
     40        top: -2px;
     41        left: 20px;
     42        font-size: 16px;
     43        font-weight: 300;
     44        line-height: 1.5;
     45        width: 280px;
     46        margin: 0;
     47}
     48
    5449.themes-php div.updated a {
    5550        text-decoration: underline;
    5651}
     
    401396        z-index: 2;
    402397}
    403398
    404 /*
    405  * The search form
    406  */
    407 .themes-php .theme-search {
    408         position: relative;
    409         top: -2px;
    410         left: 20px;
    411         font-size: 16px;
    412         font-weight: 300;
    413         line-height: 1.5;
    414         width: 280px;
    415 }
    416 
    417399/**
    418400 * Theme Overlay
    419401 * Shown when clicking a theme
     
    10241006        .themes-php .wrap h2 {
    10251007                width: 100%;
    10261008        }
    1027 
    1028         .themes-php .theme-search {
     1009       
     1010        .themes-php .wp-filter-search {
    10291011                float: none;
    10301012                clear: both;
    10311013                left: 0;
     
    10881070        display: none !important;
    10891071}
    10901072
    1091 .theme-navigation {
    1092         background: #fff;
    1093         -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
    1094         box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
    1095         -webkit-box-sizing: border-box;
    1096         -moz-box-sizing: border-box;
    1097         box-sizing: border-box;
    1098         color: #555;
    1099         display: inline-block;
    1100         font-size: 13px;
    1101         margin: 20px 0 30px;
    1102         padding: 0 20px;
    1103         position: relative;
    1104         width: 100%;
    1105 }
    1106 .theme-install-php a.upload,
    1107 .theme-install-php a.browse-themes {
    1108         cursor: pointer;
    1109 }
    1110 .theme-install-php a.browse-themes,
    1111 .theme-install-php.show-upload-theme a.upload {
    1112         display: none;
    1113 }
    1114 .theme-install-php.show-upload-theme a.browse-themes {
    1115         display: inline;
    1116 }
    1117 .upload-theme {
    1118         -webkit-box-sizing: border-box;
    1119         -moz-box-sizing: border-box;
    1120         box-sizing: border-box;
    1121         display: none;
    1122         margin: 0px 0 0;
    1123         padding: 0;
    1124         width: 100%;
    1125         overflow: hidden;
    1126         position: relative;
    1127         top: 10px;
    1128 }
    1129 body.show-upload-theme .upload-theme {
    1130         display: block;
    1131 }
    1132 .upload-theme .wp-upload-form {
    1133         background: #fafafa;
    1134         border: 1px solid #e5e5e5;
    1135         padding: 30px;
    1136         margin: 30px auto;
    1137         max-width: 380px;
    1138 }
    1139 .upload-theme .install-help {
    1140         color: #999;
    1141         font-size: 18px;
    1142         font-style: normal;
    1143         margin: 0;
    1144         padding: 40px 0 0;
    1145         text-align: center;
    1146 }
    1147 body.show-upload-theme .upload-theme + .theme-navigation,
    1148 body.show-upload-theme .upload-theme + .theme-navigation + .theme-browser {
    1149         display: none;
    1150 }
    1151 .theme-navigation .theme-count {
    1152         margin-left: 0;
    1153         position: absolute;
    1154         top: 12px;
    1155 }
    1156 .theme-count + .theme-section {
    1157         margin-left: 60px;
    1158 }
    1159 .theme-section,
    1160 .theme-filter {
    1161         border-bottom: 4px solid #fff;
    1162         color: #666;
    1163         cursor: pointer;
    1164         display: inline-block;
    1165         margin: 0 10px;
    1166         padding: 15px 0;
    1167 }
    1168 .theme-section.current,
    1169 .theme-filter.current {
    1170         border-bottom: 4px solid #666;
    1171         color: #222;
    1172 }
    1173 .theme-top-filters {
    1174         display: inline-block;
    1175 }
    1176 .theme-navigation .more-filters {
    1177         color: #666;
    1178         cursor: pointer;
    1179         display: inline-block;
    1180         margin: 0 10px;
    1181         padding: 4px 6px;
    1182 }
    1183 body.more-filters-opened .more-filters {
    1184         background: #777;
    1185         -webkit-border-radius: 2px;
    1186         border-radius: 2px;
    1187         border: none;
    1188         color: #fff;
    1189 }
    1190 
    1191 body.more-filters-opened .more-filters:before {
    1192         color: #fff;
    1193 }
    1194 
    1195 body.more-filters-opened .more-filters:hover,
    1196 body.more-filters-opened .more-filters:focus {
    1197         background: rgb(46, 162, 204);
    1198 }
    1199 
    1200 .theme-install-php .theme-search {
    1201         position: absolute;
    1202         right: 10px;
    1203         top: 9px;
    1204         font-size: 16px;
    1205         font-weight: 300;
    1206         line-height: 1.5;
    1207         width: 280px;
    1208 }
    1209 .more-filters:before {
    1210         color: #777;
    1211         text-align: center;
    1212         margin: 0 5px 0 0;
    1213         content: "\f111";
    1214         display: inline-block;
    1215         width: 16px;
    1216         height: 16px;
    1217         -webkit-font-smoothing: antialiased;
    1218         font-size: 16px;
    1219         line-height: 1;
    1220         font-family: "dashicons";
    1221         text-decoration: inherit;
    1222         font-weight: normal;
    1223         font-style: normal;
    1224         vertical-align: top;
    1225         -webkit-transition: color .1s ease-in 0;
    1226         transition: color .1s ease-in 0;
    1227         text-align: center;
    1228 }
    1229 .more-filters.current:before {
    1230         color: #fff;
    1231 }
    1232 .more-filters-container {
    1233         display: none;
    1234         padding: 20px;
    1235         border-top: 1px solid #eee;
    1236         margin: 0 -20px;
    1237         background: #fafafa;
    1238 }
    1239 body.more-filters-opened .more-filters-container {
    1240         display: block;
    1241         overflow: hidden;
    1242 }
    1243 body.more-filters-opened .theme-section.current {
    1244         border-bottom: none;
    1245 }
    1246 body.more-filters-opened .theme-browser,
    1247 body.more-filters-opened.filters-applied.loading-themes .theme-browser {
    1248         display: none;
    1249 }
    1250 body.more-filters-opened.filters-applied .theme-browser {
    1251         display: block;
    1252 }
    1253 .more-filters-container .filters-group {
    1254         -webkit-box-sizing: border-box;
    1255         -moz-box-sizing: border-box;
    1256         box-sizing: border-box;
    1257         float: left;
    1258         width: 19%;
    1259         background: #fff;
    1260         margin: 0 1% 0 0;
    1261         border: 1px solid #e5e5e5;
    1262         -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1263         box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1264         padding: 10px;
    1265 }
    1266 .more-filters-container .wide-filters-group {
    1267         width: 38%;
    1268 }
    1269 .more-filters-container .feature-name {
    1270         margin: 0;
    1271         position: relative;
    1272 }
    1273 .more-filters-container ol {
    1274         list-style-type: none;
    1275         margin: 20px 0 0;
    1276         font-size: 12px;
    1277 }
    1278 .more-filters-container li {
    1279         display: inline-block;
    1280         vertical-align: top;
    1281         list-style-type: none;
    1282         margin: 5px 0;
    1283         padding-right: 25px;
    1284         width: 160px;
    1285 }
    1286 .theme-navigation .more-filters-container .apply-filters {
    1287         margin: 0 0 20px;
    1288 }
    1289 .theme-navigation .more-filters-container .clear-filters {
    1290         display: none;
    1291         margin: 0 0 20px 10px;
    1292 }
    1293 .more-filters-container .apply-filters span {
    1294         display: inline-block;
    1295         font-size: 12px;
    1296         text-indent: 10px;
    1297         opacity: 0.8;
    1298 }
    1299 .more-filters-container .filtering-by {
    1300         display: none;
    1301         margin: 0;
    1302 }
    1303 .more-filters-container .filtering-by > span {
    1304         font-weight: 600;
    1305 }
    1306 .more-filters-container .filtering-by .tags {
    1307         display: inline;
    1308 }
    1309 .more-filters-container .filtering-by .tag {
    1310         background: #fff;
    1311         border: 1px solid #e5e5e5;
    1312         -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1313         box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1314         font-size: 11px;
    1315         margin: 0 5px;
    1316         padding: 4px 8px;
    1317 }
    1318 .more-filters-container .filtering-by a {
    1319         margin-left: 10px;
    1320 }
    1321 body.filters-applied .more-filters-container .filters-group,
    1322 body.filters-applied .more-filters-container a.button,
    1323 body.filters-applied .more-filters-container br {
    1324         display: none !important;
    1325 }
    1326 body.filters-applied .more-filters-container .filtering-by {
    1327         display: block;
    1328 }
    1329 body.filters-applied .more-filters-container {
    1330         padding: 20px;
    1331 }
    1332 p.no-themes {
    1333         color: #999;
    1334         font-size: 18px;
    1335         font-style: normal;
    1336         margin: 0;
    1337         padding: 0;
    1338         text-align: center;
    1339         display: none;
    1340 }
    1341 body.no-results p.no-themes {
    1342         display: block;
    1343 }
    1344 body.show-upload-theme p.no-themes {
    1345         display: none !important;
    1346 }
    1347 
    1348 
    1349 .theme-install-php .add-new-theme {
    1350         display: none !important;
    1351 }
    1352 
    1353 @media only screen and (max-width: 1120px) {
    1354         .theme-install-php .theme-search {
    1355                 margin: 20px 0;
    1356                 position: static;
    1357                 width: 100%;
    1358         }
    1359         .more-filters-container {
    1360                 border-bottom: 1px solid #eee;
    1361         }
    1362         .upload-theme .wp-upload-form {
    1363                 margin: 20px 0;
    1364                 max-width: 100%;
    1365         }
    1366         .upload-theme .install-help {
    1367                 font-size: 15px;
    1368                 padding: 20px 0 0;
    1369                 text-align: left;
    1370         }
    1371         .more-filters-container .filters-group {
    1372                 margin-bottom: 0;
    1373                 margin-top: 5px;
    1374                 width: 100%;
    1375         }
    1376         .more-filters-container .filters-group li {
    1377                 margin: 10px 0;
    1378         }
    1379 }
    1380 
    1381 @media only screen and (max-width: 782px) {
    1382         .more-filters-container .filters-group {
    1383                 width: 100%;
    1384         }
    1385         .more-filters-container .filters-group li {
    1386                 width: 100%;
    1387         }
    1388 }
    1389 
    1390 .rating {
    1391         margin: 30px 0;
    1392 }
    1393 .rating span:before {
    1394         color: #e6b800;
    1395         content: "\f154";
    1396         display: inline-block;
    1397         -webkit-font-smoothing: antialiased;
    1398         font: normal 20px/1 'dashicons';
    1399         vertical-align: top;
    1400 }
    1401 /* Half stars */
    1402 .rating-10 span.one:before,
    1403 .rating-30 span.two:before,
    1404 .rating-50 span.three:before,
    1405 .rating-70 span.four:before,
    1406 .rating-90 span.five:before {
    1407         content: "\f459";
    1408 }
    1409 /* Full stars */
    1410 .rating-20 span.one:before {
    1411         content: "\f155";
    1412 }
    1413 .rating-30 span.one:before,
    1414 .rating-40 span.one:before,
    1415 .rating-40 span.two:before {
    1416         content: "\f155";
    1417 }
    1418 .rating-50 span.one:before,
    1419 .rating-50 span.two:before,
    1420 .rating-60 span.one:before,
    1421 .rating-60 span.two:before,
    1422 .rating-60 span.three:before {
    1423         content: "\f155";
    1424 }
    1425 .rating-70 span.one:before,
    1426 .rating-70 span.two:before,
    1427 .rating-70 span.three:before,
    1428 .rating-80 span.one:before,
    1429 .rating-80 span.two:before,
    1430 .rating-80 span.three:before,
    1431 .rating-80 span.four:before {
    1432         content: "\f155";
    1433 }
    1434 .rating-90 span.one:before,
    1435 .rating-90 span.two:before,
    1436 .rating-90 span.three:before,
    1437 .rating-90 span.four:before,
    1438 .rating-100 span.one:before,
    1439 .rating-100 span.two:before,
    1440 .rating-100 span.three:before,
    1441 .rating-100 span.four:before,
    1442 .rating-100 span.five:before {
    1443         content: "\f155";
    1444 }
    1445 .rating .ratings {
    1446         display: inline;
    1447         margin-left: 10px;
    1448         line-height: 20px;
    1449         color: #999;
    1450 }
    1451 .loading-themes .theme-browser,
    1452 .error .theme-browser {
    1453         display: none;
    1454 }
    1455 .loading-themes .spinner {
    1456         display: block;
    1457         margin: 40px auto 0;
    1458         float: none;
    1459 }
    1460 
    14611073/*------------------------------------------------------------------------------
    14621074  16.3 - Custom Header Screen
    14631075------------------------------------------------------------------------------*/
     
    16181230        overflow: auto;
    16191231}
    16201232
     1233.wp-full-overlay-sidebar .rating {
     1234        display: block;
     1235        margin: 30px 0;
     1236}
     1237.wp-full-overlay-sidebar .rating span:before {
     1238        color: #e6b800;
     1239}
     1240
    16211241/* Close & Navigation Links */
    16221242.theme-install-overlay .wp-full-overlay-sidebar .wp-full-overlay-header {
    16231243        padding: 0;
  • trunk/src/wp-admin/css/wp-admin.css

     
    1212@import url(nav-menus.css);
    1313@import url(widgets.css);
    1414@import url(l10n.css);
     15@import url(filter.css);
  • trunk/src/wp-admin/includes/ajax-actions.php

     
    26052605}
    26062606
    26072607/**
     2608 * Ajax handler for getting plugins from plugins_api().
     2609 *
     2610 * @since 4.0.0
     2611 */
     2612function wp_ajax_query_plugins() {
     2613        global $plugins_allowedtags, $plugins_field_defaults;
     2614       
     2615        if ( ! current_user_can( 'install_plugins' ) ) {
     2616                wp_send_json_error();
     2617        }
     2618        $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array(
     2619                'per_page' => 20,
     2620                'fields'   => $plugins_field_defaults
     2621        ) );
     2622
     2623        $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
     2624
     2625        /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
     2626        $args = apply_filters( 'install_plugins_table_api_args_' . $old_filter, $args );
     2627
     2628        require( ABSPATH . 'wp-admin/includes/plugin-install.php' ); // Needed for plugins_api
     2629       
     2630        $api = plugins_api( 'query_plugins', $args );
     2631
     2632        if ( is_wp_error( $api ) ) {
     2633                wp_send_json_error();
     2634        }
     2635
     2636        foreach ( $api->plugins as &$plugin ) {
     2637               
     2638                if ( version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin->tested ) ), $plugin->tested, '>' ) ) {
     2639                        $plugin->compatibility = 'untested';
     2640                } else if ( version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin->requires ) ), $plugin->requires, '<' ) ) {
     2641                        $plugin->compatibility = 'incompatible';
     2642                } else {
     2643                        $plugin->compatibility = 'compatible';
     2644                }
     2645               
     2646                $details_link   = self_admin_url( 'plugin-install.php?tab=plugin-information&amp;plugin=' . $plugin->slug .
     2647                                                                '&amp;TB_iframe=true&amp;width=830&amp;height=654' );
     2648                                                               
     2649                /**
     2650                 * Filter the details link for a plugin.
     2651                 *
     2652                 * @since 4.0.0
     2653                 *
     2654                 * @param string $details_link Link to view the current plugin's details.
     2655                 * @param array  $plugin       The plugin currently being listed.
     2656                 */
     2657                $plugin->detail_url = apply_filters( 'plugin_install_details_link', $details_link, (array) $plugin );
     2658               
     2659                $action_links = array();
     2660               
     2661                $name = strip_tags( $plugin->name . ' ' . $plugin->version );
     2662               
     2663                $status = install_plugin_install_status( $plugin );
     2664               
     2665                switch ( $status['status'] ) {
     2666                        case 'install':
     2667                                if ( $status['url'] ) {
     2668                                        $action_links[]  = '<a class="install-now button" href="' . $status['url'] . '" title="' . esc_attr( sprintf( __( 'Install %s' ), $name ) ) . '">' . __( 'Install Now' ) . '</a>';
     2669                                }
     2670
     2671                                break;
     2672                        case 'update_available':
     2673                                if ( $status['url'] ) {
     2674                                        $action_links[] = '<a class="button" href="' . $status['url'] . '" title="' . esc_attr( sprintf( __( 'Update to version %s' ), $status['version'] ) ) . '">' . __( 'Update Now' ) . '</a>';
     2675                                }
     2676
     2677                                break;
     2678                        case 'latest_installed':
     2679                        case 'newer_installed':
     2680                                $action_links[] = '<span class="button button-disabled" title="' . esc_attr__( 'This plugin is already installed and is up to date' ) . ' ">' . _x( 'Installed', 'plugin' ) . '</span>';
     2681                                break;
     2682                }
     2683               
     2684                $action_links[] = '<a href="' . esc_attr( $details_link ) . '" class="thickbox" title="' .
     2685                                                                esc_attr( sprintf( __( 'More information about %s' ), $plugin->name ) ) . '">' . __( 'More Details' ) . '</a>';
     2686
     2687                /**
     2688                 * Filter the install action links for a plugin.
     2689                 *
     2690                 * @since 2.7.0
     2691                 *
     2692                 * @param array $action_links An array of plugin action hyperlinks. Defaults are links to Details and Install Now.
     2693                 * @param array $plugin       The plugin currently being listed.
     2694                 */
     2695                $plugin->action_links = apply_filters( 'plugin_install_action_links', $action_links, (array) $plugin );
     2696               
     2697                $plugin->name                                   = wp_kses( strip_tags( $plugin->name ), $plugins_allowedtags );
     2698                $plugin->author                                 = wp_kses( $plugin->author, $plugins_allowedtags );
     2699                $plugin->slug                                   = wp_kses( $plugin->slug, $plugins_allowedtags );
     2700                $plugin->version                                = wp_kses( $plugin->version, $plugins_allowedtags );
     2701                $plugin->description                    = strip_tags( $plugin->description );
     2702                $plugin->short_description              = strip_tags( $plugin->short_description );
     2703                $plugin->rating                                 = wp_kses( $plugin->rating, $plugins_allowedtags );
     2704                $plugin->ratings                                = wp_kses( $plugin->ratings, $plugins_allowedtags );
     2705                $plugin->num_ratings                    = $plugin->num_ratings;
     2706                $plugin->num_ratings_formatted  = number_format_i18n( $plugin->num_ratings );
     2707                $plugin->downloaded                             = number_format_i18n( $plugin->downloaded );
     2708                $plugin->last_updated                   = sprintf( __( '%s ago' ), human_time_diff( strtotime( $plugin->last_updated ) ) );
     2709        }
     2710
     2711        wp_send_json_success( $api );
     2712}
     2713
     2714/**
    26082715 * Apply [embed] handlers to a string.
    26092716 *
    26102717 * @since 4.0.0
  • trunk/src/wp-admin/includes/class-wp-plugin-install-list-table.php

     
    2727                // These are the tabs which are shown on the page
    2828                $tabs = array();
    2929                $tabs['dashboard'] = __( 'Search' );
    30                 if ( 'search' == $tab )
     30                if ( 'search' == $tab ) {
    3131                        $tabs['search'] = __( 'Search Results' );
    32                 $tabs['upload']    = __( 'Upload' );
     32                }
    3333                $tabs['featured']  = _x( 'Featured', 'Plugin Installer' );
    3434                $tabs['popular']   = _x( 'Popular', 'Plugin Installer' );
    3535                $tabs['new']       = _x( 'Newest', 'Plugin Installer' );
     
    4040
    4141                $nonmenu_tabs = array( 'plugin-information' ); //Valid actions to perform which do not have a Menu item.
    4242
    43                 /**
    44                  * Filter the tabs shown on the Plugin Install screen.
    45                  *
    46                  * @since 2.7.0
    47                  *
    48                  * @param array $tabs The tabs shown on the Plugin Install screen. Defaults are 'dashboard', 'search',
    49                  *                    'upload', 'featured', 'popular', 'new', and 'favorites'.
    50                  */
     43                /** This filter is documented in wp-admin/plugin-install.php */
    5144                $tabs = apply_filters( 'install_plugins_tabs', $tabs );
    5245
    5346                /**
     
    112105                 * Filter API request arguments for each Plugin Install screen tab.
    113106                 *
    114107                 * The dynamic portion of the hook name, $tab, refers to the plugin install tabs.
    115                  * Default tabs are 'dashboard', 'search', 'upload', 'featured', 'popular', 'new',
     108                 * Default tabs are 'dashboard', 'search', 'featured', 'popular', 'new',
    116109                 * and 'favorites'.
    117110                 *
    118111                 * @since 3.7.0
  • trunk/src/wp-admin/includes/plugin-install.php

     
    126126
    127127function install_dashboard() {
    128128        ?>
    129         <p><?php printf( __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%1$s">WordPress Plugin Directory</a> or upload a plugin in .zip format via <a href="%2$s">this page</a>.' ), 'https://wordpress.org/plugins/', self_admin_url( 'plugin-install.php?tab=upload' ) ); ?></p>
     129        <p><?php printf( __( 'Plugins extend and expand the functionality of WordPress. You may automatically install plugins from the <a href="%1$s">WordPress Plugin Directory</a> or <a href="%2$s" class="wp-upload-show">upload a plugin</a> in .zip format.' ), 'https://wordpress.org/plugins/', self_admin_url( 'plugin-install.php?upload' ) ); ?></p>
    130130
    131131        <h4><?php _e('Search') ?></h4>
    132132        <?php install_search_form( false ); ?>
     
    187187 */
    188188function install_plugins_upload( $page = 1 ) {
    189189?>
    190         <h4><?php _e('Install a plugin in .zip format'); ?></h4>
    191         <p class="install-help"><?php _e('If you have a plugin in a .zip format, you may install it by uploading it here.'); ?></p>
    192         <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url('update.php?action=upload-plugin'); ?>">
    193                 <?php wp_nonce_field( 'plugin-upload'); ?>
    194                 <label class="screen-reader-text" for="pluginzip"><?php _e('Plugin zip file'); ?></label>
    195                 <input type="file" id="pluginzip" name="pluginzip" />
    196                 <?php submit_button( __( 'Install Now' ), 'button', 'install-plugin-submit', false ); ?>
    197         </form>
     190        <div class="wp-upload-container wp-upload-container-hidden">
     191                <p class="install-help"><?php _e( 'If you have a plugin in a .zip format, you may install it by uploading it here.' ); ?></p>
     192                <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-plugin' ); ?>">
     193                        <?php wp_nonce_field( 'plugin-upload' ); ?>
     194                        <label class="screen-reader-text" for="pluginzip"><?php _e( 'Plugin zip file' ); ?></label>
     195                        <input type="file" id="pluginzip" name="pluginzip" />
     196                        <?php submit_button( __( 'Install Now' ), 'button', 'install-plugin-submit', false ); ?>
     197                </form>
     198        </div>
    198199<?php
    199200}
    200201add_action('install_plugins_upload', 'install_plugins_upload', 10, 1);
  • trunk/src/wp-admin/includes/theme-install.php

     
    136136
    137137function install_themes_upload() {
    138138?>
    139 <p class="install-help"><?php _e('If you have a theme in a .zip format, you may install it by uploading it here.'); ?></p>
    140 <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url('update.php?action=upload-theme'); ?>">
    141         <?php wp_nonce_field( 'theme-upload'); ?>
    142         <input type="file" name="themezip" />
    143         <?php submit_button( __( 'Install Now' ), 'button', 'install-theme-submit', false ); ?>
    144 </form>
    145         <?php
     139        <div class="wp-upload-container wp-upload-container-hidden">
     140                <p class="install-help"><?php _e( 'If you have a theme in a .zip format, you may install it by uploading it here.' ); ?></p>
     141                <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo self_admin_url( 'update.php?action=upload-theme' ); ?>">
     142                        <?php wp_nonce_field( 'theme-upload' ); ?>
     143                        <input type="file" name="themezip" />
     144                        <?php submit_button( __( 'Install Now' ), 'button', 'install-theme-submit', false ); ?>
     145                </form>
     146        </div>
     147<?php
    146148}
    147149// add_action('install_themes_upload', 'install_themes_upload', 10, 0);
    148150
  • trunk/src/wp-admin/js/plugin-install.js

     
    1 /* global plugininstallL10n, tb_click, confirm */
    2 
    3 /* Plugin Browser Thickbox related JS*/
    4 var tb_position;
    5 jQuery( document ).ready( function( $ ) {
    6         tb_position = function() {
    7                 var tbWindow = $( '#TB_window' ),
    8                         width = $( window ).width(),
    9                         H = $( window ).height() - ( ( 850 < width ) ? 60 : 20 ),
    10                         W = ( 850 < width ) ? 830 : width - 20;
    11 
    12                 if ( tbWindow.size() ) {
    13                         tbWindow.width( W ).height( H );
    14                         $( '#TB_iframeContent' ).width( W ).height( H );
    15                         tbWindow.css({
    16                                 'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px'
    17                         });
    18                         if ( typeof document.body.style.maxWidth !== 'undefined' ) {
    19                                 tbWindow.css({
    20                                         'top': ( ( 850 < width ) ? 30 : 10 ) + 'px',
    21                                         'margin-top': '0'
    22                                 });
    23                         }
    24                 }
    25 
    26                 return $( 'a.thickbox' ).each( function() {
    27                         var href = $( this ).attr( 'href' );
    28                         if ( ! href ) {
    29                                 return;
    30                         }
    31                         href = href.replace( /&width=[0-9]+/g, '' );
    32                         href = href.replace( /&height=[0-9]+/g, '' );
    33                         $(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) );
    34                 });
    35         };
    36 
    37         $( window ).resize( function() {
    38                 tb_position();
    39         });
    40 
    41         $('.plugins').on( 'click', 'a.thickbox', function() {
    42                 tb_click.call(this);
    43 
    44                 $('#TB_title').css({'background-color':'#222','color':'#cfcfcf'});
    45                 $('#TB_ajaxWindowTitle').html('<strong>' + plugininstallL10n.plugin_information + '</strong>&nbsp;' + $(this).attr('title') );
    46                 return false;
    47         });
    48 
    49         /* Plugin install related JS*/
    50         $( '#plugin-information-tabs a' ).click( function( event ) {
    51                 var tab = $( this ).attr( 'name' );
    52                 event.preventDefault();
    53                 //Flip the tab
    54                 $( '#plugin-information-tabs a.current' ).removeClass( 'current' );
    55                 $( this ).addClass( 'current' );
    56                 //Only show the fyi box in the description section, on smaller screen, where it's otherwise always displayed at the top.
    57                 if ( 'description' != $( this ).attr( 'name' ) && $( 'body').width() < 830 )
    58                         $( '#plugin-information-content div.fyi' ).hide();
    59                 else
    60                         $( '#plugin-information-content div.fyi' ).show();
    61                 //Flip the content.
    62                 $( '#section-holder div.section' ).hide(); //Hide 'em all
    63                 $( '#section-' + tab ).show();
    64         });
    65 
    66         $( 'a.install-now' ).click( function() {
    67                 return confirm( plugininstallL10n.ays );
    68         });
    69 });
  • trunk/src/wp-admin/js/plugin.js

     
     1/* global _wpPluginSettings */
     2window.wp = window.wp || {};
     3
     4(function($) {
     5
     6// Set up our namespace...
     7var plugins, l10n;
     8plugins = wp.plugins = wp.plugins || {};
     9
     10// Store the plugin data and settings for organized and quick access
     11plugins.data = _wpPluginSettings;
     12l10n = plugins.data.l10n;
     13
     14// Setup app structure
     15_.extend( plugins, {  view: {}, routes: {}, router: {}, template: wp.template });
     16
     17// Set up the Collection for our plugin data
     18// @has 'id' 'name' 'screenshot' 'author' 'authorURI' 'version' 'active' ...
     19plugins.Collection = Backbone.Collection.extend({
     20
     21        // Paginates the collection with a helper method
     22        // that slices the collection
     23        paginate: function( instance ) {
     24                var collection = this;
     25                instance = instance || 0;
     26               
     27                // Plugins per instance are set at 20
     28                collection = _( collection.rest( 20 * instance ) );
     29                collection = _( collection.first( 20 ) );
     30
     31                return collection;
     32        },
     33
     34        count: false,
     35
     36        // Handles requests for more plugins
     37        // and caches results
     38        //
     39        // When we are missing a cache object we fire an apiCall()
     40        // which triggers events of `query:success` or `query:fail`
     41        query: function( request ) {
     42                /**
     43                 * @static
     44                 * @type Array
     45                 */
     46                var queries = this.queries,
     47                        self = this,
     48                        query, isPaginated, count;
     49
     50                // Store current query request args
     51                // for later use with the event `plugin:end`
     52                this.currentQuery.request = request;
     53
     54                // Search the query cache for matches.
     55                query = _.find( queries, function( query ) {
     56                        return _.isEqual( query.request, request );
     57                });
     58
     59                // If the request matches the stored currentQuery.request
     60                // it means we have a paginated request.
     61                isPaginated = _.has( request, 'page' );
     62
     63                // Reset the internal api page counter for non paginated queries.
     64                if ( ! isPaginated ) {
     65                        this.currentQuery.page = 1;
     66                }
     67               
     68                // Otherwise, send a new API call and add it to the cache.
     69                if ( ! query && ! isPaginated ) {
     70                        query = this.apiCall( request ).done( function( data ) {
     71
     72                                // Update the collection with the queried data.
     73                                if ( data.plugins ) {
     74                                        self.reset( data.plugins );
     75                                        count = data.info.results;
     76                                       
     77                                        // Store the results and the query request
     78                                        queries.push( { plugins: data.plugins, request: request, total: count } );
     79                                }
     80
     81                                // Trigger a collection refresh event
     82                                // and a `query:success` event with a `count` argument.
     83                                self.trigger( 'update' );
     84                                self.trigger( 'query:success', count );
     85
     86                                if ( data.plugins && data.plugins.length === 0 ) {
     87                                        self.trigger( 'query:empty' );
     88                                }
     89
     90                        }).fail( function() {
     91                                self.trigger( 'query:fail' );
     92                        });
     93                } else {
     94                        // If it's a paginated request we need to fetch more plugins...
     95                        if ( isPaginated ) {
     96                                return this.apiCall( request, isPaginated ).done( function( data ) {
     97                                        // Add the new plugins to the current collection
     98                                        // @todo update counter
     99                                        self.add( data.plugins );
     100                                        self.trigger( 'query:success' );
     101
     102                                        // We are done loading plugins for now.
     103                                        self.loadingPlugins = false;
     104
     105                                }).fail( function() {
     106                                        self.trigger( 'query:fail' );
     107                                });
     108                        }
     109
     110                        if ( query.plugins.length === 0 ) {
     111                                self.trigger( 'query:empty' );
     112                        } else {
     113                                $( 'body' ).removeClass( 'no-results' );
     114                        }
     115
     116                        // Only trigger an update event since we already have the plugins
     117                        // on our cached object
     118                        if ( _.isNumber( query.total ) ) {
     119                                this.count = query.total;
     120                        }
     121
     122                        this.reset( query.plugins );
     123                        if ( ! query.total ) {
     124                                this.count = this.length;
     125                        }
     126
     127                        this.trigger( 'update' );
     128                        this.trigger( 'query:success', this.count );
     129                }
     130        },
     131
     132        // Local cache array for API queries
     133        queries: [],
     134
     135        // Keep track of current query so we can handle pagination
     136        currentQuery: {
     137                page: 1,
     138                request: {}
     139        },
     140
     141        // Send request to api.wordpress.org/plugins
     142        apiCall: function( request, paginated ) {
     143                return wp.ajax.send( 'query-plugins', {
     144                        data: {
     145                        // Request data
     146                                request: _.extend({
     147                                        per_page: 20,
     148                                        fields: {
     149                                                last_updated: true,
     150                                                downloaded: true,
     151                                        },
     152                                }, request)
     153                        },
     154
     155                        beforeSend: function() {
     156                                if ( ! paginated ) {
     157                                        // Spin it
     158                                        $( 'body' ).addClass( 'loading-content' ).removeClass( 'no-results' );
     159                                }
     160                        }
     161                });
     162        },
     163
     164        // Static status controller for when we are loading plugins.
     165        loadingPlugins: false
     166});
     167
     168// This is the view that controls each plugin item
     169// that will be displayed on the screen
     170plugins.view.Plugin = wp.Backbone.View.extend({
     171
     172        // Wrap plugin data on a div.plugin element
     173        className: 'plugin',
     174
     175        // The HTML template for each element to be rendered
     176        html: plugins.template( 'plugin' ),
     177
     178        render: function() {
     179                var data = this.model.toJSON();
     180                // Render plugins using the html template
     181                this.$el.html( this.html( data ) ).attr({
     182                        tabindex: 0
     183                });
     184        }
     185});
     186
     187plugins.view.InstallerSearch =  wp.Backbone.View.extend({
     188
     189        tagName: 'input',
     190        className: 'wp-filter-search',
     191        id: 'wp-filter-search-input',
     192        searching: false,
     193
     194        attributes: {
     195                placeholder: l10n.searchPlaceholder,
     196                type: 'search'
     197        },
     198       
     199        events: {
     200                'input':  'search',
     201                'keyup':  'search',
     202                'change': 'search',
     203                'search': 'search',
     204                'blur':   'pushState'
     205        },
     206
     207        // Handles Ajax request for searching through plugins in public repo
     208        search: function( event ) {
     209                var options = {};
     210
     211                // Tabbing or reverse tabbing into the search input shouldn't trigger a search
     212                if ( event.type === 'keyup' && ( event.which === 9 || event.which === 16 ) ) {
     213                        return;
     214                }
     215
     216                this.collection = this.options.parent.view.collection;
     217               
     218                // Clear on escape.
     219                if ( event.type === 'keyup' && event.which === 27 ) {
     220                        event.target.value = '';
     221                }
     222               
     223                // Update the URL hash
     224                if ( event.target.value ) {
     225                        plugins.router.navigate( plugins.router.baseUrl( '?search=' + event.target.value ), options );
     226                } else {
     227                        plugins.router.navigate( plugins.router.baseUrl( '' ) );
     228                }
     229
     230                _.debounce( _.bind( this.doSearch, this ), 300 )( event.target.value );
     231        },
     232
     233        doSearch: _.debounce( function( value ) {
     234                var request = {};
     235
     236                request.search = value;
     237
     238                // Intercept an [author] search.
     239                //
     240                // If input value starts with `author:` send a request
     241                // for `author` instead of a regular `search`
     242                if ( value.substring( 0, 7 ) === 'author:' ) {
     243                        request.search = '';
     244                        request.author = value.slice( 7 );
     245                }
     246
     247                // Intercept a [tag] search.
     248                //
     249                // If input value starts with `tag:` send a request
     250                // for `tag` instead of a regular `search`
     251                if ( value.substring( 0, 4 ) === 'tag:' ) {
     252                        request.search = '';
     253                        request.tag = [ value.slice( 4 ) ];
     254                }
     255
     256                $( '.wp-filter-link.current' ).removeClass( 'current' );
     257                $( 'body' ).removeClass( 'show-filter-drawer filters-applied' );
     258
     259                // Get the plugins by sending Ajax POST request to api.wordpress.org/plugins
     260                // or searching the local cache
     261                this.collection.query( request );
     262
     263                // Set route
     264                plugins.router.navigate( plugins.router.baseUrl( '?search=' + value ), { replace: true } );
     265        }, 300 ),
     266
     267        pushState: function( event ) {
     268                var url = plugins.router.baseUrl( '' );
     269
     270                if ( event.target.value ) {
     271                        url = plugins.router.baseUrl( '?search=' + event.target.value );
     272                }
     273
     274                this.searching = false;
     275                plugins.router.navigate( url );
     276        }
     277});
     278
     279plugins.view.Appearance = wp.Backbone.View.extend({
     280
     281        el: '#wpbody-content .wrap .plugin-browser',
     282       
     283        window: $( window ),
     284        // Pagination instance
     285        page: 0,
     286
     287        // Sets up a throttler for binding to 'scroll'
     288        initialize: function( options ) {
     289                // Scroller checks how far the scroll position is
     290                _.bindAll( this, 'scroller' );
     291
     292                // Bind to the scroll event and throttle
     293                // the results from this.scroller
     294                this.window.bind( 'scroll', _.throttle( this.scroller, 300 ) );
     295        },
     296
     297        // Main render control
     298        render: function() {
     299                // Setup the main plugin view
     300                // with the current plugin collection
     301                this.view = new plugins.view.Plugins({
     302                        collection: this.collection,
     303                        parent: this
     304                });
     305
     306                // Render and append
     307                this.view.render();
     308                this.$el.empty().append( this.view.el ).addClass( 'rendered' );
     309                this.$el.append( '<br class="clear"/>' );
     310        },
     311
     312        // Checks when the user gets close to the bottom
     313        // of the page and triggers a plugin:scroll event
     314        scroller: function() {
     315                var self = this,
     316                        bottom, threshold;
     317
     318                bottom = this.window.scrollTop() + self.window.height();
     319                threshold = self.$el.offset().top + self.$el.outerHeight( false ) - self.window.height();
     320                threshold = Math.round( threshold * 0.9 );
     321
     322                if ( bottom > threshold ) {
     323                        this.trigger( 'plugin:scroll' );
     324                }
     325        }
     326});
     327
     328// Controls the rendering of div.plugins,
     329// a wrapper that will hold all the plugin elements
     330plugins.view.Plugins = wp.Backbone.View.extend({
     331
     332        className: 'plugins',
     333
     334        // Number to keep track of scroll position
     335        // while in th-overlay mode
     336        index: 0,
     337
     338        // The plugin count element
     339        count: $( '.plugin-count' ),
     340
     341        initialize: function( options ) {
     342                var self = this;
     343
     344                // Set up parent
     345                this.parent = options.parent;
     346
     347                // When the collection is updated by user input...
     348                this.listenTo( self.collection, 'update', function() {
     349                        self.parent.page = 0;
     350                        self.render( this );
     351                });
     352
     353                // Update plugin count to full result set when available.
     354                this.listenTo( self.collection, 'query:success', function( count ) {
     355                        if ( _.isNumber( count ) ) {
     356                                self.count.text( count );
     357                        } else {
     358                                self.count.text( self.collection.length );
     359                        }
     360                });
     361
     362                this.listenTo( self.collection, 'query:empty', function() {
     363                        $( 'body' ).addClass( 'no-results' );
     364                });
     365
     366                this.listenTo( this.parent, 'plugin:scroll', function() {
     367                        self.renderPlugins( self.parent.page );
     368                });
     369        },
     370
     371        // Manages rendering of plugins pages
     372        // and keeping plugin count in sync
     373        render: function() {
     374                // Clear the DOM, please
     375                this.$el.html( '' );
     376
     377                // Generate the themes
     378                // Using page instance
     379                // While checking the collection has items
     380                if ( this.options.collection.size() > 0 ) {
     381                        this.renderPlugins( this.parent.page );
     382                }
     383
     384                // Display a live plugin count for the collection
     385                this.count.text( this.collection.count ? this.collection.count : this.collection.length );
     386        },
     387
     388        // Iterates through each instance of the collection
     389        // and renders each plugin module
     390        renderPlugins: function( page ) {
     391                var self = this;
     392
     393                self.instance = self.collection.paginate( page );
     394
     395                // If we have no more plugins bail
     396                if ( self.instance.size() === 0 ) {
     397                        // Fire a no-more-plugins event.
     398                        this.parent.trigger( 'plugin:end' );
     399                        return;
     400                }
     401               
     402                // Loop through the themes and setup each theme view
     403                self.instance.each( function( plugin ) {
     404                        self.plugin = new plugins.view.Plugin({
     405                                model: plugin,
     406                                parent: self
     407                        });
     408
     409                        // Render the views...
     410                        self.plugin.render();
     411                        // and append them to div.plugins
     412                        self.$el.append( self.plugin.el );
     413                });
     414
     415                this.parent.page++;
     416        },
     417});
     418
     419plugins.view.Installer = plugins.view.Appearance.extend({
     420
     421        el: '#wpbody-content .wrap',
     422        searchContainer: $( '.wp-filter' ),
     423        activeClass: 'current',
     424       
     425        window: $( window ),
     426        // Pagination instance
     427        page: 0,
     428       
     429        // Register events for sorting and filters in wp-filter
     430        events: {
     431                'click .wp-filter-link': 'onSort',
     432        },
     433       
     434        // Initial render method
     435        render: function() {
     436                var self = this;
     437
     438                this.search();
     439                this.uploader();
     440               
     441                this.collection = new plugins.Collection();
     442               
     443                // Bump `collection.currentQuery.page` and request more plugins if we hit the end of the page.
     444                this.listenTo( this, 'plugin:end', function() {
     445
     446                        // Set loadingPlugins to true and bump page instance of currentQuery.
     447                        self.collection.loadingPlugins = true;
     448                        self.collection.currentQuery.page++;
     449
     450                        // Use currentQuery.page to build the plugins request.
     451                        _.extend( self.collection.currentQuery.request, { page: self.collection.currentQuery.page } );
     452                        self.collection.query( self.collection.currentQuery.request );
     453                });
     454
     455                this.listenTo( this.collection, 'query:success', function() {
     456                        $( 'body' ).removeClass( 'loading-content' );
     457                        $( '.wp-filter-content' ).find( '.error' ).remove();
     458                });
     459
     460                this.listenTo( this.collection, 'query:fail', function() {
     461                        $( 'body' ).removeClass( 'loading-content' );
     462                        $( '.wp-filter-content' ).find( '.error' ).remove();
     463                        $( '.wp-filter-content' ).find( '.plugins' ).before( '<div class="error"><p>' + l10n.error + '</p></div>' );
     464                });
     465
     466                if ( this.view ) {
     467                        this.view.remove();
     468                }
     469
     470                // Set ups the view and passes the section argument
     471                this.view = new plugins.view.Plugins({
     472                        collection: this.collection,
     473                        parent: this
     474                });
     475
     476                // Reset pagination every time the install view handler is run
     477                this.page = 0;
     478
     479                // Render and append
     480                this.$el.find( '.plugins' ).remove();
     481                this.view.render();
     482                this.$el.find( '.wp-filter-content' ).append( this.view.el ).addClass( 'rendered' );
     483        },
     484       
     485        // Handles all the rendering of the public plugin directory
     486        browse: function( section ) {
     487                // Create a new collection with the proper plugin data
     488                // for each section
     489                this.collection.query( { browse: section } );
     490        },
     491
     492        // Sorting navigation
     493        onSort: function( event ) {
     494                var $el = $( event.target ),
     495                        sort = $el.data( 'sort' );
     496
     497                event.preventDefault();
     498
     499                $( 'body' ).removeClass( 'filters-applied show-filter-drawer' );
     500
     501                // Bail if this is already active
     502                if ( $el.hasClass( this.activeClass ) ) {
     503                        return;
     504                }
     505
     506                this.sort( sort );
     507
     508                // Trigger a router.navigate update
     509                plugins.router.navigate( plugins.router.baseUrl( '?browse=' + sort ) );
     510        },
     511       
     512        sort: function( sort ) {
     513                this.clearSearch();
     514
     515                $( '.wp-filter-link' ).removeClass( this.activeClass );
     516                $( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
     517
     518                this.browse( sort );
     519        },
     520       
     521        // Search input and view
     522        // for current plugin collection
     523        search: function() {
     524                var view,
     525                        self = this
     526
     527                view = new plugins.view.InstallerSearch({
     528                        collection: self.collection,
     529                        parent: this
     530                });
     531
     532                // Render and append search form
     533                view.render();
     534                this.searchContainer
     535                        .append( $.parseHTML( '<label class="screen-reader-text" for="wp-filter-search-input">' + l10n.search + '</label>' ) )
     536                        .append( view.el );
     537        },
     538       
     539        uploader: function() {
     540                $( '.wp-upload-show' ).on( 'click', function( event ) {
     541                        event.preventDefault();
     542                        $( 'body' ).addClass( 'show-upload-container' );
     543                        plugins.router.navigate( plugins.router.baseUrl( '?upload' ), { replace: true } );
     544                });
     545                $( '.wp-upload-hide' ).on( 'click', function( event ) {
     546                        event.preventDefault();
     547                        $( 'body' ).removeClass( 'show-upload-container' );
     548                        plugins.router.navigate( plugins.router.baseUrl( '' ), { replace: true } );
     549                });
     550        },
     551       
     552        clearSearch: function() {
     553                $( '#wp-filter-search-input' ).val( '' );
     554        }
     555});
     556
     557plugins.InstallerRouter = Backbone.Router.extend({
     558
     559        routes: {
     560                'plugin-install.php?browse=:sort': 'sort',
     561                'plugin-install.php?upload': 'upload',
     562                'plugin-install.php?search=:query': 'search',
     563                'plugin-install.php': 'sort'
     564        },
     565
     566        baseUrl: function( url ) {
     567                return 'plugin-install.php' + url;
     568        },
     569
     570        search: function( query ) {
     571                $( '.wp-filter-search' ).val( query );
     572        },
     573       
     574        navigate: function() {
     575                if ( Backbone.history._hasPushState ) {
     576                        Backbone.Router.prototype.navigate.apply( this, arguments );
     577                }
     578        }
     579
     580});
     581
     582plugins.RunInstaller = {
     583
     584        init: function() {
     585                // Set up the view
     586                // Passes the default 'section' as an option
     587                this.view = new plugins.view.Installer({
     588                        section: 'featured'
     589                });
     590
     591                // Render results
     592                this.render();
     593        },
     594
     595        render: function() {
     596
     597                // Render results
     598                this.view.render();
     599                this.routes();
     600               
     601                Backbone.history.start({
     602                        root: plugins.data.settings.adminUrl,
     603                        pushState: true,
     604                        hashChange: false
     605                });
     606        },
     607
     608        routes: function() {
     609                var self = this,
     610                        request = {};
     611
     612                // Bind to our global `wp.plugins` object
     613                // so that the router is available to sub-views
     614                plugins.router = new plugins.InstallerRouter();
     615
     616                // Handles sorting / browsing routes
     617                // Also handles the root URL triggering a sort request
     618                // for `featured`, the default view
     619                plugins.router.on( 'route:sort', function( sort ) {
     620                        if ( ! sort ) {
     621                                sort = 'featured';
     622                        }
     623                        self.view.sort( sort );
     624                        self.view.trigger( 'plugin:close' );
     625                });
     626               
     627                // Support the `upload` route by going straight to upload section
     628                plugins.router.on( 'route:upload', function() {
     629                        $( '.wp-upload-show' ).trigger( 'click' );
     630                });
     631               
     632                // The `search` route event. The router populates the input field.
     633                plugins.router.on( 'route:search', function() {
     634                        $( '.wp-filter-search' ).focus().trigger( 'keyup' );
     635                });
     636
     637                this.extraRoutes();
     638        },
     639
     640        extraRoutes: function() {
     641                return false;
     642        }
     643
     644}
     645
     646// Ready...
     647$( document ).ready(function() {
     648
     649        plugins.RunInstaller.init();
     650
     651});
     652
     653// Plugin Browser Thickbox related JS
     654var tb_position;
     655$( document ).ready(function() {
     656        tb_position = function() {
     657                var tbWindow = $( '#TB_window' ),
     658                        width = $( window ).width(),
     659                        H = $( window ).height() - ( ( 850 < width ) ? 60 : 20 ),
     660                        W = ( 850 < width ) ? 830 : width - 20;
     661
     662                if ( tbWindow.size() ) {
     663                        tbWindow.width( W ).height( H );
     664                        $( '#TB_iframeContent' ).width( W ).height( H );
     665                        tbWindow.css({
     666                                'margin-left': '-' + parseInt( ( W / 2 ), 10 ) + 'px'
     667                        });
     668                        if ( typeof document.body.style.maxWidth !== 'undefined' ) {
     669                                tbWindow.css({
     670                                        'top': ( ( 850 < width ) ? 30 : 10 ) + 'px',
     671                                        'margin-top': '0'
     672                                });
     673                        }
     674                }
     675               
     676                return $( 'a.thickbox' ).each( function() {
     677                        var href = $( this ).attr( 'href' );
     678                        if ( ! href ) {
     679                                return;
     680                        }
     681                        href = href.replace( /&width=[0-9]+/g, '' );
     682                        href = href.replace( /&height=[0-9]+/g, '' );
     683                        $(this).attr( 'href', href + '&width=' + W + '&height=' + ( H ) );
     684                });
     685        };
     686
     687        $( window ).resize( function() {
     688                tb_position();
     689        });
     690
     691        $('.plugins').on( 'click', 'a.thickbox', function() {
     692                tb_click.call(this);
     693               
     694                $('#TB_title').css({'background-color':'#222','color':'#cfcfcf'});
     695                $('#TB_ajaxWindowTitle').html('<strong>' + l10n.pluginInformation + '</strong>&nbsp;' + $(this).attr('title') );
     696               
     697                tb_position();
     698               
     699                return false;
     700        });
     701
     702        /* Plugin install related JS*/
     703        $( '#plugin-information-tabs a' ).click( function( event ) {
     704                var tab = $( this ).attr( 'name' );
     705                event.preventDefault();
     706                //Flip the tab
     707                $( '#plugin-information-tabs a.current' ).removeClass( 'current' );
     708                $( this ).addClass( 'current' );
     709                //Only show the fyi box in the description section, on smaller screen, where it's otherwise always displayed at the top.
     710                if ( 'description' != $( this ).attr( 'name' ) && $( 'body').width() < 830 )
     711                        $( '#plugin-information-content div.fyi' ).hide();
     712                else
     713                        $( '#plugin-information-content div.fyi' ).show();
     714                //Flip the content.
     715                $( '#section-holder div.section' ).hide(); //Hide 'em all
     716                $( '#section-' + tab ).show();
     717        });
     718
     719        $( 'a.install-now' ).click( function() {
     720                return confirm( l10n.ays );
     721        });
     722});
     723
     724})( jQuery );
     725 No newline at end of file
  • trunk/src/wp-admin/js/theme.js

     
    7979
    8080                // Render and append
    8181                this.view.render();
    82                 this.$el.empty().append( this.view.el ).addClass('rendered');
     82                this.$el.empty().append( this.view.el ).addClass( 'rendered' );
    8383                this.$el.append( '<br class="clear"/>' );
    8484        },
    8585
     
    105105                // Render and append after screen title
    106106                view.render();
    107107                this.searchContainer
    108                         .append( $.parseHTML( '<label class="screen-reader-text" for="theme-search-input">' + l10n.search + '</label>' ) )
     108                        .append( $.parseHTML( '<label class="screen-reader-text" for="wp-filter-search-input">' + l10n.search + '</label>' ) )
    109109                        .append( view.el );
    110110        },
    111111
    112112        // Checks when the user gets close to the bottom
    113         // of the mage and triggers a theme:scroll event
     113        // of the page and triggers a theme:scroll event
    114114        scroller: function() {
    115115                var self = this,
    116116                        bottom, threshold;
     
    342342                        beforeSend: function() {
    343343                                if ( ! paginated ) {
    344344                                        // Spin it
    345                                         $( 'body' ).addClass( 'loading-themes' ).removeClass( 'no-results' );
     345                                        $( 'body' ).addClass( 'loading-content' ).removeClass( 'no-results' );
    346346                                }
    347347                        }
    348348                });
     
    10801080themes.view.Search = wp.Backbone.View.extend({
    10811081
    10821082        tagName: 'input',
    1083         className: 'theme-search',
    1084         id: 'theme-search-input',
     1083        className: 'wp-filter-search',
     1084        id: 'wp-filter-search-input',
    10851085        searching: false,
    10861086
    10871087        attributes: {
     
    11101110        // Runs a search on the theme collection.
    11111111        search: function( event ) {
    11121112                var options = {};
    1113 
     1113               
    11141114                // Clear on escape.
    11151115                if ( event.type === 'keyup' && event.which === 27 ) {
    11161116                        event.target.value = '';
     
    11681168        },
    11691169
    11701170        search: function( query ) {
    1171                 $( '.theme-search' ).val( query );
     1171                $( '.wp-filter-search' ).val( query );
    11721172        },
    11731173
    11741174        themes: function() {
    1175                 $( '.theme-search' ).val( '' );
     1175                $( '.wp-filter-search' ).val( '' );
    11761176        },
    11771177
    11781178        navigate: function() {
     
    12291229
    12301230                // Handles search route event
    12311231                themes.router.on( 'route:search', function() {
    1232                         $( '.theme-search' ).trigger( 'keyup' );
     1232                        $( '.wp-filter-search' ).trigger( 'keyup' );
    12331233                });
    12341234
    12351235                this.extraRoutes();
     
    12881288                        request.tag = [ value.slice( 4 ) ];
    12891289                }
    12901290
    1291                 $( '.theme-section.current' ).removeClass( 'current' );
    1292                 $( 'body' ).removeClass( 'more-filters-opened filters-applied' );
     1291                $( '.wp-filter-link.current' ).removeClass( 'current' );
     1292                $( 'body' ).removeClass( 'show-filter-drawer filters-applied' );
    12931293
    12941294                // Get the themes by sending Ajax POST request to api.wordpress.org/themes
    12951295                // or searching the local cache
     
    13041304
    13051305        el: '#wpbody-content .wrap',
    13061306
    1307         // Register events for sorting and filters in theme-navigation
     1307        // Register events for sorting and filters in wp-filter
    13081308        events: {
    1309                 'click .theme-section': 'onSort',
     1309                'click .wp-filter-link': 'onSort',
    13101310                'click .theme-filter': 'onFilter',
    1311                 'click .more-filters': 'moreFilters',
    1312                 'click .apply-filters': 'applyFilters',
    1313                 'click [type="checkbox"]': 'addFilter',
    1314                 'click .clear-filters': 'clearFilters',
    1315                 'click .feature-name': 'filterSection',
    1316                 'click .filtering-by a': 'backToFilters'
     1311                'click .wp-filter-drawer-toggle': 'moreFilters',
     1312                'click .wp-filter-drawer-apply': 'applyFilters',
     1313                'click .wp-filter-group [type="checkbox"]': 'addFilter',
     1314                'click .wp-filter-drawer-clear': 'clearFilters',
     1315                'click .wp-filter-group-title': 'filterSection',
     1316                'click .wp-filter-by a': 'backToFilters'
    13171317        },
    13181318
    13191319        // Initial render method
     
    13431343                });
    13441344
    13451345                this.listenTo( this.collection, 'query:success', function() {
    1346                         $( 'body' ).removeClass( 'loading-themes' );
     1346                        $( 'body' ).removeClass( 'loading-content' );
    13471347                        $( '.theme-browser' ).find( 'div.error' ).remove();
    13481348                });
    13491349
    13501350                this.listenTo( this.collection, 'query:fail', function() {
    1351                         $( 'body' ).removeClass( 'loading-themes' );
     1351                        $( 'body' ).removeClass( 'loading-content' );
    13521352                        $( '.theme-browser' ).find( 'div.error' ).remove();
    13531353                        $( '.theme-browser' ).find( 'div.themes' ).before( '<div class="error"><p>' + l10n.error + '</p></div>' );
    13541354                });
     
    13861386
    13871387                event.preventDefault();
    13881388
    1389                 $( 'body' ).removeClass( 'filters-applied more-filters-opened' );
     1389                $( 'body' ).removeClass( 'filters-applied show-filter-drawer' );
    13901390
    13911391                // Bail if this is already active
    13921392                if ( $el.hasClass( this.activeClass ) ) {
     
    13951395
    13961396                this.sort( sort );
    13971397
    1398                 // Trigger a router.naviagte update
     1398                // Trigger a router.navigate update
    13991399                themes.router.navigate( themes.router.baseUrl( '?browse=' + sort ) );
    14001400        },
    14011401
    14021402        sort: function( sort ) {
    14031403                this.clearSearch();
    14041404
    1405                 $( '.theme-section, .theme-filter' ).removeClass( this.activeClass );
     1405                $( '.wp-filter-link, .theme-filter' ).removeClass( this.activeClass );
    14061406                $( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
    14071407
    14081408                this.browse( sort );
     
    14191419                        return;
    14201420                }
    14211421
    1422                 $( '.theme-filter, .theme-section' ).removeClass( this.activeClass );
     1422                $( '.wp-filter-link, .theme-filter' ).removeClass( this.activeClass );
    14231423                $el.addClass( this.activeClass );
    14241424
    14251425                if ( ! filter ) {
     
    14461446                var name,
    14471447                        tags = this.filtersChecked(),
    14481448                        request = { tag: tags },
    1449                         filteringBy = $( '.filtering-by .tags' );
     1449                        filteringBy = $( '.wp-filter-by .tags' );
    14501450
    14511451                if ( event ) {
    14521452                        event.preventDefault();
    14531453                }
    14541454
    14551455                $( 'body' ).addClass( 'filters-applied' );
    1456                 $( '.theme-section.current' ).removeClass( 'current' );
     1456                $( '.wp-filter-link.current' ).removeClass( 'current' );
    14571457                filteringBy.empty();
    14581458
    14591459                _.each( tags, function( tag ) {
    1460                         name = $( 'label[for="feature-id-' + tag + '"]' ).text();
     1460                        name = $( 'label[for="filter-id-' + tag + '"]' ).text();
    14611461                        filteringBy.append( '<span class="tag">' + name + '</span>' );
    14621462                });
    14631463
     
    14691469        // Get the checked filters
    14701470        // @return {array} of tags or false
    14711471        filtersChecked: function() {
    1472                 var items = $( '.feature-group' ).find( ':checkbox' ),
     1472                var items = $( '.wp-filter-group' ).find( ':checkbox' ),
    14731473                        tags = [];
    14741474
    14751475                _.each( items.filter( ':checked' ), function( item ) {
     
    14781478
    14791479                // When no filters are checked, restore initial state and return
    14801480                if ( tags.length === 0 ) {
    1481                         $( '.apply-filters' ).find( 'span' ).text( '' );
    1482                         $( '.clear-filters' ).hide();
     1481                        $( '.wp-filter-drawer-apply' ).find( 'span' ).text( '' );
     1482                        $( '.wp-filter-drawer-clear' ).hide();
    14831483                        $( 'body' ).removeClass( 'filters-applied' );
    14841484                        return false;
    14851485                }
    14861486
    1487                 $( '.apply-filters' ).find( 'span' ).text( tags.length );
    1488                 $( '.clear-filters' ).css( 'display', 'inline-block' );
     1487                $( '.wp-filter-drawer-apply' ).find( 'span' ).text( tags.length );
     1488                $( '.wp-filter-drawer-clear' ).css( 'display', 'inline-block' );
    14891489
    14901490                return tags;
    14911491        },
     
    14941494
    14951495        // Overwrite search container class to append search
    14961496        // in new location
    1497         searchContainer: $( '.theme-navigation' ),
     1497        searchContainer: $( '.wp-filter' ),
    14981498
    14991499        uploader: function() {
    1500                 $( 'a.upload' ).on( 'click', function( event ) {
     1500                $( '.wp-upload-show' ).on( 'click', function( event ) {
    15011501                        event.preventDefault();
    1502                         $( 'body' ).addClass( 'show-upload-theme' );
     1502                        $( 'body' ).addClass( 'show-upload-container' );
    15031503                        themes.router.navigate( themes.router.baseUrl( '?upload' ), { replace: true } );
    15041504                });
    1505                 $( 'a.browse-themes' ).on( 'click', function( event ) {
     1505                $( '.wp-upload-hide' ).on( 'click', function( event ) {
    15061506                        event.preventDefault();
    1507                         $( 'body' ).removeClass( 'show-upload-theme' );
     1507                        $( 'body' ).removeClass( 'show-upload-container' );
    15081508                        themes.router.navigate( themes.router.baseUrl( '' ), { replace: true } );
    15091509                });
    15101510        },
     
    15191519
    15201520                // If the filters section is opened and filters are checked
    15211521                // run the relevant query collapsing to filtered-by state
    1522                 if ( $( 'body' ).hasClass( 'more-filters-opened' ) && this.filtersChecked() ) {
     1522                if ( $( 'body' ).hasClass( 'show-filter-drawer' ) && this.filtersChecked() ) {
    15231523                        return this.addFilter();
    15241524                }
    15251525
    15261526                this.clearSearch();
    15271527
    15281528                themes.router.navigate( themes.router.baseUrl( '' ) );
    1529                 $( 'body' ).toggleClass( 'more-filters-opened' );
     1529                $( 'body' ).toggleClass( 'show-filter-drawer' );
    15301530        },
    15311531
    15321532        // Expand/collapse each individual filter section
     
    15371537        // Clears all the checked filters
    15381538        // @uses filtersChecked()
    15391539        clearFilters: function( event ) {
    1540                 var items = $( '.feature-group' ).find( ':checkbox' ),
     1540                var items = $( '.wp-filter-group' ).find( ':checkbox' ),
    15411541                        self = this;
    15421542
    15431543                event.preventDefault();
     
    15571557        },
    15581558
    15591559        clearSearch: function() {
    1560                 $( '#theme-search-input').val( '' );
     1560                $( '#wp-filter-search-input' ).val( '' );
    15611561        }
    15621562});
    15631563
     
    15751575        },
    15761576
    15771577        search: function( query ) {
    1578                 $( '.theme-search' ).val( query );
     1578                $( '.wp-filter-search' ).val( query );
    15791579        },
    15801580
    15811581        navigate: function() {
     
    16421642
    16431643                // Support the `upload` route by going straight to upload section
    16441644                themes.router.on( 'route:upload', function() {
    1645                         $( 'a.upload' ).trigger( 'click' );
     1645                        $( '.wp-upload-show' ).trigger( 'click' );
    16461646                });
    16471647
    16481648                // The `search` route event. The router populates the input field.
    16491649                themes.router.on( 'route:search', function() {
    1650                         $( '.theme-search' ).focus().trigger( 'keyup' );
     1650                        $( '.wp-filter-search' ).focus().trigger( 'keyup' );
    16511651                });
    16521652
    16531653                this.extraRoutes();
  • trunk/src/wp-admin/plugin-install.php

     
    66 * @subpackage Administration
    77 */
    88// TODO route this pages via a specific iframe handler instead of the do_action below
    9 if ( !defined( 'IFRAME_REQUEST' ) && isset( $_GET['tab'] ) && ( 'plugin-information' == $_GET['tab'] ) )
     9if ( !defined( 'IFRAME_REQUEST' ) && isset( $_GET['tab'] ) && ( 'plugin-information' == $_GET['tab'] ) ) {
    1010        define( 'IFRAME_REQUEST', true );
     11}
    1112
    1213/**
    1314 * WordPress Administration Bootstrap.
    1415 */
    1516require_once( dirname( __FILE__ ) . '/admin.php' );
     17require( ABSPATH . 'wp-admin/includes/plugin-install.php' );
    1618
    17 if ( ! current_user_can('install_plugins') )
     19wp_reset_vars( array( 'tab' ) );
     20
     21if ( ! current_user_can('install_plugins') ) {
    1822        wp_die(__('You do not have sufficient permissions to install plugins on this site.'));
     23}
    1924
    2025if ( is_multisite() && ! is_network_admin() ) {
    2126        wp_redirect( network_admin_url( 'plugin-install.php' ) );
    2227        exit();
    2328}
    2429
    25 $wp_list_table = _get_list_table('WP_Plugin_Install_List_Table');
    26 $pagenum = $wp_list_table->get_pagenum();
    27 $wp_list_table->prepare_items();
    28 
    2930$title = __('Install Plugins');
    3031$parent_file = 'plugins.php';
    3132
    32 wp_enqueue_script( 'plugin-install' );
    33 if ( 'plugin-information' != $tab )
     33$tabs = array(
     34        'upload'                => __( 'Upload Plugin' ),
     35        'browse-plugins'        => _x( 'Browse', 'plugins' ),
     36);
     37
     38$sections = array(
     39        'featured'      => _x( 'Featured', 'plugins' ),
     40        'popular'       => _x( 'Popular', 'plugins' ),
     41        'new'           => _x( 'Latest', 'plugins' ),
     42);
     43if ( $tab === 'beta' || false !== strpos( $GLOBALS['wp_version'], '-' ) ) {
     44        $sections['beta'] = _x( 'Beta Testing', 'plugins' );
     45}
     46
     47wp_localize_script( 'plugin', '_wpPluginSettings', array(
     48        'plugins' => false,
     49        'settings' => array(
     50                'isInstall'     => true,
     51                'canInstall'    => current_user_can( 'install_plugins' ),
     52                'installURI'    => current_user_can( 'install_plugins' ) ? self_admin_url( 'plugin-install.php' ) : null,
     53                'adminUrl'      => parse_url( self_admin_url(), PHP_URL_PATH )
     54        ),
     55        'l10n' => array(
     56                'search'  => __( 'Search Plugins' ),
     57                'searchPlaceholder' => __( 'Search plugins...' ), // placeholder (no ellipsis)
     58                'upload' => __( 'Upload Plugin' ),
     59                'error'  => __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ),
     60                'pluginInformation' => __('Plugin Information:'),
     61                'ays' => __('Are you sure you want to install this plugin?'),
     62        ),
     63        'browse' => array(
     64                'sections' => $sections,
     65        ),
     66) );
     67
     68wp_enqueue_script( 'plugin' );
     69
     70if ( 'plugin-information' != $tab ) {
    3471        add_thickbox();
     72}
    3573
    3674$body_id = $tab;
    3775
     
    4381 *
    4482 * @since 2.7.0
    4583 */
    46 do_action( "install_plugins_pre_$tab" );
     84if ( $tab ) {
     85        do_action( "install_plugins_pre_$tab" );       
     86}
    4787
     88add_screen_option( 'misc_screen_options', array( 'option' => 'manageplugin-installplugin-cardcolumnshidden', 'id' => 'plugin-card' ) );
     89
     90$screen_options = array(
     91        'description' => 'Description',
     92        'rating' => 'Rating',
     93        'extra_details' => 'Extra Details'
     94);
     95foreach ( $screen_options as $id => $label ) {
     96        add_screen_option( $id, array( 'label' => __( $label ) ) );
     97}
     98
    4899get_current_screen()->add_help_tab( array(
    49100'id'            => 'overview',
    50101'title'         => __('Overview'),
     
    73124include(ABSPATH . 'wp-admin/admin-header.php');
    74125?>
    75126<div class="wrap">
    76 <h2><?php echo esc_html( $title ); ?></h2>
     127        <h2>
     128                <?php echo esc_html( $title ); ?>
     129                <?php
     130                /**
     131                 * Filter the tabs shown on the Plugin Install screen.
     132                 *
     133                 * @since 2.7.0
     134                 * @param array $tabs The tabs shown on the Plugin Install screen. Defaults are
     135                 *                    'upload' and 'browse-plugins'.
     136                 */
     137                $tabs = apply_filters( 'install_plugins_tabs', $tabs );
     138                foreach ( $tabs as $tab_slug => $tab_name ) {
     139                        $visibility = $tab_slug == 'upload' ? ' wp-upload-show' : ' wp-upload-hide';
     140                       
     141                        echo '<a href="#" class="' . esc_attr( $tab_slug ) . $visibility . ' add-new-h2">' . $tab_name . '</a>';
     142                }
     143                ?>
     144        </h2>
    77145
    78 <?php $wp_list_table->views(); ?>
     146        <?php install_plugins_upload(); ?>
    79147
    80 <br class="clear" />
    81 <?php
    82 /**
    83  * Fires after the plugins list table in each tab of the Install Plugins screen.
    84  *
    85  * The dynamic portion of the action hook, $tab, allows for targeting
    86  * individual tabs, for instance 'install_plugins_plugin-information'.
    87  *
    88  * @since 2.7.0
    89  *
    90  * @param int $paged The current page number of the plugins list table.
    91  */
    92 ?>
    93 <?php do_action( "install_plugins_$tab", $paged ); ?>
     148        <div class="wp-filter hide-on-upload">
     149                <div class="wp-filter-count">
     150                        <span class="count plugin-count"></span>
     151                </div>
     152               
     153                <ul class="wp-filter-links">
     154                <?php foreach( $sections as $section_sort => $section_text ) { ?>
     155                        <li>
     156                                <a href="#" class="wp-filter-link" data-sort="<?php echo $section_sort; ?>">
     157                                        <?php echo $section_text; ?>
     158                                </a>
     159                        </li>
     160                <?php } ?>
     161                </ul>
     162               
     163                <a class="wp-filter-drawer-toggle dashicons-before dashicons-heart" href="#" data-drawer="favorites">
     164                        <?php _e( 'Favorites' ); ?>
     165                </a>
     166                <a class="wp-filter-drawer-toggle dashicons-before dashicons-tag" href="#" data-drawer="tag">
     167                        <?php _e( 'Tag Filter' ); ?>
     168                </a>
     169               
     170                <div class="wp-filter-drawer" data-drawer="favorites">
     171               
     172                        TODO - Favorites
     173                       
     174                </div>
     175                <div class="wp-filter-drawer" data-drawer="tag">
     176               
     177                        TODO - Tag Filter
     178                       
     179                </div>
     180       
     181        </div>
     182       
     183        <div class="hide-on-upload">
     184                <div class="wp-filter-content plugin-browser"></div>
     185       
     186                <p class="wp-filter-notice"><?php _e( 'No plugins found. Try a different search.' ); ?></p>
     187                <span class="spinner"></span>
     188        </div>
     189        <br class="clear" />
     190        <?php
     191        /**
     192         * Fires after the plugins list table in each tab of the Install Plugins screen.
     193         *
     194         * The dynamic portion of the action hook, $tab, allows for targeting
     195         * individual tabs, for instance 'install_plugins_plugin-information'.
     196         *
     197         * @since 2.7.0
     198         *
     199         * @param int $paged The current page number of the plugins list table.
     200         */
     201        if ( $tab ) {
     202                do_action( "install_plugins_$tab", $paged );
     203        }
     204        ?>
    94205</div>
     206
     207<script id="tmpl-plugin" type="text/template">
     208        <div class="plugin-card">
     209                <?php
     210                $hidden = get_user_option( 'manageplugin-installplugin-cardcolumnshidden' );
     211                $columns = array();
     212               
     213                foreach ( $screen_options as $id => $field ) {
     214                        $columns[$id] = is_array( $hidden ) && in_array( $id, $hidden ) ? "column-{$id} column-hidden" : "column-{$id} column-visible";
     215                }
     216                ?>
     217                <div class="plugin-card-top">
     218                        <div class="name data-field">
     219                                <h4>
     220                                        <a href="{{{ data.detail_url }}}" class="thickbox">
     221                                                {{{ data.name }}}
     222                                        </a>
     223                                </h4>
     224                        <# if ( data.action_links ) { #>
     225                                <div class="action-links">
     226                                        <ul class="plugin-action-buttons">
     227                                        <# _.each( data.action_links, function ( action_link ) { #>
     228                                                <li>{{{ action_link }}}</li>
     229                                        <# }); #>
     230                                        </ul>
     231                                </div>
     232                        <# } #>
     233                        </div>
     234                        <div class="desc <?php echo $columns['description']; ?>">
     235                                <p>
     236                                        {{{ data.short_description }}}
     237                                <# if ( data.author ) { #>
     238                                        <span class="authors">
     239                                                <cite><?php printf( __( 'By %s' ), '{{{ data.author }}}' ); ?></cite>
     240                                        </span>
     241                                <# } #>
     242                                </p>
     243                        </div>
     244                </div>
     245                <footer class="plugin-card-bottom <?php echo $columns['extra_details']; ?>">
     246                        <div class="vers <?php echo $columns['rating']; ?>">
     247                                <div class="rating rating-{{ Math.round( data.rating / 10 ) * 10 }}">
     248                                        <span class="one"></span>
     249                                        <span class="two"></span>
     250                                        <span class="three"></span>
     251                                        <span class="four"></span>
     252                                        <span class="five"></span>
     253                                </div>
     254                                <span class="num-ratings">({{ data.num_ratings_formatted }})</span>
     255                        </div>
     256                        <div class="column-updated">
     257                                <strong><?php echo __( 'Last updated:' ); ?></strong> {{ data.last_updated }}
     258                        </div>
     259                        <div class="column-downloaded">
     260                                <?php printf( _n( '%s download', '%s downloads', '{{ data.downloaded }}' ), '{{ data.downloaded }}' ); ?>
     261                        </div>
     262                        <div class="column-compatibility">
     263                        <# if ( data.compatibility == 'untested' ) { #>
     264                                <?php echo __( '<strong>Untested</strong> with your install' ); ?>
     265                        <# } else if ( data.compatibility == 'incompatible' ) { #>
     266                                <?php echo __( '<strong>Incompatible</strong> with your install' ); ?>
     267                        <# } else { #>
     268                                <?php echo __( '<strong>Compatible</strong> with your install' ); ?>
     269                        <# } #>
     270                        </div>
     271                </footer>
     272        </div>
     273</script>
     274               
    95275<?php
    96276/**
    97277 * WordPress Administration Template Footer.
    98278 */
    99 include(ABSPATH . 'wp-admin/admin-footer.php');
     279include(ABSPATH . 'wp-admin/admin-footer.php');
     280 No newline at end of file
  • trunk/src/wp-admin/theme-install.php

     
    1212
    1313wp_reset_vars( array( 'tab' ) );
    1414
    15 if ( ! current_user_can('install_themes') )
     15if ( ! current_user_can('install_themes') ) {
    1616        wp_die( __( 'You do not have sufficient permissions to install themes on this site.' ) );
     17}
    1718
    1819if ( is_multisite() && ! is_network_admin() ) {
    1920        wp_redirect( network_admin_url( 'theme-install.php' ) );
     
    3334);
    3435
    3536$sections = array(
    36         'featured' => __( 'Featured Themes' ),
    37         'popular'  => __( 'Popular Themes' ),
    38         'new'      => __( 'Newest Themes' ),
     37        'featured' => _x( 'Featured', 'themes' ),
     38        'popular'  => _x( 'Popular', 'themes' ),
     39        'new'      => _x( 'Latest', 'themes' ),
    3940);
    4041
    4142$installed_themes = search_theme_directories();
     
    125126                 */
    126127                $tabs = apply_filters( 'install_themes_tabs', $tabs );
    127128                foreach ( $tabs as $tab_slug => $tab_name ) {
    128                         echo '<a href="#" class="' . esc_attr( $tab_slug ) . ' add-new-h2">' . $tab_name . '</a>';
     129                        $visibility = $tab_slug == 'upload' ? ' wp-upload-show' : ' wp-upload-hide';
     130                       
     131                        echo '<a href="#" class="' . esc_attr( $tab_slug ) . $visibility . ' add-new-h2">' . $tab_name . '</a>';
    129132                }
    130133                ?>
    131134        </h2>
    132135
    133         <div class="upload-theme">
    134136        <?php install_themes_upload(); ?>
    135         </div>
    136 
    137         <div class="theme-navigation">
    138                 <span class="theme-count"></span>
    139                 <a class="theme-section" href="#" data-sort="featured"><?php _ex( 'Featured', 'themes' ); ?></a>
    140                 <a class="theme-section" href="#" data-sort="popular"><?php _ex( 'Popular', 'themes' ); ?></a>
    141                 <a class="theme-section" href="#" data-sort="new"><?php _ex( 'Latest', 'themes' ); ?></a>
    142                 <div class="theme-top-filters">
    143                         <!-- <span class="theme-filter" data-filter="photoblogging">Photography</span>
    144                         <span class="theme-filter" data-filter="responsive-layout">Responsive</span> -->
    145                         <a class="more-filters" href="#"><?php _e( 'Feature Filter' ); ?></a>
     137       
     138        <div class="wp-filter hide-on-upload">
     139                <div class="wp-filter-count">
     140                        <span class="count theme-count"></span>
    146141                </div>
    147                 <div class="more-filters-container">
    148                         <a class="apply-filters button button-secondary" href="#"><?php _e( 'Apply Filters' ); ?><span></span></a>
    149                         <a class="clear-filters button button-secondary" href="#"><?php _e( 'Clear' ); ?></a>
    150                         <br class="clear" />
     142               
     143                <ul class="wp-filter-links">
     144                <?php foreach( $sections as $section_sort => $section_text ) { ?>
     145                        <li>
     146                                <a href="#" class="wp-filter-link" data-sort="<?php echo $section_sort; ?>">
     147                                        <?php echo $section_text; ?>
     148                                </a>
     149                        </li>
     150                <?php } ?>
     151                </ul>
     152               
     153                <a class="wp-filter-drawer-toggle dashicons-before dashicons-admin-generic" href="#" data-drawer="feature">
     154                        <?php _e( 'Feature Filter' ); ?>
     155                </a>
     156               
     157                <div class="wp-filter-drawer" data-drawer="feature">
     158                        <div class="wp-filter-drawer-buttons">
     159                                <a class="wp-filter-drawer-apply button button-secondary" href="#"><?php _e( 'Apply Filters' ); ?><span></span></a>
     160                                <a class="wp-filter-drawer-clear button button-secondary" href="#"><?php _e( 'Clear' ); ?></a>
     161                        </div>
    151162                <?php
    152163                $feature_list = get_theme_feature_list();
    153164                foreach ( $feature_list as $feature_name => $features ) {
    154                         if ( $feature_name === 'Features' || $feature_name === __( 'Features' ) ) { // hack hack hack
    155                                 echo '<div class="filters-group wide-filters-group">';
    156                         } else {
    157                                 echo '<div class="filters-group">';
    158                         }
    159                         $feature_name = esc_html( $feature_name );
    160                         echo '<h4 class="feature-name">' . $feature_name . '</h4>';
    161                         echo '<ol class="feature-group">';
    162                         foreach ( $features as $feature => $feature_name ) {
    163                                 $feature = esc_attr( $feature );
    164                                 echo '<li><input type="checkbox" id="feature-id-' . $feature . '" value="' . $feature . '" /> ';
    165                                 echo '<label for="feature-id-' . $feature . '">' . $feature_name . '</label></li>';
    166                         }
    167                         echo '</ol>';
    168                         echo '</div>';
    169                 }
    170                 ?>
    171                         <div class="filtering-by">
     165                        if ( $feature_name === 'Features' || $feature_name === __( 'Features' ) ) { // hack hack hack ?>
     166                                <div class="wp-filter-group wp-filter-group-wide">
     167                        <?php } else { ?>
     168                                <div class="wp-filter-group">
     169                        <?php } ?>
     170                                <h4 class="wp-filter-group-title"><?php echo $feature_name; ?></h4>
     171                                <ol>
     172                                <?php foreach ( $features as $feature => $feature_name ) {
     173                                        $feature = esc_attr( $feature ); ?>
     174                                        <li>
     175                                                <input type="checkbox" id="filter-id-<?php echo $feature; ?>" value="<?php echo $feature; ?>" />
     176                                                <label for="filter-id-<?php echo $feature; ?>"><?php echo $feature_name; ?></label>
     177                                        </li>
     178                                <?php } ?>
     179                                </ol>
     180                        </div>
     181                <?php } ?>
     182                        <div class="wp-filter-by">
    172183                                <span><?php _e( 'Filtering by:' ); ?></span>
    173184                                <div class="tags"></div>
    174185                                <a href="#"><?php _e( 'Edit' ); ?></a>
    175186                        </div>
    176187                </div>
     188       
    177189        </div>
    178         <div class="theme-browser"></div>
    179         <div class="theme-install-overlay wp-full-overlay expanded"></div>
    180 
    181         <p class="no-themes"><?php _e( 'No themes found. Try a different search.' ); ?></p>
    182         <span class="spinner"></span>
    183 
     190       
     191        <div class="hide-on-upload">
     192                <div class="wp-filter-content theme-browser"></div>
     193                <div class="wp-full-overlay theme-install-overlay expanded"></div>
     194       
     195                <p class="wp-filter-notice"><?php _e( 'No themes found. Try a different search.' ); ?></p>
     196                <span class="spinner"></span>
     197        </div>
    184198        <br class="clear" />
    185 <?php
    186 /**
    187  * Fires at the top of each of the tabs on the Install Themes page.
    188  *
    189  * The dynamic portion of the hook name, $tab, refers to the current
    190  * theme install tab. Possible values are 'dashboard', 'search', 'upload',
    191  * 'featured', 'new', or 'updated'.
    192  *
    193  * @since 2.8.0
    194  *
    195  * @param int $paged Number of the current page of results being viewed.
    196  */
    197 if ( $tab ) {
    198         do_action( "install_themes_{$tab}", $paged );
    199 }
    200 ?>
     199        <?php
     200        /**
     201        * Fires at the top of each of the tabs on the Install Themes page.
     202        *
     203        * The dynamic portion of the hook name, $tab, refers to the current
     204        * theme install tab. Possible values are 'dashboard', 'search', 'upload',
     205        * 'featured', 'new', or 'updated'.
     206        *
     207        * @since 2.8.0
     208        *
     209        * @param int $paged Number of the current page of results being viewed.
     210        */
     211        if ( $tab ) {
     212                do_action( "install_themes_{$tab}", $paged );
     213        }
     214        ?>
    201215</div>
    202216
    203217<script id="tmpl-theme" type="text/template">
  • trunk/src/wp-admin/themes.php

     
    117117
    118118<div class="wrap">
    119119        <h2><?php esc_html_e( 'Themes' ); ?>
    120                 <span class="theme-count"><?php echo count( $themes ); ?></span>
     120                <span class="wp-title-count theme-count"><?php echo count( $themes ); ?></span>
    121121        <?php if ( ! is_multisite() && current_user_can( 'install_themes' ) ) : ?>
    122122                <a href="<?php echo admin_url( 'theme-install.php' ); ?>" class="hide-if-no-js add-new-h2"><?php echo esc_html( _x( 'Add New', 'Add new theme' ) ); ?></a>
    123123        <?php endif; ?>
  • trunk/src/wp-includes/script-loader.php

     
    488488                        'error' => __('Error while saving the changes.')
    489489                ) );
    490490
    491                 $scripts->add( 'plugin-install', "/wp-admin/js/plugin-install$suffix.js", array( 'jquery', 'thickbox' ), false, 1 );
    492                 did_action( 'init' ) && $scripts->localize( 'plugin-install', 'plugininstallL10n', array(
    493                         'plugin_information' => __('Plugin Information:'),
    494                         'ays' => __('Are you sure you want to install this plugin?')
    495                 ) );
     491                $scripts->add( 'plugin', "/wp-admin/js/plugin$suffix.js", array( 'wp-backbone' ), false, 1 );
    496492
    497493                $scripts->add( 'updates', "/wp-admin/js/updates$suffix.js", array( 'jquery' ) );
    498494