Make WordPress Core

Ticket #28673: 28673.diff

File 28673.diff, 79.0 KB (added by paulwilde, 8 years ago)
  • 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 body.more-filters-opened .more-filters:before {
    444         color: $menu-text;
    445         background-color: $menu-background;
    446 }
    447 
    448 body.more-filters-opened .more-filters:hover,
    449 body.more-filters-opened .more-filters:focus,
    450 body.more-filters-opened .more-filters:hover:before,
    451 body.more-filters-opened .more-filters:focus:before {
    452         background-color: $menu-highlight-background;
    453         color: $menu-highlight-text;
    454 }
    455 
    456437.theme-install-overlay .close-full-overlay:hover,
    457438.theme-install-overlay .close-full-overlay:focus,
    458439.theme-install-overlay .previous-theme:hover,
     
    463444        color: $menu-highlight-text;
    464445}
    465446
     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
    466472/* Widgets */
    467473
    468474.widgets-chooser li.widgets-chooser-selected {
     
    523529        background: $menu-highlight-background;
    524530}
    525531
    526 .star-rating .star {
     532.star-rating .star,
     533.rating span:before {
    527534        color: $highlight-color;
    528535}
    529536
  • 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}
     95body.show-filter-drawer .wp-filter-drawer {
     96        display: block;
     97        overflow: hidden;
     98}
     99body.show-filter-drawer .wp-filter-drawer-toggle:hover,
     100body.show-filter-drawer .wp-filter-drawer-toggle:focus {
     101        background: rgb(46, 162, 204);
     102}
     103body.show-filter-drawer .wp-filter-link.current {
     104        border-bottom: none;
     105}
     106
     107body.show-filter-drawer .wp-filter-drawer-toggle {
     108        background: #777;
     109        -webkit-border-radius: 2px;
     110        border-radius: 2px;
     111        border: none;
     112        color: #fff;
     113}
     114body.show-filter-drawer .wp-filter-drawer-toggle:before {
     115        color: #fff;
     116}
     117
     118.wp-filter-group {
     119        -webkit-box-sizing: border-box;
     120        -moz-box-sizing: border-box;
     121        box-sizing: border-box;
     122        float: left;
     123        width: 19%;
     124        background: #fff;
     125        margin: 0 1% 0 0;
     126        border: 1px solid #e5e5e5;
     127        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     128        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     129        padding: 10px;
     130}
     131.wp-filter-group-wide {
     132        width: 38%;
     133}
     134.wp-filter-group-title {
     135        margin: 0;
     136        position: relative;
     137}
     138
     139.wp-filter-drawer ol {
     140        list-style-type: none;
     141        margin: 20px 0 0;
     142        font-size: 12px;
     143}
     144.wp-filter-drawer li {
     145        display: inline-block;
     146        vertical-align: top;
     147        list-style-type: none;
     148        margin: 5px 0;
     149        padding-right: 25px;
     150        width: 160px;
     151}
     152
     153.wp-filter .button.wp-filter-drawer-apply {
     154        margin: 0 0 20px;
     155}
     156.wp-filter .button.wp-filter-drawer-apply span {
     157        display: inline-block;
     158        font-size: 12px;
     159        text-indent: 10px;
     160        opacity: 0.8;
     161}
     162.wp-filter .button.wp-filter-drawer-clear {
     163        display: none;
     164        margin: 0 0 20px 10px;
     165}
     166
     167.wp-filter-by {
     168        display: none;
     169        margin: 0;
     170}
     171.wp-filter-by > span {
     172        font-weight: 600;
     173}
     174.wp-filter-by a {
     175        margin-left: 10px;
     176}
     177.wp-filter-by .tags {
     178        display: inline;
     179}
     180.wp-filter-by .tag {
     181        background: #fff;
     182        border: 1px solid #e5e5e5;
     183        -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     184        box-shadow: 0 1px 1px rgba(0,0,0,0.04);
     185        font-size: 11px;
     186        margin: 0 5px;
     187        padding: 4px 8px;
     188}
     189
     190body.filters-applied .wp-filter-group,
     191body.filters-applied .wp-filter-drawer a.button,
     192body.filters-applied .wp-filter-drawer br {
     193        display: none !important;
     194}
     195body.filters-applied .wp-filter-by {
     196        display: block;
     197}
     198body.filters-applied .wp-filter-drawer {
     199        padding: 20px;
     200}
     201
     202body.show-filter-drawer .wp-filter-content,
     203body.show-filter-drawer.filters-applied.loading-content .wp-filter-content {
     204        display: none;
     205}
     206body.show-filter-drawer.filters-applied .wp-filter-content {
     207        display: block;
     208}
     209
     210.loading-content .wp-filter-content,
     211.error .wp-filter-content {
     212        display: none;
     213}
     214.loading-content .spinner {
     215        display: block;
     216        margin: 40px auto 0;
     217        float: none;
     218}
     219
     220.wp-filter-notice {
     221        color: #999;
     222        font-size: 18px;
     223        font-style: normal;
     224        margin: 0;
     225        padding: 0;
     226        text-align: center;
     227        display: none;
     228}
     229body.no-results .wp-filter-notice {
     230        display: block;
     231}
     232
     233@media only screen and (max-width: 1120px) {
     234
     235        .wp-filter-search {
     236                margin: 20px 0;
     237                position: static;
     238                width: 100%;
     239        }
     240       
     241        .wp-filter-drawer {
     242                border-bottom: 1px solid #eee;
     243        }
     244        .wp-filter-group {
     245                margin-bottom: 0;
     246                margin-top: 5px;
     247                width: 100%;
     248        }
     249        .wp-filter-group li {
     250                margin: 10px 0;
     251        }
     252}
     253
     254@media only screen and (max-width: 782px) {
     255
     256        .wp-filter-group,
     257        .wp-filter-group li {
     258                width: 100%;
     259        }
     260
     261}
     262 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 body.more-filters-opened .more-filters:before {
    1185         background: #777;
    1186         -webkit-border-radius: 2px;
    1187         border-radius: 2px;
    1188         border: none;
    1189         color: #fff;
    1190 }
    1191 
    1192 body.more-filters-opened .more-filters:hover,
    1193 body.more-filters-opened .more-filters:focus,
    1194 body.more-filters-opened .more-filters:hover:before,
    1195 body.more-filters-opened .more-filters:focus:before {
    1196         background: rgb(46, 162, 204);
    1197 }
    1198 
    1199 .theme-install-php .theme-search {
    1200         position: absolute;
    1201         right: 10px;
    1202         top: 9px;
    1203         font-size: 16px;
    1204         font-weight: 300;
    1205         line-height: 1.5;
    1206         width: 280px;
    1207 }
    1208 .more-filters:before {
    1209         color: #777;
    1210         text-align: center;
    1211         margin: 0 5px 0 0;
    1212         content: "\f111";
    1213         display: inline-block;
    1214         width: 16px;
    1215         height: 16px;
    1216         -webkit-font-smoothing: antialiased;
    1217         font-size: 16px;
    1218         line-height: 1;
    1219         font-family: "dashicons";
    1220         text-decoration: inherit;
    1221         font-weight: normal;
    1222         font-style: normal;
    1223         vertical-align: top;
    1224         -webkit-transition: color .1s ease-in 0;
    1225         transition: color .1s ease-in 0;
    1226         text-align: center;
    1227 }
    1228 .more-filters.current:before {
    1229         color: #fff;
    1230 }
    1231 .more-filters-container {
    1232         display: none;
    1233         padding: 20px;
    1234         border-top: 1px solid #eee;
    1235         margin: 0 -20px;
    1236         background: #fafafa;
    1237 }
    1238 body.more-filters-opened .more-filters-container {
    1239         display: block;
    1240         overflow: hidden;
    1241 }
    1242 body.more-filters-opened .theme-section.current {
    1243         border-bottom: none;
    1244 }
    1245 body.more-filters-opened .theme-browser,
    1246 body.more-filters-opened.filters-applied.loading-themes .theme-browser {
    1247         display: none;
    1248 }
    1249 body.more-filters-opened.filters-applied .theme-browser {
    1250         display: block;
    1251 }
    1252 .more-filters-container .filters-group {
    1253         -webkit-box-sizing: border-box;
    1254         -moz-box-sizing: border-box;
    1255         box-sizing: border-box;
    1256         float: left;
    1257         width: 19%;
    1258         background: #fff;
    1259         margin: 0 1% 0 0;
    1260         border: 1px solid #e5e5e5;
    1261         -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1262         box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1263         padding: 10px;
    1264 }
    1265 .more-filters-container .wide-filters-group {
    1266         width: 38%;
    1267 }
    1268 .more-filters-container .feature-name {
    1269         margin: 0;
    1270         position: relative;
    1271 }
    1272 .more-filters-container ol {
    1273         list-style-type: none;
    1274         margin: 20px 0 0;
    1275         font-size: 12px;
    1276 }
    1277 .more-filters-container li {
    1278         display: inline-block;
    1279         vertical-align: top;
    1280         list-style-type: none;
    1281         margin: 5px 0;
    1282         padding-right: 25px;
    1283         width: 160px;
    1284 }
    1285 .theme-navigation .more-filters-container .apply-filters {
    1286         margin: 0 0 20px;
    1287 }
    1288 .theme-navigation .more-filters-container .clear-filters {
    1289         display: none;
    1290         margin: 0 0 20px 10px;
    1291 }
    1292 .more-filters-container .apply-filters span {
    1293         display: inline-block;
    1294         font-size: 12px;
    1295         text-indent: 10px;
    1296         opacity: 0.8;
    1297 }
    1298 .more-filters-container .filtering-by {
    1299         display: none;
    1300         margin: 0;
    1301 }
    1302 .more-filters-container .filtering-by > span {
    1303         font-weight: 600;
    1304 }
    1305 .more-filters-container .filtering-by .tags {
    1306         display: inline;
    1307 }
    1308 .more-filters-container .filtering-by .tag {
    1309         background: #fff;
    1310         border: 1px solid #e5e5e5;
    1311         -webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1312         box-shadow: 0 1px 1px rgba(0,0,0,0.04);
    1313         font-size: 11px;
    1314         margin: 0 5px;
    1315         padding: 4px 8px;
    1316 }
    1317 .more-filters-container .filtering-by a {
    1318         margin-left: 10px;
    1319 }
    1320 body.filters-applied .more-filters-container .filters-group,
    1321 body.filters-applied .more-filters-container a.button,
    1322 body.filters-applied .more-filters-container br {
    1323         display: none !important;
    1324 }
    1325 body.filters-applied .more-filters-container .filtering-by {
    1326         display: block;
    1327 }
    1328 body.filters-applied .more-filters-container {
    1329         padding: 20px;
    1330 }
    1331 p.no-themes {
    1332         color: #999;
    1333         font-size: 18px;
    1334         font-style: normal;
    1335         margin: 0;
    1336         padding: 0;
    1337         text-align: center;
    1338         display: none;
    1339 }
    1340 body.no-results p.no-themes {
    1341         display: block;
    1342 }
    1343 body.show-upload-theme p.no-themes {
    1344         display: none !important;
    1345 }
    1346 
    1347 
    1348 .theme-install-php .add-new-theme {
    1349         display: none !important;
    1350 }
    1351 
    1352 @media only screen and (max-width: 1120px) {
    1353         .theme-install-php .theme-search {
    1354                 margin: 20px 0;
    1355                 position: static;
    1356                 width: 100%;
    1357         }
    1358         .more-filters-container {
    1359                 border-bottom: 1px solid #eee;
    1360         }
    1361         .upload-theme .wp-upload-form {
    1362                 margin: 20px 0;
    1363                 max-width: 100%;
    1364         }
    1365         .upload-theme .install-help {
    1366                 font-size: 15px;
    1367                 padding: 20px 0 0;
    1368                 text-align: left;
    1369         }
    1370         .more-filters-container .filters-group {
    1371                 margin-bottom: 0;
    1372                 margin-top: 5px;
    1373                 width: 100%;
    1374         }
    1375         .more-filters-container .filters-group li {
    1376                 margin: 10px 0;
    1377         }
    1378 }
    1379 
    1380 @media only screen and (max-width: 782px) {
    1381         .more-filters-container .filters-group {
    1382                 width: 100%;
    1383         }
    1384         .more-filters-container .filters-group li {
    1385                 width: 100%;
    1386         }
    1387 }
    1388 
    1389 .rating {
    1390         margin: 30px 0;
    1391 }
    1392 .rating span:before {
    1393         color: #e6b800;
    1394         content: "\f154";
    1395         display: inline-block;
    1396         -webkit-font-smoothing: antialiased;
    1397         font: normal 20px/1 'dashicons';
    1398         vertical-align: top;
    1399 }
    1400 /* Half stars */
    1401 .rating-10 span.one:before,
    1402 .rating-30 span.two:before,
    1403 .rating-50 span.three:before,
    1404 .rating-70 span.four:before,
    1405 .rating-90 span.five:before {
    1406         content: "\f459";
    1407 }
    1408 /* Full stars */
    1409 .rating-20 span.one:before {
    1410         content: "\f155";
    1411 }
    1412 .rating-30 span.one:before,
    1413 .rating-40 span.one:before,
    1414 .rating-40 span.two:before {
    1415         content: "\f155";
    1416 }
    1417 .rating-50 span.one:before,
    1418 .rating-50 span.two:before,
    1419 .rating-60 span.one:before,
    1420 .rating-60 span.two:before,
    1421 .rating-60 span.three:before {
    1422         content: "\f155";
    1423 }
    1424 .rating-70 span.one:before,
    1425 .rating-70 span.two:before,
    1426 .rating-70 span.three:before,
    1427 .rating-80 span.one:before,
    1428 .rating-80 span.two:before,
    1429 .rating-80 span.three:before,
    1430 .rating-80 span.four:before {
    1431         content: "\f155";
    1432 }
    1433 .rating-90 span.one:before,
    1434 .rating-90 span.two:before,
    1435 .rating-90 span.three:before,
    1436 .rating-90 span.four:before,
    1437 .rating-100 span.one:before,
    1438 .rating-100 span.two:before,
    1439 .rating-100 span.three:before,
    1440 .rating-100 span.four:before,
    1441 .rating-100 span.five:before {
    1442         content: "\f155";
    1443 }
    1444 .rating .ratings {
    1445         display: inline;
    1446         margin-left: 10px;
    1447         line-height: 20px;
    1448         color: #999;
    1449 }
    1450 .loading-themes .theme-browser,
    1451 .error .theme-browser {
    1452         display: none;
    1453 }
    1454 .loading-themes .spinner {
    1455         display: block;
    1456         margin: 40px auto 0;
    1457         float: none;
    1458 }
    1459 
    14601073/*------------------------------------------------------------------------------
    14611074  16.3 - Custom Header Screen
    14621075------------------------------------------------------------------------------*/
     
    16171230        overflow: auto;
    16181231}
    16191232
     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
    16201241/* Close & Navigation Links */
    16211242.theme-install-overlay .wp-full-overlay-sidebar .wp-full-overlay-header {
    16221243        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

     
    25862586}
    25872587
    25882588/**
     2589 * Ajax handler for getting plugins from plugins_api().
     2590 *
     2591 * @since 4.0.0
     2592 */
     2593function wp_ajax_query_plugins() {
     2594        global $plugins_allowedtags, $plugins_field_defaults;
     2595       
     2596        if ( ! current_user_can( 'install_plugins' ) ) {
     2597                wp_send_json_error();
     2598        }
     2599        $args = wp_parse_args( wp_unslash( $_REQUEST['request'] ), array(
     2600                'per_page' => 20,
     2601                'fields'   => $plugins_field_defaults
     2602        ) );
     2603
     2604        $old_filter = isset( $args['browse'] ) ? $args['browse'] : 'search';
     2605
     2606        /** This filter is documented in wp-admin/includes/class-wp-theme-install-list-table.php */
     2607        $args = apply_filters( 'install_plugins_table_api_args_' . $old_filter, $args );
     2608
     2609        require( ABSPATH . 'wp-admin/includes/plugin-install.php' ); // Needed for plugins_api
     2610       
     2611        $api = plugins_api( 'query_plugins', $args );
     2612
     2613        if ( is_wp_error( $api ) ) {
     2614                wp_send_json_error();
     2615        }
     2616
     2617        foreach ( $api->plugins as &$plugin ) {
     2618               
     2619                if ( version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin->tested ) ), $plugin->tested, '>' ) ) {
     2620                        $plugin->compatibility = 'untested';
     2621                } else if ( version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $plugin->requires ) ), $plugin->requires, '<' ) ) {
     2622                        $plugin->compatibility = 'incompatible';
     2623                } else {
     2624                        $plugin->compatibility = 'compatible';
     2625                }
     2626               
     2627                $details_link   = self_admin_url( 'plugin-install.php?tab=plugin-information&amp;plugin=' . $plugin->slug .
     2628                                                                '&amp;TB_iframe=true&amp;width=830&amp;height=654' );
     2629                                                               
     2630                /**
     2631                 * Filter the details link for a plugin.
     2632                 *
     2633                 * @since 4.0.0
     2634                 *
     2635                 * @param string $details_link Link to view the current plugin's details.
     2636                 * @param array  $plugin       The plugin currently being listed.
     2637                 */
     2638                $plugin->detail_url = apply_filters( 'plugin_install_details_link', $details_link, (array) $plugin );
     2639               
     2640                $action_links = array();
     2641               
     2642                $name = strip_tags( $plugin->name . ' ' . $plugin->version );
     2643               
     2644                $status = install_plugin_install_status( $plugin );
     2645               
     2646                switch ( $status['status'] ) {
     2647                        case 'install':
     2648                                if ( $status['url'] ) {
     2649                                        $action_links[]  = '<a class="install-now button" href="' . $status['url'] . '" title="' . esc_attr( sprintf( __( 'Install %s' ), $name ) ) . '">' . __( 'Install Now' ) . '</a>';
     2650                                }
     2651
     2652                                break;
     2653                        case 'update_available':
     2654                                if ( $status['url'] ) {
     2655                                        $action_links[] = '<a class="button" href="' . $status['url'] . '" title="' . esc_attr( sprintf( __( 'Update to version %s' ), $status['version'] ) ) . '">' . __( 'Update Now' ) . '</a>';
     2656                                }
     2657
     2658                                break;
     2659                        case 'latest_installed':
     2660                        case 'newer_installed':
     2661                                $action_links[] = '<span class="button button-disabled" title="' . esc_attr__( 'This plugin is already installed and is up to date' ) . ' ">' . _x( 'Installed', 'plugin' ) . '</span>';
     2662                                break;
     2663                }
     2664               
     2665                $action_links[] = '<a href="' . esc_attr( $details_link ) . '" class="thickbox" title="' .
     2666                                                                esc_attr( sprintf( __( 'More information about %s' ), $plugin->name ) ) . '">' . __( 'More Details' ) . '</a>';
     2667
     2668                /**
     2669                 * Filter the install action links for a plugin.
     2670                 *
     2671                 * @since 2.7.0
     2672                 *
     2673                 * @param array $action_links An array of plugin action hyperlinks. Defaults are links to Details and Install Now.
     2674                 * @param array $plugin       The plugin currently being listed.
     2675                 */
     2676                $plugin->action_links = apply_filters( 'plugin_install_action_links', $action_links, (array) $plugin );
     2677               
     2678                $plugin->name                                   = wp_kses( strip_tags( $plugin->name ), $plugins_allowedtags );
     2679                $plugin->author                                 = wp_kses( $plugin->author, $plugins_allowedtags );
     2680                $plugin->slug                                   = wp_kses( $plugin->slug, $plugins_allowedtags );
     2681                $plugin->version                                = wp_kses( $plugin->version, $plugins_allowedtags );
     2682                $plugin->description                    = strip_tags( $plugin->description );
     2683                $plugin->short_description              = strip_tags( $plugin->short_description );
     2684                $plugin->rating                                 = wp_kses( $plugin->rating, $plugins_allowedtags );
     2685                $plugin->ratings                                = wp_kses( $plugin->ratings, $plugins_allowedtags );
     2686                $plugin->num_ratings                    = $plugin->num_ratings;
     2687                $plugin->num_ratings_formatted  = number_format_i18n( $plugin->num_ratings );
     2688                $plugin->downloaded                             = number_format_i18n( $plugin->downloaded );
     2689                $plugin->last_updated                   = sprintf( __( '%s ago' ), human_time_diff( strtotime( $plugin->last_updated ) ) );
     2690        }
     2691
     2692        wp_send_json_success( $api );
     2693}
     2694
     2695/**
    25892696 * Apply [embed] handlers to a string.
    25902697 *
    25912698 * @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.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();
     
    12561256                }
    12571257
    12581258                this.collection = this.options.parent.view.collection;
     1259                this.collection.doSearch( event.target.value );
    12591260
    12601261                // Clear on escape.
    12611262                if ( event.type === 'keyup' && event.which === 27 ) {
     
    12881289                        request.tag = [ value.slice( 4 ) ];
    12891290                }
    12901291
    1291                 $( '.theme-section.current' ).removeClass( 'current' );
    1292                 $( 'body' ).removeClass( 'more-filters-opened filters-applied' );
     1292                $( '.wp-filter-link.current' ).removeClass( 'current' );
     1293                $( 'body' ).removeClass( 'show-filter-drawer filters-applied' );
    12931294
    12941295                // Get the themes by sending Ajax POST request to api.wordpress.org/themes
    12951296                // or searching the local cache
     
    13041305
    13051306        el: '#wpbody-content .wrap',
    13061307
    1307         // Register events for sorting and filters in theme-navigation
     1308        // Register events for sorting and filters in wp-filter
    13081309        events: {
    1309                 'click .theme-section': 'onSort',
     1310                'click .wp-filter-link': 'onSort',
    13101311                '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'
     1312                'click .wp-filter-drawer-toggle': 'moreFilters',
     1313                'click .wp-filter-drawer-apply': 'applyFilters',
     1314                'click .wp-filter-group [type="checkbox"]': 'addFilter',
     1315                'click .wp-filter-drawer-clear': 'clearFilters',
     1316                'click .wp-filter-group-title': 'filterSection',
     1317                'click .wp-filter-by a': 'backToFilters'
    13171318        },
    13181319
    13191320        // Initial render method
     
    13431344                });
    13441345
    13451346                this.listenTo( this.collection, 'query:success', function() {
    1346                         $( 'body' ).removeClass( 'loading-themes' );
     1347                        $( 'body' ).removeClass( 'loading-content' );
    13471348                        $( '.theme-browser' ).find( 'div.error' ).remove();
    13481349                });
    13491350
    13501351                this.listenTo( this.collection, 'query:fail', function() {
    1351                         $( 'body' ).removeClass( 'loading-themes' );
     1352                        $( 'body' ).removeClass( 'loading-content' );
    13521353                        $( '.theme-browser' ).find( 'div.error' ).remove();
    13531354                        $( '.theme-browser' ).find( 'div.themes' ).before( '<div class="error"><p>' + l10n.error + '</p></div>' );
    13541355                });
     
    13861387
    13871388                event.preventDefault();
    13881389
    1389                 $( 'body' ).removeClass( 'filters-applied more-filters-opened' );
     1390                $( 'body' ).removeClass( 'filters-applied show-filter-drawer' );
    13901391
    13911392                // Bail if this is already active
    13921393                if ( $el.hasClass( this.activeClass ) ) {
     
    13951396
    13961397                this.sort( sort );
    13971398
    1398                 // Trigger a router.naviagte update
     1399                // Trigger a router.navigate update
    13991400                themes.router.navigate( themes.router.baseUrl( '?browse=' + sort ) );
    14001401        },
    14011402
    14021403        sort: function( sort ) {
    14031404                this.clearSearch();
    14041405
    1405                 $( '.theme-section, .theme-filter' ).removeClass( this.activeClass );
     1406                $( '.wp-filter-link, .theme-filter' ).removeClass( this.activeClass );
    14061407                $( '[data-sort="' + sort + '"]' ).addClass( this.activeClass );
    14071408
    14081409                this.browse( sort );
     
    14191420                        return;
    14201421                }
    14211422
    1422                 $( '.theme-filter, .theme-section' ).removeClass( this.activeClass );
     1423                $( '.wp-filter-link, .theme-filter' ).removeClass( this.activeClass );
    14231424                $el.addClass( this.activeClass );
    14241425
    14251426                if ( ! filter ) {
     
    14461447                var name,
    14471448                        tags = this.filtersChecked(),
    14481449                        request = { tag: tags },
    1449                         filteringBy = $( '.filtering-by .tags' );
     1450                        filteringBy = $( '.wp-filter-by .tags' );
    14501451
    14511452                if ( event ) {
    14521453                        event.preventDefault();
    14531454                }
    14541455
    14551456                $( 'body' ).addClass( 'filters-applied' );
    1456                 $( '.theme-section.current' ).removeClass( 'current' );
     1457                $( '.wp-filter-link.current' ).removeClass( 'current' );
    14571458                filteringBy.empty();
    14581459
    14591460                _.each( tags, function( tag ) {
    1460                         name = $( 'label[for="feature-id-' + tag + '"]' ).text();
     1461                        name = $( 'label[for="filter-id-' + tag + '"]' ).text();
    14611462                        filteringBy.append( '<span class="tag">' + name + '</span>' );
    14621463                });
    14631464
     
    14691470        // Get the checked filters
    14701471        // @return {array} of tags or false
    14711472        filtersChecked: function() {
    1472                 var items = $( '.feature-group' ).find( ':checkbox' ),
     1473                var items = $( '.wp-filter-group' ).find( ':checkbox' ),
    14731474                        tags = [];
    14741475
    14751476                _.each( items.filter( ':checked' ), function( item ) {
     
    14781479
    14791480                // When no filters are checked, restore initial state and return
    14801481                if ( tags.length === 0 ) {
    1481                         $( '.apply-filters' ).find( 'span' ).text( '' );
    1482                         $( '.clear-filters' ).hide();
     1482                        $( '.wp-filter-drawer-apply' ).find( 'span' ).text( '' );
     1483                        $( '.wp-filter-drawer-clear' ).hide();
    14831484                        $( 'body' ).removeClass( 'filters-applied' );
    14841485                        return false;
    14851486                }
    14861487
    1487                 $( '.apply-filters' ).find( 'span' ).text( tags.length );
    1488                 $( '.clear-filters' ).css( 'display', 'inline-block' );
     1488                $( '.wp-filter-drawer-apply' ).find( 'span' ).text( tags.length );
     1489                $( '.wp-filter-drawer-clear' ).css( 'display', 'inline-block' );
    14891490
    14901491                return tags;
    14911492        },
     
    14941495
    14951496        // Overwrite search container class to append search
    14961497        // in new location
    1497         searchContainer: $( '.theme-navigation' ),
     1498        searchContainer: $( '.wp-filter' ),
    14981499
    14991500        uploader: function() {
    1500                 $( 'a.upload' ).on( 'click', function( event ) {
     1501                $( '.wp-upload-show' ).on( 'click', function( event ) {
    15011502                        event.preventDefault();
    1502                         $( 'body' ).addClass( 'show-upload-theme' );
     1503                        $( 'body' ).addClass( 'show-upload-container' );
    15031504                        themes.router.navigate( themes.router.baseUrl( '?upload' ), { replace: true } );
    15041505                });
    1505                 $( 'a.browse-themes' ).on( 'click', function( event ) {
     1506                $( '.wp-upload-hide' ).on( 'click', function( event ) {
    15061507                        event.preventDefault();
    1507                         $( 'body' ).removeClass( 'show-upload-theme' );
     1508                        $( 'body' ).removeClass( 'show-upload-container' );
    15081509                        themes.router.navigate( themes.router.baseUrl( '' ), { replace: true } );
    15091510                });
    15101511        },
     
    15191520
    15201521                // If the filters section is opened and filters are checked
    15211522                // run the relevant query collapsing to filtered-by state
    1522                 if ( $( 'body' ).hasClass( 'more-filters-opened' ) && this.filtersChecked() ) {
     1523                if ( $( 'body' ).hasClass( 'show-filter-drawer' ) && this.filtersChecked() ) {
    15231524                        return this.addFilter();
    15241525                }
    15251526
    15261527                this.clearSearch();
    15271528
    15281529                themes.router.navigate( themes.router.baseUrl( '' ) );
    1529                 $( 'body' ).toggleClass( 'more-filters-opened' );
     1530                $( 'body' ).toggleClass( 'show-filter-drawer' );
    15301531        },
    15311532
    15321533        // Expand/collapse each individual filter section
     
    15371538        // Clears all the checked filters
    15381539        // @uses filtersChecked()
    15391540        clearFilters: function( event ) {
    1540                 var items = $( '.feature-group' ).find( ':checkbox' ),
     1541                var items = $( '.wp-filter-group' ).find( ':checkbox' ),
    15411542                        self = this;
    15421543
    15431544                event.preventDefault();
     
    15571558        },
    15581559
    15591560        clearSearch: function() {
    1560                 $( '#theme-search-input').val( '' );
     1561                $( '#wp-filter-search-input' ).val( '' );
    15611562        }
    15621563});
    15631564
     
    15751576        },
    15761577
    15771578        search: function( query ) {
    1578                 $( '.theme-search' ).val( query );
     1579                $( '.wp-filter-search' ).val( query );
    15791580        },
    15801581
    15811582        navigate: function() {
     
    16421643
    16431644                // Support the `upload` route by going straight to upload section
    16441645                themes.router.on( 'route:upload', function() {
    1645                         $( 'a.upload' ).trigger( 'click' );
     1646                        $( '.wp-upload-show' ).trigger( 'click' );
    16461647                });
    16471648
    16481649                // The `search` route event. The router populates the input field.
    16491650                themes.router.on( 'route:search', function() {
    1650                         $( '.theme-search' ).focus().trigger( 'keyup' );
     1651                        $( '.wp-filter-search' ).focus().trigger( 'keyup' );
    16511652                });
    16521653
    16531654                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