From 6c8f14c09105d0afa4c1574215c59b5021040e76 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Fri, 14 Dec 2012 15:14:54 -0800 Subject: [PATCH] Wordpress 3.5 Signed-off-by: Edward Z. Yang --- readme.html | 2 +- wp-activate.php | 20 +- wp-admin/about.php | 111 +- wp-admin/admin-ajax.php | 14 +- wp-admin/admin-footer.php | 11 +- wp-admin/admin-header.php | 15 +- wp-admin/admin.php | 8 +- wp-admin/async-upload.php | 65 +- wp-admin/credits.php | 4 +- wp-admin/css/color-picker-rtl.css | 27 + wp-admin/css/color-picker-rtl.min.css | 1 + wp-admin/css/color-picker.css | 107 + wp-admin/css/color-picker.min.css | 1 + wp-admin/css/colors-classic.css | 2202 ++- wp-admin/css/colors-classic.dev.css | 2498 --- wp-admin/css/colors-classic.min.css | 1 + wp-admin/css/colors-fresh.css | 2077 ++- wp-admin/css/colors-fresh.dev.css | 2086 --- wp-admin/css/colors-fresh.min.css | 1 + wp-admin/css/customize-controls-rtl.css | 86 +- wp-admin/css/customize-controls-rtl.dev.css | 86 - wp-admin/css/customize-controls-rtl.min.css | 1 + wp-admin/css/customize-controls.css | 528 +- wp-admin/css/customize-controls.dev.css | 537 - wp-admin/css/customize-controls.min.css | 1 + wp-admin/css/ie-rtl.css | 241 +- wp-admin/css/ie-rtl.dev.css | 239 - wp-admin/css/ie-rtl.min.css | 1 + wp-admin/css/ie.css | 627 +- wp-admin/css/ie.dev.css | 573 - wp-admin/css/ie.min.css | 1 + wp-admin/css/install.css | 262 +- wp-admin/css/install.dev.css | 268 - wp-admin/css/install.min.css | 1 + wp-admin/css/media-rtl.css | 72 +- wp-admin/css/media-rtl.dev.css | 71 - wp-admin/css/media-rtl.min.css | 1 + wp-admin/css/media.css | 354 +- wp-admin/css/media.dev.css | 329 - wp-admin/css/media.min.css | 1 + wp-admin/css/wp-admin-rtl.css | 2642 ++- wp-admin/css/wp-admin-rtl.dev.css | 2532 --- wp-admin/css/wp-admin-rtl.min.css | 1 + wp-admin/css/wp-admin.css | 8590 ++++++++- wp-admin/css/wp-admin.dev.css | 8221 --------- wp-admin/css/wp-admin.min.css | 1 + wp-admin/custom-background.php | 59 +- wp-admin/custom-header.php | 162 +- wp-admin/customize.php | 15 +- wp-admin/edit-comments.php | 2 +- wp-admin/edit-form-advanced.php | 154 +- wp-admin/edit-form-comment.php | 12 +- wp-admin/edit-link-form.php | 6 +- wp-admin/edit-tag-form.php | 5 +- wp-admin/edit-tags.php | 16 +- wp-admin/edit.php | 13 +- wp-admin/export.php | 15 +- wp-admin/freedoms.php | 2 +- wp-admin/gears-manifest.php | 51 - wp-admin/images/align-center-2x.png | Bin 0 -> 147 bytes wp-admin/images/align-center.png | Bin 571 -> 546 bytes wp-admin/images/align-left-2x.png | Bin 0 -> 143 bytes wp-admin/images/align-left.png | Bin 587 -> 554 bytes wp-admin/images/align-none-2x.png | Bin 0 -> 121 bytes wp-admin/images/align-none.png | Bin 453 -> 417 bytes wp-admin/images/align-right-2x.png | Bin 0 -> 142 bytes wp-admin/images/align-right.png | Bin 556 -> 509 bytes wp-admin/images/archive-link.png | Bin 133 -> 0 bytes wp-admin/images/arrows-2x.png | Bin 0 -> 863 bytes wp-admin/images/arrows-dark-2x.png | Bin 0 -> 719 bytes wp-admin/images/arrows-dark-vs-2x.png | Bin 0 -> 761 bytes wp-admin/images/arrows-dark-vs.png | Bin 1376 -> 243 bytes wp-admin/images/arrows-dark.png | Bin 495 -> 243 bytes wp-admin/images/arrows-vs-2x.png | Bin 0 -> 723 bytes wp-admin/images/arrows-vs.png | Bin 1378 -> 243 bytes wp-admin/images/arrows.png | Bin 494 -> 243 bytes wp-admin/images/blue-grad.png | Bin 337 -> 0 bytes wp-admin/images/bubble_bg-2x.gif | Bin 0 -> 507 bytes wp-admin/images/bubble_bg-rtl-2x.gif | Bin 0 -> 499 bytes wp-admin/images/button-grad-active.png | Bin 284 -> 0 bytes wp-admin/images/button-grad.png | Bin 243 -> 0 bytes wp-admin/images/comment-grey-bubble-2x.png | Bin 0 -> 259 bytes wp-admin/images/comment-grey-bubble.png | Bin 158 -> 114 bytes wp-admin/images/date-button-2x.gif | Bin 0 -> 992 bytes wp-admin/images/date-button.gif | Bin 111 -> 400 bytes wp-admin/images/ed-bg-vs.gif | Bin 444 -> 0 bytes wp-admin/images/ed-bg.gif | Bin 190 -> 0 bytes wp-admin/images/fade-butt.png | Bin 785 -> 0 bytes wp-admin/images/fav-arrow-rtl.gif | Bin 243 -> 0 bytes wp-admin/images/fav-arrow.gif | Bin 241 -> 0 bytes wp-admin/images/fav-vs.png | Bin 142 -> 0 bytes wp-admin/images/fav.png | Bin 214 -> 0 bytes wp-admin/images/generic.png | Bin 3580 -> 719 bytes wp-admin/images/gray-grad.png | Bin 213 -> 0 bytes wp-admin/images/icons32-2x.png | Bin 37170 -> 35645 bytes wp-admin/images/icons32-vs-2x.png | Bin 36513 -> 37994 bytes wp-admin/images/icons32-vs.png | Bin 15706 -> 12920 bytes wp-admin/images/icons32.png | Bin 13441 -> 12989 bytes wp-admin/images/imgedit-icons-2x.png | Bin 0 -> 14853 bytes wp-admin/images/imgedit-icons.png | Bin 9607 -> 6989 bytes wp-admin/images/list-2x.png | Bin 0 -> 1523 bytes wp-admin/images/list.png | Bin 1104 -> 1003 bytes wp-admin/images/loading-publish.gif | Bin 1849 -> 0 bytes wp-admin/images/logo-ghost.png | Bin 559 -> 0 bytes wp-admin/images/logo.gif | Bin 1289 -> 0 bytes wp-admin/images/marker.png | Bin 652 -> 377 bytes wp-admin/images/mask.png | Bin 2020 -> 2001 bytes wp-admin/images/media-button-2x.png | Bin 0 -> 850 bytes wp-admin/images/media-button.png | Bin 3117 -> 323 bytes wp-admin/images/menu-2x.png | Bin 32775 -> 30324 bytes wp-admin/images/menu-arrow-frame-rtl.png | Bin 1391 -> 0 bytes wp-admin/images/menu-arrow-frame.png | Bin 564 -> 0 bytes wp-admin/images/menu-arrows.gif | Bin 330 -> 0 bytes wp-admin/images/menu-bits-rtl-vs.gif | Bin 1555 -> 0 bytes wp-admin/images/menu-bits-rtl.gif | Bin 1267 -> 0 bytes wp-admin/images/menu-bits-vs.gif | Bin 1448 -> 0 bytes wp-admin/images/menu-bits.gif | Bin 1139 -> 0 bytes wp-admin/images/menu-dark-rtl-vs.gif | Bin 245 -> 0 bytes wp-admin/images/menu-dark-rtl.gif | Bin 950 -> 0 bytes wp-admin/images/menu-dark-vs.gif | Bin 245 -> 0 bytes wp-admin/images/menu-dark.gif | Bin 245 -> 0 bytes wp-admin/images/menu-shadow-rtl.png | Bin 891 -> 92 bytes wp-admin/images/menu-shadow.png | Bin 131 -> 89 bytes wp-admin/images/menu-vs-2x.png | Bin 0 -> 29592 bytes wp-admin/images/menu-vs.png | Bin 9803 -> 9320 bytes wp-admin/images/menu.png | Bin 13585 -> 9165 bytes wp-admin/images/no.png | Bin 792 -> 755 bytes wp-admin/images/press-this-2x.png | Bin 0 -> 755 bytes wp-admin/images/press-this.png | Bin 567 -> 417 bytes wp-admin/images/required.gif | Bin 62 -> 0 bytes wp-admin/images/resize-2x.gif | Bin 0 -> 234 bytes wp-admin/images/resize-rtl-2x.gif | Bin 0 -> 232 bytes wp-admin/images/screen-options-toggle-vs.gif | Bin 152 -> 0 bytes wp-admin/images/screen-options-toggle.gif | Bin 205 -> 0 bytes .../images/screenshots/about-color-picker.png | Bin 0 -> 27110 bytes wp-admin/images/screenshots/about-media.png | Bin 0 -> 399038 bytes wp-admin/images/screenshots/about-retina.png | Bin 0 -> 155138 bytes .../screenshots/about-twenty-twelve.png | Bin 0 -> 201294 bytes wp-admin/images/screenshots/captions-1.png | Bin 96412 -> 0 bytes wp-admin/images/screenshots/captions-2.png | Bin 43760 -> 0 bytes wp-admin/images/screenshots/flex-header-1.png | Bin 72879 -> 0 bytes wp-admin/images/screenshots/flex-header-2.png | Bin 38544 -> 0 bytes wp-admin/images/screenshots/flex-header-3.png | Bin 48361 -> 0 bytes .../screenshots/flex-header-media-library.png | Bin 28192 -> 0 bytes .../images/screenshots/theme-customizer.png | Bin 106447 -> 0 bytes .../images/screenshots/twitter-embed-1.png | Bin 15096 -> 0 bytes .../images/screenshots/twitter-embed-2.png | Bin 16697 -> 0 bytes wp-admin/images/se.png | Bin 127 -> 120 bytes wp-admin/images/sort-2x.gif | Bin 0 -> 189 bytes wp-admin/images/stars-2x.png | Bin 0 -> 1257 bytes wp-admin/images/stars-rtl-2x.png | Bin 0 -> 3212 bytes wp-admin/images/stars-rtl.png | Bin 2003 -> 926 bytes wp-admin/images/stars.png | Bin 2098 -> 924 bytes wp-admin/images/toggle-arrow-rtl.gif | Bin 72 -> 0 bytes wp-admin/images/toggle-arrow.gif | Bin 71 -> 0 bytes wp-admin/images/upload-classic.png | Bin 1631 -> 0 bytes wp-admin/images/upload-fresh.png | Bin 1051 -> 0 bytes wp-admin/images/welcome-icons-2x.png | Bin 0 -> 6349 bytes wp-admin/images/welcome-icons.png | Bin 0 -> 2152 bytes wp-admin/images/wheel.png | Bin 11733 -> 11505 bytes wp-admin/images/white-grad-active.png | Bin 223 -> 0 bytes wp-admin/images/white-grad.png | Bin 210 -> 0 bytes wp-admin/images/widgets-arrow-vs.gif | Bin 213 -> 0 bytes wp-admin/images/widgets-arrow.gif | Bin 334 -> 0 bytes wp-admin/images/wordpress-logo.png | Bin 5048 -> 2480 bytes wp-admin/images/wp-badge.png | Bin 14352 -> 12099 bytes wp-admin/images/wp-logo-2x.png | Bin 0 -> 1806 bytes wp-admin/images/wp-logo-vs-2x.png | Bin 0 -> 2087 bytes wp-admin/images/wp-logo-vs.png | Bin 958 -> 751 bytes wp-admin/images/wp-logo.png | Bin 849 -> 661 bytes wp-admin/images/wpspin_dark.gif | Bin 2547 -> 0 bytes wp-admin/images/wpspin_light-2x.gif | Bin 0 -> 9097 bytes wp-admin/images/xit-2x.gif | Bin 0 -> 823 bytes wp-admin/images/yes.png | Bin 612 -> 539 bytes wp-admin/import.php | 58 +- wp-admin/includes/ajax-actions.php | 471 +- wp-admin/includes/bookmark.php | 22 + .../includes/class-wp-comments-list-table.php | 49 +- .../includes/class-wp-filesystem-base.php | 21 +- .../includes/class-wp-filesystem-ftpext.php | 4 + .../class-wp-filesystem-ftpsockets.php | 4 + wp-admin/includes/class-wp-importer.php | 5 - .../includes/class-wp-links-list-table.php | 13 +- wp-admin/includes/class-wp-list-table.php | 54 +- .../includes/class-wp-media-list-table.php | 103 +- .../includes/class-wp-ms-sites-list-table.php | 13 +- .../class-wp-ms-themes-list-table.php | 68 +- .../includes/class-wp-ms-users-list-table.php | 7 +- .../class-wp-plugin-install-list-table.php | 22 +- .../includes/class-wp-plugins-list-table.php | 64 +- .../includes/class-wp-posts-list-table.php | 217 +- .../includes/class-wp-terms-list-table.php | 86 +- .../class-wp-theme-install-list-table.php | 3 +- .../includes/class-wp-themes-list-table.php | 27 +- wp-admin/includes/class-wp-upgrader.php | 70 +- .../includes/class-wp-users-list-table.php | 56 +- wp-admin/includes/dashboard.php | 211 +- wp-admin/includes/deprecated.php | 93 +- wp-admin/includes/export.php | 4 +- wp-admin/includes/file.php | 18 +- wp-admin/includes/image-edit.php | 307 +- wp-admin/includes/image.php | 135 +- wp-admin/includes/import.php | 92 +- wp-admin/includes/list-table.php | 13 +- wp-admin/includes/manifest.php | 201 - wp-admin/includes/media.php | 640 +- wp-admin/includes/meta-boxes.php | 151 +- wp-admin/includes/misc.php | 51 +- wp-admin/includes/ms-deprecated.php | 4 +- wp-admin/includes/ms.php | 163 +- wp-admin/includes/nav-menu.php | 44 +- wp-admin/includes/plugin-install.php | 46 +- wp-admin/includes/plugin.php | 34 +- wp-admin/includes/post.php | 179 +- wp-admin/includes/schema.php | 76 +- wp-admin/includes/screen.php | 81 +- wp-admin/includes/template.php | 265 +- wp-admin/includes/theme-install.php | 26 +- wp-admin/includes/theme.php | 9 +- wp-admin/includes/update-core.php | 206 +- wp-admin/includes/update.php | 12 +- wp-admin/includes/upgrade.php | 134 +- wp-admin/includes/user.php | 23 +- wp-admin/includes/widgets.php | 10 +- wp-admin/index.php | 28 +- wp-admin/install.php | 18 +- wp-admin/js/cat.dev.js | 5 - wp-admin/js/cat.js | 6 +- wp-admin/js/cat.min.js | 1 + wp-admin/js/categories.dev.js | 34 - wp-admin/js/categories.js | 35 +- wp-admin/js/categories.min.js | 1 + wp-admin/js/color-picker.js | 131 + wp-admin/js/color-picker.min.js | 1 + wp-admin/js/comment.dev.js | 47 - wp-admin/js/comment.js | 50 +- wp-admin/js/comment.min.js | 1 + wp-admin/js/common.dev.js | 370 - wp-admin/js/common.js | 428 +- wp-admin/js/common.min.js | 1 + wp-admin/js/custom-background.dev.js | 66 - wp-admin/js/custom-background.js | 75 +- wp-admin/js/custom-background.min.js | 1 + wp-admin/js/custom-fields.dev.js | 34 - wp-admin/js/custom-fields.js | 35 +- wp-admin/js/custom-fields.min.js | 1 + wp-admin/js/custom-header.js | 60 + wp-admin/js/customize-controls.dev.js | 963 -- wp-admin/js/customize-controls.js | 1020 +- wp-admin/js/customize-controls.min.js | 1 + wp-admin/js/dashboard.dev.js | 93 - wp-admin/js/dashboard.js | 118 +- wp-admin/js/dashboard.min.js | 1 + wp-admin/js/edit-comments.dev.js | 606 - wp-admin/js/edit-comments.js | 608 +- wp-admin/js/edit-comments.min.js | 1 + wp-admin/js/editor.dev.js | 240 - wp-admin/js/editor.js | 239 +- wp-admin/js/editor.min.js | 1 + wp-admin/js/gallery.dev.js | 199 - wp-admin/js/gallery.js | 200 +- wp-admin/js/gallery.min.js | 1 + wp-admin/js/image-edit.dev.js | 572 - wp-admin/js/image-edit.js | 574 +- wp-admin/js/image-edit.min.js | 1 + wp-admin/js/inline-edit-post.dev.js | 303 - wp-admin/js/inline-edit-post.js | 304 +- wp-admin/js/inline-edit-post.min.js | 1 + wp-admin/js/inline-edit-tax.dev.js | 118 - wp-admin/js/inline-edit-tax.js | 119 +- wp-admin/js/inline-edit-tax.min.js | 1 + wp-admin/js/iris.min.js | 4 + wp-admin/js/link.dev.js | 67 - wp-admin/js/link.js | 68 +- wp-admin/js/link.min.js | 1 + wp-admin/js/media-gallery.dev.js | 25 - wp-admin/js/media-gallery.js | 26 +- wp-admin/js/media-gallery.min.js | 1 + wp-admin/js/media-upload.dev.js | 88 - wp-admin/js/media-upload.js | 89 +- wp-admin/js/media-upload.min.js | 1 + wp-admin/js/media.dev.js | 94 - wp-admin/js/media.js | 125 +- wp-admin/js/media.min.js | 1 + wp-admin/js/nav-menu.dev.js | 965 -- wp-admin/js/nav-menu.js | 966 +- wp-admin/js/nav-menu.min.js | 1 + wp-admin/js/password-strength-meter.dev.js | 36 - wp-admin/js/password-strength-meter.js | 37 +- wp-admin/js/password-strength-meter.min.js | 1 + wp-admin/js/plugin-install.dev.js | 53 - wp-admin/js/plugin-install.js | 54 +- wp-admin/js/plugin-install.min.js | 1 + wp-admin/js/post.dev.js | 663 - wp-admin/js/post.js | 769 +- wp-admin/js/post.min.js | 1 + wp-admin/js/postbox.dev.js | 181 - wp-admin/js/postbox.js | 187 +- wp-admin/js/postbox.min.js | 1 + wp-admin/js/set-post-thumbnail.dev.js | 21 - wp-admin/js/set-post-thumbnail.js | 22 +- wp-admin/js/set-post-thumbnail.min.js | 1 + wp-admin/js/tags.dev.js | 68 - wp-admin/js/tags.js | 69 +- wp-admin/js/tags.min.js | 1 + wp-admin/js/theme-preview.dev.js | 56 - wp-admin/js/theme-preview.js | 57 +- wp-admin/js/theme-preview.min.js | 1 + wp-admin/js/theme.dev.js | 254 - wp-admin/js/theme.js | 255 +- wp-admin/js/theme.min.js | 1 + wp-admin/js/user-profile.dev.js | 78 - wp-admin/js/user-profile.js | 79 +- wp-admin/js/user-profile.min.js | 1 + wp-admin/js/user-suggest.dev.js | 13 - wp-admin/js/user-suggest.js | 14 +- wp-admin/js/user-suggest.min.js | 1 + wp-admin/js/widgets.dev.js | 289 - wp-admin/js/widgets.js | 290 +- wp-admin/js/widgets.min.js | 1 + wp-admin/js/word-count.dev.js | 42 - wp-admin/js/word-count.js | 43 +- wp-admin/js/word-count.min.js | 1 + wp-admin/js/wp-fullscreen.dev.js | 731 - wp-admin/js/wp-fullscreen.js | 726 +- wp-admin/js/wp-fullscreen.min.js | 1 + wp-admin/js/xfn.dev.js | 16 - wp-admin/js/xfn.js | 17 +- wp-admin/js/xfn.min.js | 1 + wp-admin/link.php | 2 +- wp-admin/load-scripts.php | 8 +- wp-admin/load-styles.php | 4 +- wp-admin/maint/repair.php | 12 +- wp-admin/media-new.php | 81 +- wp-admin/media-upload.php | 89 - wp-admin/menu-header.php | 28 +- wp-admin/menu.php | 75 +- wp-admin/ms-delete-site.php | 4 +- wp-admin/nav-menus.php | 17 +- wp-admin/network.php | 184 +- wp-admin/network/menu.php | 2 +- wp-admin/network/settings.php | 51 +- wp-admin/network/site-info.php | 11 +- wp-admin/network/site-new.php | 11 +- wp-admin/network/site-themes.php | 6 - wp-admin/network/site-users.php | 58 +- wp-admin/network/sites.php | 225 +- wp-admin/network/themes.php | 22 +- wp-admin/network/upgrade.php | 7 +- wp-admin/network/users.php | 14 +- wp-admin/options-discussion.php | 19 +- wp-admin/options-general.php | 23 +- wp-admin/options-media.php | 42 +- wp-admin/options-permalink.php | 25 +- wp-admin/options-privacy.php | 63 - wp-admin/options-reading.php | 56 +- wp-admin/options-writing.php | 75 +- wp-admin/options.php | 40 +- wp-admin/plugin-editor.php | 9 +- wp-admin/plugin-install.php | 7 +- wp-admin/plugins.php | 19 +- wp-admin/post-new.php | 7 +- wp-admin/post.php | 30 +- wp-admin/press-this.php | 36 +- wp-admin/setup-config.php | 46 +- wp-admin/theme-editor.php | 19 +- wp-admin/theme-install.php | 2 +- wp-admin/themes.php | 22 +- wp-admin/update-core.php | 67 +- wp-admin/update.php | 8 +- wp-admin/upgrade.php | 12 +- wp-admin/upload.php | 10 +- wp-admin/user-edit.php | 19 +- wp-admin/user-new.php | 17 +- wp-admin/users.php | 72 +- wp-admin/widgets.php | 27 +- wp-app.php | 53 - .../themes/twentyeleven/colors/dark.css | 8 +- wp-content/themes/twentyeleven/comments.php | 13 +- .../themes/twentyeleven/content-aside.php | 4 +- .../themes/twentyeleven/content-featured.php | 2 +- .../themes/twentyeleven/content-gallery.php | 6 +- .../themes/twentyeleven/content-image.php | 6 +- .../themes/twentyeleven/content-link.php | 4 +- .../themes/twentyeleven/content-quote.php | 4 +- .../themes/twentyeleven/content-status.php | 4 +- wp-content/themes/twentyeleven/content.php | 12 +- .../themes/twentyeleven/editor-style.css | 3 +- wp-content/themes/twentyeleven/footer.php | 2 +- wp-content/themes/twentyeleven/functions.php | 19 +- .../images/comment-bubble-dark-rtl.png | Bin 1868 -> 856 bytes .../images/comment-bubble-dark.png | Bin 965 -> 872 bytes .../images/comment-bubble-rtl.png | Bin 1782 -> 783 bytes .../twentyeleven/images/comment-bubble.png | Bin 925 -> 791 bytes .../images/headers/chessboard.jpg | Bin 53906 -> 52548 bytes .../twentyeleven/images/headers/hanoi.jpg | Bin 40965 -> 39868 bytes .../images/headers/lanterns-thumbnail.jpg | Bin 8370 -> 8195 bytes .../twentyeleven/images/headers/lanterns.jpg | Bin 95061 -> 91152 bytes .../twentyeleven/images/headers/pine-cone.jpg | Bin 39112 -> 38272 bytes .../twentyeleven/images/headers/shore.jpg | Bin 79509 -> 77120 bytes .../twentyeleven/images/headers/trolley.jpg | Bin 62979 -> 62046 bytes .../twentyeleven/images/headers/wheel.jpg | Bin 60901 -> 59833 bytes .../twentyeleven/images/headers/willow.jpg | Bin 68450 -> 64681 bytes .../themes/twentyeleven/images/search.png | Bin 441 -> 440 bytes .../inc/images/content-sidebar.png | Bin 273 -> 210 bytes .../twentyeleven/inc/images/content.png | Bin 3682 -> 185 bytes .../themes/twentyeleven/inc/images/dark.png | Bin 6884 -> 5243 bytes .../themes/twentyeleven/inc/images/light.png | Bin 7052 -> 5354 bytes .../inc/images/sidebar-content.png | Bin 272 -> 209 bytes .../themes/twentyeleven/inc/widgets.php | 4 +- wp-content/themes/twentyeleven/js/html5.js | 9 +- .../twentyeleven/languages/twentyeleven.pot | 79 +- wp-content/themes/twentyeleven/screenshot.png | Bin 62878 -> 197796 bytes wp-content/themes/twentyeleven/showcase.php | 6 +- wp-content/themes/twentyeleven/single.php | 2 +- wp-content/themes/twentyeleven/style.css | 49 +- wp-content/themes/twentyten/404.php | 30 - wp-content/themes/twentyten/archive.php | 61 - wp-content/themes/twentyten/attachment.php | 26 - wp-content/themes/twentyten/author.php | 60 - wp-content/themes/twentyten/category.php | 34 - wp-content/themes/twentyten/comments.php | 79 - .../themes/twentyten/editor-style-rtl.css | 29 - wp-content/themes/twentyten/editor-style.css | 297 - wp-content/themes/twentyten/footer.php | 50 - wp-content/themes/twentyten/functions.php | 513 - wp-content/themes/twentyten/header.php | 108 - .../images/headers/berries-thumbnail.jpg | Bin 5727 -> 0 bytes .../twentyten/images/headers/berries.jpg | Bin 60696 -> 0 bytes .../headers/cherryblossoms-thumbnail.jpg | Bin 6542 -> 0 bytes .../images/headers/cherryblossoms.jpg | Bin 82037 -> 0 bytes .../images/headers/concave-thumbnail.jpg | Bin 5767 -> 0 bytes .../twentyten/images/headers/concave.jpg | Bin 38532 -> 0 bytes .../images/headers/fern-thumbnail.jpg | Bin 5530 -> 0 bytes .../themes/twentyten/images/headers/fern.jpg | Bin 25294 -> 0 bytes .../images/headers/forestfloor-thumbnail.jpg | Bin 6719 -> 0 bytes .../twentyten/images/headers/forestfloor.jpg | Bin 64870 -> 0 bytes .../images/headers/inkwell-thumbnail.jpg | Bin 4063 -> 0 bytes .../twentyten/images/headers/inkwell.jpg | Bin 39300 -> 0 bytes .../images/headers/path-thumbnail.jpg | Bin 4560 -> 0 bytes .../themes/twentyten/images/headers/path.jpg | Bin 51727 -> 0 bytes .../images/headers/sunset-thumbnail.jpg | Bin 2209 -> 0 bytes .../twentyten/images/headers/sunset.jpg | Bin 22830 -> 0 bytes .../themes/twentyten/images/wordpress.png | Bin 849 -> 0 bytes wp-content/themes/twentyten/index.php | 32 - .../themes/twentyten/languages/twentyten.pot | 422 - wp-content/themes/twentyten/license.txt | 281 - .../themes/twentyten/loop-attachment.php | 117 - wp-content/themes/twentyten/loop-page.php | 36 - wp-content/themes/twentyten/loop-single.php | 67 - wp-content/themes/twentyten/loop.php | 181 - .../themes/twentyten/onecolumn-page.php | 31 - wp-content/themes/twentyten/page.php | 32 - wp-content/themes/twentyten/rtl.css | 285 - wp-content/themes/twentyten/screenshot.png | Bin 34923 -> 0 bytes wp-content/themes/twentyten/search.php | 37 - .../themes/twentyten/sidebar-footer.php | 60 - wp-content/themes/twentyten/sidebar.php | 56 - wp-content/themes/twentyten/single.php | 27 - wp-content/themes/twentyten/style.css | 1359 -- wp-content/themes/twentyten/tag.php | 30 - wp-content/themes/twentytwelve/404.php | 29 + wp-content/themes/twentytwelve/archive.php | 63 + wp-content/themes/twentytwelve/author.php | 74 + wp-content/themes/twentytwelve/category.php | 51 + wp-content/themes/twentytwelve/comments.php | 60 + .../themes/twentytwelve/content-aside.php | 28 + .../themes/twentytwelve/content-image.php | 28 + .../themes/twentytwelve/content-link.php | 26 + .../themes/twentytwelve/content-none.php | 20 + .../themes/twentytwelve/content-page.php | 23 + .../themes/twentytwelve/content-quote.php | 25 + .../themes/twentytwelve/content-status.php | 32 + wp-content/themes/twentytwelve/content.php | 64 + wp-content/themes/twentytwelve/css/ie.css | 243 + .../themes/twentytwelve/editor-style-rtl.css | 28 + .../themes/twentytwelve/editor-style.css | 342 + wp-content/themes/twentytwelve/footer.php | 24 + wp-content/themes/twentytwelve/functions.php | 450 + wp-content/themes/twentytwelve/header.php | 54 + wp-content/themes/twentytwelve/image.php | 106 + .../themes/twentytwelve/inc/custom-header.php | 150 + wp-content/themes/twentytwelve/index.php | 66 + wp-content/themes/twentytwelve/js/html5.js | 7 + .../themes/twentytwelve/js/navigation.js | 33 + .../twentytwelve/js/theme-customizer.js | 32 + .../twentytwelve/languages/twentytwelve.pot | 350 + .../page-templates/front-page.php | 35 + .../page-templates/full-width.php | 30 + wp-content/themes/twentytwelve/page.php | 29 + wp-content/themes/twentytwelve/rtl.css | 237 + wp-content/themes/twentytwelve/screenshot.png | Bin 0 -> 171045 bytes wp-content/themes/twentytwelve/search.php | 49 + .../themes/twentytwelve/sidebar-front.php | 35 + wp-content/themes/twentytwelve/sidebar.php | 17 + wp-content/themes/twentytwelve/single.php | 33 + wp-content/themes/twentytwelve/style.css | 1727 ++ wp-content/themes/twentytwelve/tag.php | 51 + wp-cron.php | 8 +- wp-includes/SimplePie/Author.php | 157 + wp-includes/SimplePie/Cache.php | 133 + wp-includes/SimplePie/Cache/Base.php | 114 + wp-includes/SimplePie/Cache/DB.php | 137 + wp-includes/SimplePie/Cache/File.php | 173 + wp-includes/SimplePie/Cache/Memcache.php | 183 + wp-includes/SimplePie/Cache/MySQL.php | 438 + wp-includes/SimplePie/Caption.php | 210 + wp-includes/SimplePie/Category.php | 157 + .../SimplePie/Content/Type/Sniffer.php | 332 + wp-includes/SimplePie/Copyright.php | 130 + wp-includes/SimplePie/Core.php | 57 + wp-includes/SimplePie/Credit.php | 156 + .../SimplePie/Decode/HTML/Entities.php | 617 + wp-includes/SimplePie/Enclosure.php | 1380 ++ wp-includes/SimplePie/Exception.php | 52 + wp-includes/SimplePie/File.php | 292 + wp-includes/SimplePie/HTTP/Parser.php | 500 + wp-includes/SimplePie/IRI.php | 1238 ++ wp-includes/SimplePie/Item.php | 2964 ++++ wp-includes/SimplePie/Locator.php | 372 + wp-includes/SimplePie/Misc.php | 2247 +++ wp-includes/SimplePie/Net/IPv6.php | 276 + wp-includes/SimplePie/Parse/Date.php | 983 ++ wp-includes/SimplePie/Parser.php | 407 + wp-includes/SimplePie/Rating.php | 129 + wp-includes/SimplePie/Registry.php | 225 + wp-includes/SimplePie/Restriction.php | 155 + wp-includes/SimplePie/Sanitize.php | 554 + wp-includes/SimplePie/Source.php | 611 + .../SimplePie/XML/Declaration/Parser.php | 362 + wp-includes/SimplePie/gzdecode.php | 371 + wp-includes/admin-bar.php | 57 +- wp-includes/author-template.php | 6 +- wp-includes/bookmark-template.php | 13 +- wp-includes/bookmark.php | 9 +- wp-includes/cache.php | 121 +- wp-includes/canonical.php | 8 +- wp-includes/capabilities.php | 212 +- wp-includes/category-template.php | 30 +- wp-includes/category.php | 14 +- wp-includes/class-IXR.php | 11 +- wp-includes/class-feed.php | 37 +- wp-includes/class-http.php | 58 +- wp-includes/class-oembed.php | 78 +- wp-includes/class-simplepie.php | 14385 ++-------------- wp-includes/class-wp-admin-bar.php | 53 +- wp-includes/class-wp-ajax-response.php | 4 +- wp-includes/class-wp-atom-server.php | 1488 -- wp-includes/class-wp-customize-control.php | 284 +- wp-includes/class-wp-customize-manager.php | 60 +- wp-includes/class-wp-customize-section.php | 7 +- wp-includes/class-wp-customize-setting.php | 52 +- wp-includes/class-wp-editor.php | 160 +- wp-includes/class-wp-embed.php | 277 + wp-includes/class-wp-image-editor-gd.php | 390 + wp-includes/class-wp-image-editor-imagick.php | 468 + wp-includes/class-wp-image-editor.php | 400 + wp-includes/class-wp-theme.php | 28 +- wp-includes/class-wp-walker.php | 8 +- wp-includes/class-wp-xmlrpc-server.php | 669 +- wp-includes/class-wp.php | 40 +- wp-includes/class.wp-dependencies.php | 43 +- wp-includes/class.wp-scripts.php | 2 +- wp-includes/class.wp-styles.php | 2 +- wp-includes/comment-template.php | 23 +- wp-includes/comment.php | 142 +- wp-includes/cron.php | 41 +- wp-includes/css/admin-bar-rtl.css | 202 +- wp-includes/css/admin-bar-rtl.dev.css | 201 - wp-includes/css/admin-bar-rtl.min.css | 1 + wp-includes/css/admin-bar.css | 686 +- wp-includes/css/admin-bar.dev.css | 622 - wp-includes/css/admin-bar.min.css | 1 + wp-includes/css/buttons.css | 288 + wp-includes/css/buttons.min.css | 1 + wp-includes/css/editor.css | 2115 ++- wp-includes/css/editor.dev.css | 2021 --- wp-includes/css/editor.min.css | 1 + wp-includes/css/jquery-ui-dialog.css | 140 +- wp-includes/css/jquery-ui-dialog.dev.css | 140 - wp-includes/css/jquery-ui-dialog.min.css | 1 + wp-includes/css/media-views-rtl.css | 303 + wp-includes/css/media-views-rtl.min.css | 1 + wp-includes/css/media-views.css | 1673 ++ wp-includes/css/media-views.min.css | 1 + wp-includes/css/wp-pointer.css | 229 +- wp-includes/css/wp-pointer.dev.css | 188 - wp-includes/css/wp-pointer.min.css | 1 + wp-includes/default-constants.php | 19 +- wp-includes/default-filters.php | 8 +- wp-includes/default-widgets.php | 63 +- wp-includes/deprecated.php | 234 +- wp-includes/feed-atom-comments.php | 10 +- wp-includes/feed-atom.php | 8 +- wp-includes/feed-rss2-comments.php | 8 +- wp-includes/feed-rss2.php | 11 +- wp-includes/feed.php | 21 +- wp-includes/formatting.php | 183 +- wp-includes/functions.php | 584 +- wp-includes/functions.wp-scripts.php | 21 +- wp-includes/functions.wp-styles.php | 18 +- wp-includes/general-template.php | 85 +- wp-includes/http.php | 26 +- wp-includes/images/admin-bar-sprite-2x.png | Bin 4160 -> 4122 bytes wp-includes/images/admin-bar-sprite.png | Bin 3999 -> 2470 bytes wp-includes/images/arrow-pointer-blue-2x.png | Bin 0 -> 52574 bytes wp-includes/images/arrow-pointer-blue.png | Bin 959 -> 793 bytes wp-includes/images/crystal/archive.png | Bin 3066 -> 2897 bytes wp-includes/images/crystal/audio.png | Bin 2647 -> 2595 bytes wp-includes/images/crystal/code.png | Bin 2133 -> 1604 bytes wp-includes/images/crystal/default.png | Bin 638 -> 490 bytes wp-includes/images/crystal/document.png | Bin 2305 -> 2230 bytes wp-includes/images/crystal/interactive.png | Bin 2808 -> 2680 bytes wp-includes/images/crystal/spreadsheet.png | Bin 2725 -> 2680 bytes wp-includes/images/crystal/text.png | Bin 999 -> 707 bytes wp-includes/images/crystal/video.png | Bin 2372 -> 1339 bytes wp-includes/images/down_arrow-2x.gif | Bin 0 -> 83 bytes wp-includes/images/icon-pointer-flag-2x.png | Bin 0 -> 1369 bytes wp-includes/images/rss-2x.png | Bin 0 -> 1306 bytes wp-includes/images/rss.png | Bin 3341 -> 608 bytes wp-includes/images/toggle-arrow-2x.png | Bin 0 -> 354 bytes wp-includes/images/toggle-arrow.png | Bin 3226 -> 333 bytes wp-includes/images/upload.png | Bin 814 -> 0 bytes wp-includes/images/uploader-icons-2x.png | Bin 0 -> 3915 bytes wp-includes/images/uploader-icons.png | Bin 0 -> 1593 bytes wp-includes/images/wlw/wp-comments.png | Bin 1442 -> 1373 bytes wp-includes/images/wlw/wp-icon.png | Bin 779 -> 664 bytes wp-includes/images/wlw/wp-watermark.png | Bin 8280 -> 5102 bytes wp-includes/images/wpicons-2x.png | Bin 0 -> 125467 bytes wp-includes/images/wpicons.png | Bin 21059 -> 16089 bytes wp-includes/images/wpmini-blue-2x.png | Bin 0 -> 2087 bytes wp-includes/images/wpmini-blue.png | Bin 958 -> 751 bytes wp-includes/images/wpspin-2x.gif | Bin 0 -> 9097 bytes wp-includes/images/wpspin.gif | Bin 0 -> 2193 bytes wp-includes/images/xit-2x.gif | Bin 0 -> 823 bytes wp-includes/js/admin-bar.dev.js | 254 - wp-includes/js/admin-bar.js | 319 +- wp-includes/js/admin-bar.min.js | 1 + wp-includes/js/autosave.dev.js | 344 - wp-includes/js/autosave.js | 352 +- wp-includes/js/autosave.min.js | 1 + wp-includes/js/backbone.min.js | 38 + wp-includes/js/colorpicker.dev.js | 707 - wp-includes/js/colorpicker.js | 708 +- wp-includes/js/colorpicker.min.js | 1 + wp-includes/js/comment-reply.dev.js | 48 - wp-includes/js/comment-reply.js | 49 +- wp-includes/js/comment-reply.min.js | 1 + wp-includes/js/crop/marqueeHoriz.gif | Bin 1125 -> 277 bytes wp-includes/js/crop/marqueeVert.gif | Bin 1141 -> 293 bytes wp-includes/js/customize-base.dev.js | 586 - wp-includes/js/customize-base.js | 586 +- wp-includes/js/customize-base.min.js | 1 + wp-includes/js/customize-loader.dev.js | 159 - wp-includes/js/customize-loader.js | 165 +- wp-includes/js/customize-loader.min.js | 1 + wp-includes/js/customize-preview.dev.js | 146 - wp-includes/js/customize-preview.js | 147 +- wp-includes/js/customize-preview.min.js | 1 + wp-includes/js/hoverIntent.dev.js | 106 - wp-includes/js/hoverIntent.js | 107 +- wp-includes/js/hoverIntent.min.js | 1 + .../js/imgareaselect/border-anim-h.gif | Bin 219 -> 178 bytes .../js/imgareaselect/border-anim-v.gif | Bin 219 -> 178 bytes .../imgareaselect/jquery.imgareaselect.dev.js | 1198 -- .../js/imgareaselect/jquery.imgareaselect.js | 1199 +- .../imgareaselect/jquery.imgareaselect.min.js | 1 + wp-includes/js/jcrop/Jcrop.gif | Bin 329 -> 323 bytes wp-includes/js/jcrop/jquery.Jcrop.css | 35 - wp-includes/js/jcrop/jquery.Jcrop.dev.js | 1197 -- wp-includes/js/jcrop/jquery.Jcrop.js | 1 - wp-includes/js/jcrop/jquery.Jcrop.min.css | 28 + wp-includes/js/jcrop/jquery.Jcrop.min.js | 22 + wp-includes/js/jquery/jquery.color.dev.js | 128 - wp-includes/js/jquery/jquery.color.js | 1 - wp-includes/js/jquery/jquery.color.min.js | 2 + wp-includes/js/jquery/jquery.form.dev.js | 825 - wp-includes/js/jquery/jquery.form.js | 816 +- wp-includes/js/jquery/jquery.form.min.js | 11 + wp-includes/js/jquery/jquery.hotkeys.dev.js | 131 - wp-includes/js/jquery/jquery.hotkeys.js | 132 +- wp-includes/js/jquery/jquery.hotkeys.min.js | 1 + wp-includes/js/jquery/jquery.js | 6 +- wp-includes/js/jquery/jquery.masonry.min.js | 10 + .../js/jquery/jquery.table-hotkeys.dev.js | 99 - wp-includes/js/jquery/jquery.table-hotkeys.js | 100 +- .../js/jquery/jquery.table-hotkeys.min.js | 1 + wp-includes/js/jquery/suggest.dev.js | 330 - wp-includes/js/jquery/suggest.js | 331 +- wp-includes/js/jquery/suggest.min.js | 1 + .../js/jquery/ui/jquery.effects.blind.min.js | 5 - .../js/jquery/ui/jquery.effects.bounce.min.js | 5 - .../js/jquery/ui/jquery.effects.clip.min.js | 5 - .../js/jquery/ui/jquery.effects.core.min.js | 5 - .../js/jquery/ui/jquery.effects.drop.min.js | 5 - .../jquery/ui/jquery.effects.explode.min.js | 5 - .../js/jquery/ui/jquery.effects.fade.min.js | 5 - .../js/jquery/ui/jquery.effects.fold.min.js | 5 - .../jquery/ui/jquery.effects.highlight.min.js | 5 - .../jquery/ui/jquery.effects.pulsate.min.js | 5 - .../js/jquery/ui/jquery.effects.scale.min.js | 5 - .../js/jquery/ui/jquery.effects.shake.min.js | 5 - .../js/jquery/ui/jquery.effects.slide.min.js | 5 - .../jquery/ui/jquery.effects.transfer.min.js | 5 - .../js/jquery/ui/jquery.ui.accordion.min.js | 8 +- .../jquery/ui/jquery.ui.autocomplete.min.js | 8 +- .../js/jquery/ui/jquery.ui.button.min.js | 8 +- .../js/jquery/ui/jquery.ui.core.min.js | 8 +- .../js/jquery/ui/jquery.ui.datepicker.min.js | 8 +- .../js/jquery/ui/jquery.ui.dialog.min.js | 8 +- .../js/jquery/ui/jquery.ui.draggable.min.js | 8 +- .../js/jquery/ui/jquery.ui.droppable.min.js | 8 +- .../jquery/ui/jquery.ui.effect-blind.min.js | 5 + .../jquery/ui/jquery.ui.effect-bounce.min.js | 5 + .../js/jquery/ui/jquery.ui.effect-clip.min.js | 5 + .../js/jquery/ui/jquery.ui.effect-drop.min.js | 5 + .../jquery/ui/jquery.ui.effect-explode.min.js | 5 + .../js/jquery/ui/jquery.ui.effect-fade.min.js | 5 + .../js/jquery/ui/jquery.ui.effect-fold.min.js | 5 + .../ui/jquery.ui.effect-highlight.min.js | 5 + .../jquery/ui/jquery.ui.effect-pulsate.min.js | 5 + .../jquery/ui/jquery.ui.effect-scale.min.js | 5 + .../jquery/ui/jquery.ui.effect-shake.min.js | 5 + .../jquery/ui/jquery.ui.effect-slide.min.js | 5 + .../ui/jquery.ui.effect-transfer.min.js | 5 + .../js/jquery/ui/jquery.ui.effect.min.js | 5 + .../js/jquery/ui/jquery.ui.menu.min.js | 5 + .../js/jquery/ui/jquery.ui.mouse.min.js | 8 +- .../js/jquery/ui/jquery.ui.position.min.js | 8 +- .../js/jquery/ui/jquery.ui.progressbar.min.js | 8 +- .../js/jquery/ui/jquery.ui.resizable.min.js | 8 +- .../js/jquery/ui/jquery.ui.selectable.min.js | 8 +- .../js/jquery/ui/jquery.ui.slider.min.js | 8 +- .../js/jquery/ui/jquery.ui.sortable.min.js | 8 +- .../js/jquery/ui/jquery.ui.spinner.min.js | 5 + .../js/jquery/ui/jquery.ui.tabs.min.js | 8 +- .../js/jquery/ui/jquery.ui.tooltip.min.js | 5 + .../js/jquery/ui/jquery.ui.widget.min.js | 8 +- wp-includes/js/json2.dev.js | 480 - wp-includes/js/json2.js | 481 +- wp-includes/js/json2.min.js | 1 + wp-includes/js/mce-view.js | 349 + wp-includes/js/mce-view.min.js | 1 + wp-includes/js/media-editor.js | 646 + wp-includes/js/media-editor.min.js | 1 + wp-includes/js/media-models.js | 908 + wp-includes/js/media-models.min.js | 1 + wp-includes/js/media-views.js | 4289 +++++ wp-includes/js/media-views.min.js | 1 + wp-includes/js/plupload/handlers.dev.js | 481 - wp-includes/js/plupload/handlers.js | 487 +- wp-includes/js/plupload/handlers.min.js | 1 + wp-includes/js/plupload/wp-plupload.dev.js | 230 - wp-includes/js/plupload/wp-plupload.js | 344 +- wp-includes/js/plupload/wp-plupload.min.js | 1 + wp-includes/js/prototype.js | 4874 ------ wp-includes/js/quicktags.dev.js | 645 - wp-includes/js/quicktags.js | 650 +- wp-includes/js/quicktags.min.js | 1 + wp-includes/js/scriptaculous/MIT-LICENSE | 20 - wp-includes/js/scriptaculous/builder.js | 136 - wp-includes/js/scriptaculous/controls.js | 965 -- wp-includes/js/scriptaculous/dragdrop.js | 974 -- wp-includes/js/scriptaculous/effects.js | 1123 -- wp-includes/js/scriptaculous/scriptaculous.js | 68 - wp-includes/js/scriptaculous/slider.js | 275 - wp-includes/js/scriptaculous/sound.js | 59 - wp-includes/js/scriptaculous/unittest.js | 568 - .../js/scriptaculous/wp-scriptaculous.js | 73 - wp-includes/js/shortcode.js | 342 + wp-includes/js/shortcode.min.js | 1 + wp-includes/js/swfupload/handlers.dev.js | 370 - wp-includes/js/swfupload/handlers.js | 371 +- wp-includes/js/swfupload/handlers.min.js | 1 + wp-includes/js/thickbox/loadingAnimation.gif | Bin 5886 -> 15238 bytes wp-includes/js/thickbox/macFFBgHack.png | Bin 207 -> 94 bytes wp-includes/js/thickbox/tb-close-2x.png | Bin 0 -> 412 bytes wp-includes/js/thickbox/tb-close.png | Bin 506 -> 387 bytes wp-includes/js/thickbox/thickbox.css | 20 +- wp-includes/js/thickbox/thickbox.js | 11 +- wp-includes/js/tinymce/langs/wp-langs-en.js | 11 +- wp-includes/js/tinymce/langs/wp-langs.php | 15 +- .../plugins/directionality/editor_plugin.js | 2 +- .../directionality/editor_plugin_src.js | 41 +- .../plugins/fullscreen/editor_plugin.js | 2 +- .../plugins/fullscreen/editor_plugin_src.js | 10 +- .../tinymce/plugins/fullscreen/fullscreen.htm | 2 +- .../skins/clearlooks2/img/alert.gif | Bin 818 -> 810 bytes .../skins/clearlooks2/img/button.gif | Bin 280 -> 272 bytes .../skins/clearlooks2/img/confirm.gif | Bin 915 -> 907 bytes .../skins/clearlooks2/img/corners.gif | Bin 911 -> 909 bytes .../skins/clearlooks2/img/drag.gif | Bin 57 -> 51 bytes .../skins/clearlooks2/img/vertical.gif | Bin 92 -> 84 bytes .../tinymce/plugins/inlinepopups/template.htm | 2 +- .../js/tinymce/plugins/media/editor_plugin.js | 2 +- .../plugins/media/editor_plugin_src.js | 38 +- .../js/tinymce/plugins/media/js/media.js | 69 +- .../js/tinymce/plugins/media/media.htm | 14 +- .../js/tinymce/plugins/paste/editor_plugin.js | 2 +- .../plugins/paste/editor_plugin_src.js | 20 +- .../js/tinymce/plugins/paste/pastetext.htm | 13 +- .../js/tinymce/plugins/paste/pasteword.htm | 13 +- .../spellchecker/classes/GoogleSpell.php | 6 +- .../plugins/spellchecker/editor_plugin.js | 2 +- .../plugins/spellchecker/editor_plugin_src.js | 8 +- .../tinymce/plugins/tabfocus/editor_plugin.js | 2 +- .../plugins/tabfocus/editor_plugin_src.js | 2 +- .../plugins/wordpress/editor_plugin.js | 2 +- .../plugins/wordpress/editor_plugin_src.js | 92 +- .../tinymce/plugins/wordpress/img/image.gif | Bin 101 -> 95 bytes .../tinymce/plugins/wordpress/img/video.gif | Bin 99 -> 93 bytes .../tinymce/plugins/wpdialogs/js/popup.dev.js | 432 - .../js/tinymce/plugins/wpdialogs/js/popup.js | 433 +- .../tinymce/plugins/wpdialogs/js/popup.min.js | 1 + .../plugins/wpdialogs/js/wpdialog.dev.js | 28 - .../tinymce/plugins/wpdialogs/js/wpdialog.js | 29 +- .../plugins/wpdialogs/js/wpdialog.min.js | 1 + .../plugins/wpeditimage/css/editimage.css | 64 +- .../plugins/wpeditimage/editimage.html | 9 +- .../plugins/wpeditimage/editor_plugin.js | 2 +- .../plugins/wpeditimage/editor_plugin_src.js | 207 +- .../plugins/wpeditimage/img/delete-2x.png | Bin 0 -> 5064 bytes .../plugins/wpeditimage/img/delete.png | Bin 1638 -> 1386 bytes .../plugins/wpeditimage/img/image-2x.png | Bin 0 -> 2687 bytes .../tinymce/plugins/wpeditimage/img/image.png | Bin 3701 -> 946 bytes .../plugins/wpeditimage/js/editimage.dev.js | 613 - .../plugins/wpeditimage/js/editimage.js | 614 +- .../plugins/wpeditimage/js/editimage.min.js | 1 + .../wpfullscreen/css/wp-fullscreen.css | 26 +- .../plugins/wpfullscreen/editor_plugin.js | 2 +- .../plugins/wpfullscreen/editor_plugin_src.js | 58 +- .../plugins/wpgallery/editor_plugin.js | 2 +- .../plugins/wpgallery/editor_plugin_src.js | 69 +- .../plugins/wpgallery/img/delete-2x.png | Bin 0 -> 5064 bytes .../tinymce/plugins/wpgallery/img/delete.png | Bin 1638 -> 1386 bytes .../tinymce/plugins/wpgallery/img/edit-2x.png | Bin 0 -> 4924 bytes .../js/tinymce/plugins/wpgallery/img/edit.png | Bin 1799 -> 1590 bytes .../tinymce/plugins/wplink/editor_plugin.js | 2 +- .../plugins/wplink/editor_plugin_src.js | 7 +- .../tinymce/plugins/wpview/editor_plugin.js | 1 + .../plugins/wpview/editor_plugin_src.js | 188 + .../js/tinymce/themes/advanced/about.htm | 6 +- .../js/tinymce/themes/advanced/anchor.htm | 13 +- .../js/tinymce/themes/advanced/charmap.htm | 4 +- .../tinymce/themes/advanced/color_picker.htm | 18 +- .../themes/advanced/editor_template.js | 2 +- .../themes/advanced/editor_template_src.js | 220 +- .../js/tinymce/themes/advanced/image.htm | 17 +- .../tinymce/themes/advanced/img/gotmoxie.png | Bin 983 -> 892 bytes .../js/tinymce/themes/advanced/img/icons.gif | Bin 11790 -> 11982 bytes .../js/tinymce/themes/advanced/js/anchor.js | 25 +- .../themes/advanced/js/color_picker.js | 60 +- .../js/tinymce/themes/advanced/js/image.js | 6 +- .../js/tinymce/themes/advanced/js/link.js | 12 +- .../themes/advanced/js/source_editor.js | 32 +- .../js/tinymce/themes/advanced/link.htm | 19 +- .../js/tinymce/themes/advanced/shortcuts.htm | 2 +- .../themes/advanced/skins/default/dialog.css | 5 +- .../themes/advanced/skins/default/ui.css | 7 +- .../advanced/skins/highcontrast/dialog.css | 5 +- .../themes/advanced/skins/highcontrast/ui.css | 6 +- .../themes/advanced/skins/o2k7/dialog.css | 5 +- .../tinymce/themes/advanced/skins/o2k7/ui.css | 7 +- .../advanced/skins/wp_theme/content.css | 2 - .../themes/advanced/skins/wp_theme/dialog.css | 43 +- .../advanced/skins/wp_theme/img/embedded.png | Bin 28741 -> 27345 bytes .../advanced/skins/wp_theme/img/gallery.png | Bin 27676 -> 26240 bytes .../advanced/skins/wp_theme/img/page_bug.gif | Bin 180 -> 176 bytes .../advanced/skins/wp_theme/img/tabs.gif | Bin 1326 -> 1322 bytes .../themes/advanced/skins/wp_theme/ui.css | 2 - .../tinymce/themes/advanced/source_editor.htm | 15 +- wp-includes/js/tinymce/tiny_mce.js | 2 +- wp-includes/js/tinymce/tiny_mce_popup.js | 2 +- wp-includes/js/tinymce/wp-mce-help.php | 195 +- wp-includes/js/tinymce/wp-tinymce-schema.js | 940 + wp-includes/js/tinymce/wp-tinymce.js.gz | Bin 101121 -> 115683 bytes wp-includes/js/tinymce/wp-tinymce.php | 3 +- wp-includes/js/tw-sack.dev.js | 193 - wp-includes/js/tw-sack.js | 194 +- wp-includes/js/tw-sack.min.js | 1 + wp-includes/js/underscore.min.js | 5 + .../utils.dev.js => wp-includes/js/utils.js | 0 .../utils.js => wp-includes/js/utils.min.js | 0 wp-includes/js/wp-ajax-response.dev.js | 64 - wp-includes/js/wp-ajax-response.js | 65 +- wp-includes/js/wp-ajax-response.min.js | 1 + wp-includes/js/wp-list-revisions.dev.js | 24 - wp-includes/js/wp-list-revisions.js | 25 +- wp-includes/js/wp-list-revisions.min.js | 1 + wp-includes/js/wp-lists.dev.js | 464 - wp-includes/js/wp-lists.js | 465 +- wp-includes/js/wp-lists.min.js | 1 + wp-includes/js/wp-pointer.dev.js | 281 - wp-includes/js/wp-pointer.js | 282 +- wp-includes/js/wp-pointer.min.js | 1 + wp-includes/js/wplink.dev.js | 593 - wp-includes/js/wplink.js | 594 +- wp-includes/js/wplink.min.js | 1 + wp-includes/kses.php | 258 +- wp-includes/l10n.php | 30 +- wp-includes/link-template.php | 340 +- wp-includes/load.php | 42 +- wp-includes/media-template.php | 467 + wp-includes/media.php | 951 +- wp-includes/meta.php | 69 +- wp-includes/ms-blogs.php | 426 +- wp-includes/ms-default-constants.php | 29 +- wp-includes/ms-default-filters.php | 4 + wp-includes/ms-functions.php | 354 +- wp-includes/ms-load.php | 12 +- wp-includes/ms-settings.php | 2 + wp-includes/nav-menu-template.php | 25 +- wp-includes/nav-menu.php | 43 +- wp-includes/option.php | 26 +- wp-includes/pluggable-deprecated.php | 22 + wp-includes/pluggable.php | 73 +- wp-includes/plugin.php | 21 +- wp-includes/pomo/entry.php | 6 +- wp-includes/pomo/mo.php | 39 +- wp-includes/pomo/po.php | 33 +- wp-includes/pomo/streams.php | 40 +- wp-includes/pomo/translations.php | 18 +- wp-includes/post-template.php | 163 +- wp-includes/post.php | 810 +- wp-includes/query.php | 198 +- wp-includes/rewrite.php | 94 +- wp-includes/script-loader.php | 188 +- wp-includes/shortcodes.php | 3 +- wp-includes/taxonomy.php | 109 +- wp-includes/template-loader.php | 4 + wp-includes/template.php | 57 +- wp-includes/theme-compat/comments-popup.php | 4 +- wp-includes/theme-compat/comments.php | 2 +- wp-includes/theme.php | 81 +- wp-includes/update.php | 32 +- wp-includes/user.php | 196 +- wp-includes/vars.php | 3 +- wp-includes/version.php | 13 +- wp-includes/widgets.php | 8 +- wp-includes/wp-db.php | 198 +- wp-includes/wp-diff.php | 2 +- wp-load.php | 2 +- wp-login.php | 61 +- wp-mail.php | 2 +- wp-settings.php | 18 +- wp-signup.php | 8 +- xmlrpc.php | 2 +- 947 files changed, 83777 insertions(+), 74817 deletions(-) create mode 100644 wp-admin/css/color-picker-rtl.css create mode 100644 wp-admin/css/color-picker-rtl.min.css create mode 100644 wp-admin/css/color-picker.css create mode 100644 wp-admin/css/color-picker.min.css delete mode 100644 wp-admin/css/colors-classic.dev.css create mode 100644 wp-admin/css/colors-classic.min.css delete mode 100644 wp-admin/css/colors-fresh.dev.css create mode 100644 wp-admin/css/colors-fresh.min.css delete mode 100644 wp-admin/css/customize-controls-rtl.dev.css create mode 100644 wp-admin/css/customize-controls-rtl.min.css delete mode 100644 wp-admin/css/customize-controls.dev.css create mode 100644 wp-admin/css/customize-controls.min.css delete mode 100644 wp-admin/css/ie-rtl.dev.css create mode 100644 wp-admin/css/ie-rtl.min.css delete mode 100644 wp-admin/css/ie.dev.css create mode 100644 wp-admin/css/ie.min.css delete mode 100644 wp-admin/css/install.dev.css create mode 100644 wp-admin/css/install.min.css delete mode 100644 wp-admin/css/media-rtl.dev.css create mode 100644 wp-admin/css/media-rtl.min.css delete mode 100644 wp-admin/css/media.dev.css create mode 100644 wp-admin/css/media.min.css delete mode 100644 wp-admin/css/wp-admin-rtl.dev.css create mode 100644 wp-admin/css/wp-admin-rtl.min.css delete mode 100644 wp-admin/css/wp-admin.dev.css create mode 100644 wp-admin/css/wp-admin.min.css delete mode 100644 wp-admin/gears-manifest.php create mode 100644 wp-admin/images/align-center-2x.png create mode 100644 wp-admin/images/align-left-2x.png create mode 100644 wp-admin/images/align-none-2x.png create mode 100644 wp-admin/images/align-right-2x.png delete mode 100644 wp-admin/images/archive-link.png create mode 100644 wp-admin/images/arrows-2x.png create mode 100644 wp-admin/images/arrows-dark-2x.png create mode 100644 wp-admin/images/arrows-dark-vs-2x.png create mode 100644 wp-admin/images/arrows-vs-2x.png delete mode 100644 wp-admin/images/blue-grad.png create mode 100644 wp-admin/images/bubble_bg-2x.gif create mode 100644 wp-admin/images/bubble_bg-rtl-2x.gif delete mode 100644 wp-admin/images/button-grad-active.png delete mode 100644 wp-admin/images/button-grad.png create mode 100644 wp-admin/images/comment-grey-bubble-2x.png create mode 100644 wp-admin/images/date-button-2x.gif delete mode 100644 wp-admin/images/ed-bg-vs.gif delete mode 100644 wp-admin/images/ed-bg.gif delete mode 100644 wp-admin/images/fade-butt.png delete mode 100644 wp-admin/images/fav-arrow-rtl.gif delete mode 100644 wp-admin/images/fav-arrow.gif delete mode 100644 wp-admin/images/fav-vs.png delete mode 100644 wp-admin/images/fav.png delete mode 100644 wp-admin/images/gray-grad.png create mode 100644 wp-admin/images/imgedit-icons-2x.png create mode 100644 wp-admin/images/list-2x.png delete mode 100644 wp-admin/images/loading-publish.gif delete mode 100644 wp-admin/images/logo-ghost.png delete mode 100644 wp-admin/images/logo.gif create mode 100644 wp-admin/images/media-button-2x.png delete mode 100644 wp-admin/images/menu-arrow-frame-rtl.png delete mode 100644 wp-admin/images/menu-arrow-frame.png delete mode 100644 wp-admin/images/menu-arrows.gif delete mode 100644 wp-admin/images/menu-bits-rtl-vs.gif delete mode 100644 wp-admin/images/menu-bits-rtl.gif delete mode 100644 wp-admin/images/menu-bits-vs.gif delete mode 100644 wp-admin/images/menu-bits.gif delete mode 100644 wp-admin/images/menu-dark-rtl-vs.gif delete mode 100644 wp-admin/images/menu-dark-rtl.gif delete mode 100644 wp-admin/images/menu-dark-vs.gif delete mode 100644 wp-admin/images/menu-dark.gif create mode 100644 wp-admin/images/menu-vs-2x.png create mode 100644 wp-admin/images/press-this-2x.png delete mode 100644 wp-admin/images/required.gif create mode 100644 wp-admin/images/resize-2x.gif create mode 100644 wp-admin/images/resize-rtl-2x.gif delete mode 100644 wp-admin/images/screen-options-toggle-vs.gif delete mode 100644 wp-admin/images/screen-options-toggle.gif create mode 100644 wp-admin/images/screenshots/about-color-picker.png create mode 100644 wp-admin/images/screenshots/about-media.png create mode 100644 wp-admin/images/screenshots/about-retina.png create mode 100644 wp-admin/images/screenshots/about-twenty-twelve.png delete mode 100644 wp-admin/images/screenshots/captions-1.png delete mode 100644 wp-admin/images/screenshots/captions-2.png delete mode 100644 wp-admin/images/screenshots/flex-header-1.png delete mode 100644 wp-admin/images/screenshots/flex-header-2.png delete mode 100644 wp-admin/images/screenshots/flex-header-3.png delete mode 100644 wp-admin/images/screenshots/flex-header-media-library.png delete mode 100644 wp-admin/images/screenshots/theme-customizer.png delete mode 100644 wp-admin/images/screenshots/twitter-embed-1.png delete mode 100644 wp-admin/images/screenshots/twitter-embed-2.png create mode 100644 wp-admin/images/sort-2x.gif create mode 100644 wp-admin/images/stars-2x.png create mode 100644 wp-admin/images/stars-rtl-2x.png delete mode 100644 wp-admin/images/toggle-arrow-rtl.gif delete mode 100644 wp-admin/images/toggle-arrow.gif delete mode 100644 wp-admin/images/upload-classic.png delete mode 100644 wp-admin/images/upload-fresh.png create mode 100644 wp-admin/images/welcome-icons-2x.png create mode 100644 wp-admin/images/welcome-icons.png delete mode 100644 wp-admin/images/white-grad-active.png delete mode 100644 wp-admin/images/white-grad.png delete mode 100644 wp-admin/images/widgets-arrow-vs.gif delete mode 100644 wp-admin/images/widgets-arrow.gif create mode 100644 wp-admin/images/wp-logo-2x.png create mode 100644 wp-admin/images/wp-logo-vs-2x.png delete mode 100644 wp-admin/images/wpspin_dark.gif create mode 100644 wp-admin/images/wpspin_light-2x.gif create mode 100644 wp-admin/images/xit-2x.gif delete mode 100644 wp-admin/includes/manifest.php delete mode 100644 wp-admin/js/cat.dev.js create mode 100644 wp-admin/js/cat.min.js delete mode 100644 wp-admin/js/categories.dev.js create mode 100644 wp-admin/js/categories.min.js create mode 100644 wp-admin/js/color-picker.js create mode 100644 wp-admin/js/color-picker.min.js delete mode 100644 wp-admin/js/comment.dev.js create mode 100644 wp-admin/js/comment.min.js delete mode 100644 wp-admin/js/common.dev.js create mode 100644 wp-admin/js/common.min.js delete mode 100644 wp-admin/js/custom-background.dev.js create mode 100644 wp-admin/js/custom-background.min.js delete mode 100644 wp-admin/js/custom-fields.dev.js create mode 100644 wp-admin/js/custom-fields.min.js create mode 100644 wp-admin/js/custom-header.js delete mode 100644 wp-admin/js/customize-controls.dev.js create mode 100644 wp-admin/js/customize-controls.min.js delete mode 100644 wp-admin/js/dashboard.dev.js create mode 100644 wp-admin/js/dashboard.min.js delete mode 100644 wp-admin/js/edit-comments.dev.js create mode 100644 wp-admin/js/edit-comments.min.js delete mode 100644 wp-admin/js/editor.dev.js create mode 100644 wp-admin/js/editor.min.js delete mode 100644 wp-admin/js/gallery.dev.js create mode 100644 wp-admin/js/gallery.min.js delete mode 100644 wp-admin/js/image-edit.dev.js create mode 100644 wp-admin/js/image-edit.min.js delete mode 100644 wp-admin/js/inline-edit-post.dev.js create mode 100644 wp-admin/js/inline-edit-post.min.js delete mode 100644 wp-admin/js/inline-edit-tax.dev.js create mode 100644 wp-admin/js/inline-edit-tax.min.js create mode 100644 wp-admin/js/iris.min.js delete mode 100644 wp-admin/js/link.dev.js create mode 100644 wp-admin/js/link.min.js delete mode 100644 wp-admin/js/media-gallery.dev.js create mode 100644 wp-admin/js/media-gallery.min.js delete mode 100644 wp-admin/js/media-upload.dev.js create mode 100644 wp-admin/js/media-upload.min.js delete mode 100644 wp-admin/js/media.dev.js create mode 100644 wp-admin/js/media.min.js delete mode 100644 wp-admin/js/nav-menu.dev.js create mode 100644 wp-admin/js/nav-menu.min.js delete mode 100644 wp-admin/js/password-strength-meter.dev.js create mode 100644 wp-admin/js/password-strength-meter.min.js delete mode 100644 wp-admin/js/plugin-install.dev.js create mode 100644 wp-admin/js/plugin-install.min.js delete mode 100644 wp-admin/js/post.dev.js create mode 100644 wp-admin/js/post.min.js delete mode 100644 wp-admin/js/postbox.dev.js create mode 100644 wp-admin/js/postbox.min.js delete mode 100644 wp-admin/js/set-post-thumbnail.dev.js create mode 100644 wp-admin/js/set-post-thumbnail.min.js delete mode 100644 wp-admin/js/tags.dev.js create mode 100644 wp-admin/js/tags.min.js delete mode 100644 wp-admin/js/theme-preview.dev.js create mode 100644 wp-admin/js/theme-preview.min.js delete mode 100644 wp-admin/js/theme.dev.js create mode 100644 wp-admin/js/theme.min.js delete mode 100644 wp-admin/js/user-profile.dev.js create mode 100644 wp-admin/js/user-profile.min.js delete mode 100644 wp-admin/js/user-suggest.dev.js create mode 100644 wp-admin/js/user-suggest.min.js delete mode 100644 wp-admin/js/widgets.dev.js create mode 100644 wp-admin/js/widgets.min.js delete mode 100644 wp-admin/js/word-count.dev.js create mode 100644 wp-admin/js/word-count.min.js delete mode 100644 wp-admin/js/wp-fullscreen.dev.js create mode 100644 wp-admin/js/wp-fullscreen.min.js delete mode 100644 wp-admin/js/xfn.dev.js create mode 100644 wp-admin/js/xfn.min.js delete mode 100644 wp-admin/options-privacy.php delete mode 100644 wp-app.php delete mode 100644 wp-content/themes/twentyten/404.php delete mode 100644 wp-content/themes/twentyten/archive.php delete mode 100644 wp-content/themes/twentyten/attachment.php delete mode 100644 wp-content/themes/twentyten/author.php delete mode 100644 wp-content/themes/twentyten/category.php delete mode 100644 wp-content/themes/twentyten/comments.php delete mode 100644 wp-content/themes/twentyten/editor-style-rtl.css delete mode 100644 wp-content/themes/twentyten/editor-style.css delete mode 100644 wp-content/themes/twentyten/footer.php delete mode 100644 wp-content/themes/twentyten/functions.php delete mode 100644 wp-content/themes/twentyten/header.php delete mode 100644 wp-content/themes/twentyten/images/headers/berries-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/berries.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/cherryblossoms-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/cherryblossoms.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/concave-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/concave.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/fern-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/fern.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/forestfloor-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/forestfloor.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/inkwell-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/inkwell.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/path-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/path.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/sunset-thumbnail.jpg delete mode 100644 wp-content/themes/twentyten/images/headers/sunset.jpg delete mode 100644 wp-content/themes/twentyten/images/wordpress.png delete mode 100644 wp-content/themes/twentyten/index.php delete mode 100644 wp-content/themes/twentyten/languages/twentyten.pot delete mode 100644 wp-content/themes/twentyten/license.txt delete mode 100644 wp-content/themes/twentyten/loop-attachment.php delete mode 100644 wp-content/themes/twentyten/loop-page.php delete mode 100644 wp-content/themes/twentyten/loop-single.php delete mode 100644 wp-content/themes/twentyten/loop.php delete mode 100644 wp-content/themes/twentyten/onecolumn-page.php delete mode 100644 wp-content/themes/twentyten/page.php delete mode 100644 wp-content/themes/twentyten/rtl.css delete mode 100644 wp-content/themes/twentyten/screenshot.png delete mode 100644 wp-content/themes/twentyten/search.php delete mode 100644 wp-content/themes/twentyten/sidebar-footer.php delete mode 100644 wp-content/themes/twentyten/sidebar.php delete mode 100644 wp-content/themes/twentyten/single.php delete mode 100644 wp-content/themes/twentyten/style.css delete mode 100644 wp-content/themes/twentyten/tag.php create mode 100644 wp-content/themes/twentytwelve/404.php create mode 100644 wp-content/themes/twentytwelve/archive.php create mode 100644 wp-content/themes/twentytwelve/author.php create mode 100644 wp-content/themes/twentytwelve/category.php create mode 100644 wp-content/themes/twentytwelve/comments.php create mode 100644 wp-content/themes/twentytwelve/content-aside.php create mode 100644 wp-content/themes/twentytwelve/content-image.php create mode 100644 wp-content/themes/twentytwelve/content-link.php create mode 100644 wp-content/themes/twentytwelve/content-none.php create mode 100644 wp-content/themes/twentytwelve/content-page.php create mode 100644 wp-content/themes/twentytwelve/content-quote.php create mode 100644 wp-content/themes/twentytwelve/content-status.php create mode 100644 wp-content/themes/twentytwelve/content.php create mode 100644 wp-content/themes/twentytwelve/css/ie.css create mode 100644 wp-content/themes/twentytwelve/editor-style-rtl.css create mode 100644 wp-content/themes/twentytwelve/editor-style.css create mode 100644 wp-content/themes/twentytwelve/footer.php create mode 100644 wp-content/themes/twentytwelve/functions.php create mode 100644 wp-content/themes/twentytwelve/header.php create mode 100644 wp-content/themes/twentytwelve/image.php create mode 100644 wp-content/themes/twentytwelve/inc/custom-header.php create mode 100644 wp-content/themes/twentytwelve/index.php create mode 100644 wp-content/themes/twentytwelve/js/html5.js create mode 100644 wp-content/themes/twentytwelve/js/navigation.js create mode 100644 wp-content/themes/twentytwelve/js/theme-customizer.js create mode 100644 wp-content/themes/twentytwelve/languages/twentytwelve.pot create mode 100644 wp-content/themes/twentytwelve/page-templates/front-page.php create mode 100644 wp-content/themes/twentytwelve/page-templates/full-width.php create mode 100644 wp-content/themes/twentytwelve/page.php create mode 100644 wp-content/themes/twentytwelve/rtl.css create mode 100644 wp-content/themes/twentytwelve/screenshot.png create mode 100644 wp-content/themes/twentytwelve/search.php create mode 100644 wp-content/themes/twentytwelve/sidebar-front.php create mode 100644 wp-content/themes/twentytwelve/sidebar.php create mode 100644 wp-content/themes/twentytwelve/single.php create mode 100644 wp-content/themes/twentytwelve/style.css create mode 100644 wp-content/themes/twentytwelve/tag.php create mode 100644 wp-includes/SimplePie/Author.php create mode 100644 wp-includes/SimplePie/Cache.php create mode 100644 wp-includes/SimplePie/Cache/Base.php create mode 100644 wp-includes/SimplePie/Cache/DB.php create mode 100644 wp-includes/SimplePie/Cache/File.php create mode 100644 wp-includes/SimplePie/Cache/Memcache.php create mode 100644 wp-includes/SimplePie/Cache/MySQL.php create mode 100644 wp-includes/SimplePie/Caption.php create mode 100644 wp-includes/SimplePie/Category.php create mode 100644 wp-includes/SimplePie/Content/Type/Sniffer.php create mode 100644 wp-includes/SimplePie/Copyright.php create mode 100644 wp-includes/SimplePie/Core.php create mode 100644 wp-includes/SimplePie/Credit.php create mode 100644 wp-includes/SimplePie/Decode/HTML/Entities.php create mode 100644 wp-includes/SimplePie/Enclosure.php create mode 100644 wp-includes/SimplePie/Exception.php create mode 100644 wp-includes/SimplePie/File.php create mode 100644 wp-includes/SimplePie/HTTP/Parser.php create mode 100644 wp-includes/SimplePie/IRI.php create mode 100644 wp-includes/SimplePie/Item.php create mode 100644 wp-includes/SimplePie/Locator.php create mode 100644 wp-includes/SimplePie/Misc.php create mode 100644 wp-includes/SimplePie/Net/IPv6.php create mode 100644 wp-includes/SimplePie/Parse/Date.php create mode 100644 wp-includes/SimplePie/Parser.php create mode 100644 wp-includes/SimplePie/Rating.php create mode 100644 wp-includes/SimplePie/Registry.php create mode 100644 wp-includes/SimplePie/Restriction.php create mode 100644 wp-includes/SimplePie/Sanitize.php create mode 100644 wp-includes/SimplePie/Source.php create mode 100644 wp-includes/SimplePie/XML/Declaration/Parser.php create mode 100644 wp-includes/SimplePie/gzdecode.php delete mode 100644 wp-includes/class-wp-atom-server.php create mode 100644 wp-includes/class-wp-embed.php create mode 100644 wp-includes/class-wp-image-editor-gd.php create mode 100644 wp-includes/class-wp-image-editor-imagick.php create mode 100644 wp-includes/class-wp-image-editor.php delete mode 100644 wp-includes/css/admin-bar-rtl.dev.css create mode 100644 wp-includes/css/admin-bar-rtl.min.css delete mode 100644 wp-includes/css/admin-bar.dev.css create mode 100644 wp-includes/css/admin-bar.min.css create mode 100644 wp-includes/css/buttons.css create mode 100644 wp-includes/css/buttons.min.css delete mode 100644 wp-includes/css/editor.dev.css create mode 100644 wp-includes/css/editor.min.css delete mode 100644 wp-includes/css/jquery-ui-dialog.dev.css create mode 100644 wp-includes/css/jquery-ui-dialog.min.css create mode 100644 wp-includes/css/media-views-rtl.css create mode 100644 wp-includes/css/media-views-rtl.min.css create mode 100644 wp-includes/css/media-views.css create mode 100644 wp-includes/css/media-views.min.css delete mode 100644 wp-includes/css/wp-pointer.dev.css create mode 100644 wp-includes/css/wp-pointer.min.css create mode 100644 wp-includes/images/arrow-pointer-blue-2x.png create mode 100644 wp-includes/images/down_arrow-2x.gif create mode 100644 wp-includes/images/icon-pointer-flag-2x.png create mode 100644 wp-includes/images/rss-2x.png create mode 100644 wp-includes/images/toggle-arrow-2x.png delete mode 100644 wp-includes/images/upload.png create mode 100644 wp-includes/images/uploader-icons-2x.png create mode 100644 wp-includes/images/uploader-icons.png create mode 100644 wp-includes/images/wpicons-2x.png create mode 100644 wp-includes/images/wpmini-blue-2x.png create mode 100644 wp-includes/images/wpspin-2x.gif create mode 100644 wp-includes/images/wpspin.gif create mode 100644 wp-includes/images/xit-2x.gif delete mode 100644 wp-includes/js/admin-bar.dev.js create mode 100644 wp-includes/js/admin-bar.min.js delete mode 100644 wp-includes/js/autosave.dev.js create mode 100644 wp-includes/js/autosave.min.js create mode 100644 wp-includes/js/backbone.min.js delete mode 100644 wp-includes/js/colorpicker.dev.js create mode 100644 wp-includes/js/colorpicker.min.js delete mode 100644 wp-includes/js/comment-reply.dev.js create mode 100644 wp-includes/js/comment-reply.min.js delete mode 100644 wp-includes/js/customize-base.dev.js create mode 100644 wp-includes/js/customize-base.min.js delete mode 100644 wp-includes/js/customize-loader.dev.js create mode 100644 wp-includes/js/customize-loader.min.js delete mode 100644 wp-includes/js/customize-preview.dev.js create mode 100644 wp-includes/js/customize-preview.min.js delete mode 100644 wp-includes/js/hoverIntent.dev.js create mode 100644 wp-includes/js/hoverIntent.min.js delete mode 100644 wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js create mode 100644 wp-includes/js/imgareaselect/jquery.imgareaselect.min.js delete mode 100644 wp-includes/js/jcrop/jquery.Jcrop.css delete mode 100644 wp-includes/js/jcrop/jquery.Jcrop.dev.js delete mode 100644 wp-includes/js/jcrop/jquery.Jcrop.js create mode 100644 wp-includes/js/jcrop/jquery.Jcrop.min.css create mode 100644 wp-includes/js/jcrop/jquery.Jcrop.min.js delete mode 100644 wp-includes/js/jquery/jquery.color.dev.js delete mode 100644 wp-includes/js/jquery/jquery.color.js create mode 100644 wp-includes/js/jquery/jquery.color.min.js delete mode 100644 wp-includes/js/jquery/jquery.form.dev.js create mode 100644 wp-includes/js/jquery/jquery.form.min.js delete mode 100644 wp-includes/js/jquery/jquery.hotkeys.dev.js create mode 100644 wp-includes/js/jquery/jquery.hotkeys.min.js create mode 100644 wp-includes/js/jquery/jquery.masonry.min.js delete mode 100644 wp-includes/js/jquery/jquery.table-hotkeys.dev.js create mode 100644 wp-includes/js/jquery/jquery.table-hotkeys.min.js delete mode 100644 wp-includes/js/jquery/suggest.dev.js create mode 100644 wp-includes/js/jquery/suggest.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.blind.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.bounce.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.clip.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.core.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.drop.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.explode.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.fade.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.fold.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.highlight.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.pulsate.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.scale.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.shake.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.slide.min.js delete mode 100644 wp-includes/js/jquery/ui/jquery.effects.transfer.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-blind.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-bounce.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-clip.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-drop.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-explode.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-fade.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-fold.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-highlight.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-pulsate.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-scale.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-shake.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-slide.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect-transfer.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.effect.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.menu.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.spinner.min.js create mode 100644 wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js delete mode 100644 wp-includes/js/json2.dev.js create mode 100644 wp-includes/js/json2.min.js create mode 100644 wp-includes/js/mce-view.js create mode 100644 wp-includes/js/mce-view.min.js create mode 100644 wp-includes/js/media-editor.js create mode 100644 wp-includes/js/media-editor.min.js create mode 100644 wp-includes/js/media-models.js create mode 100644 wp-includes/js/media-models.min.js create mode 100644 wp-includes/js/media-views.js create mode 100644 wp-includes/js/media-views.min.js delete mode 100644 wp-includes/js/plupload/handlers.dev.js create mode 100644 wp-includes/js/plupload/handlers.min.js delete mode 100644 wp-includes/js/plupload/wp-plupload.dev.js create mode 100644 wp-includes/js/plupload/wp-plupload.min.js delete mode 100644 wp-includes/js/prototype.js delete mode 100644 wp-includes/js/quicktags.dev.js create mode 100644 wp-includes/js/quicktags.min.js delete mode 100644 wp-includes/js/scriptaculous/MIT-LICENSE delete mode 100644 wp-includes/js/scriptaculous/builder.js delete mode 100644 wp-includes/js/scriptaculous/controls.js delete mode 100644 wp-includes/js/scriptaculous/dragdrop.js delete mode 100644 wp-includes/js/scriptaculous/effects.js delete mode 100644 wp-includes/js/scriptaculous/scriptaculous.js delete mode 100644 wp-includes/js/scriptaculous/slider.js delete mode 100644 wp-includes/js/scriptaculous/sound.js delete mode 100644 wp-includes/js/scriptaculous/unittest.js delete mode 100644 wp-includes/js/scriptaculous/wp-scriptaculous.js create mode 100644 wp-includes/js/shortcode.js create mode 100644 wp-includes/js/shortcode.min.js delete mode 100644 wp-includes/js/swfupload/handlers.dev.js create mode 100644 wp-includes/js/swfupload/handlers.min.js create mode 100644 wp-includes/js/thickbox/tb-close-2x.png delete mode 100644 wp-includes/js/tinymce/plugins/wpdialogs/js/popup.dev.js create mode 100644 wp-includes/js/tinymce/plugins/wpdialogs/js/popup.min.js delete mode 100644 wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.dev.js create mode 100644 wp-includes/js/tinymce/plugins/wpdialogs/js/wpdialog.min.js create mode 100644 wp-includes/js/tinymce/plugins/wpeditimage/img/delete-2x.png create mode 100644 wp-includes/js/tinymce/plugins/wpeditimage/img/image-2x.png delete mode 100644 wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js create mode 100644 wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.min.js create mode 100644 wp-includes/js/tinymce/plugins/wpgallery/img/delete-2x.png create mode 100644 wp-includes/js/tinymce/plugins/wpgallery/img/edit-2x.png create mode 100644 wp-includes/js/tinymce/plugins/wpview/editor_plugin.js create mode 100644 wp-includes/js/tinymce/plugins/wpview/editor_plugin_src.js delete mode 100644 wp-includes/js/tinymce/themes/advanced/skins/wp_theme/ui.css create mode 100644 wp-includes/js/tinymce/wp-tinymce-schema.js delete mode 100644 wp-includes/js/tw-sack.dev.js create mode 100644 wp-includes/js/tw-sack.min.js create mode 100644 wp-includes/js/underscore.min.js rename wp-admin/js/utils.dev.js => wp-includes/js/utils.js (100%) rename wp-admin/js/utils.js => wp-includes/js/utils.min.js (100%) delete mode 100644 wp-includes/js/wp-ajax-response.dev.js create mode 100644 wp-includes/js/wp-ajax-response.min.js delete mode 100644 wp-includes/js/wp-list-revisions.dev.js create mode 100644 wp-includes/js/wp-list-revisions.min.js delete mode 100644 wp-includes/js/wp-lists.dev.js create mode 100644 wp-includes/js/wp-lists.min.js delete mode 100644 wp-includes/js/wp-pointer.dev.js create mode 100644 wp-includes/js/wp-pointer.min.js delete mode 100644 wp-includes/js/wplink.dev.js create mode 100644 wp-includes/js/wplink.min.js create mode 100644 wp-includes/media-template.php diff --git a/readme.html b/readme.html index d5998ba6..368674e2 100644 --- a/readme.html +++ b/readme.html @@ -8,7 +8,7 @@

WordPress -
Version 3.4.2 +
Version 3.5

Semantic Personal Publishing Platform

diff --git a/wp-activate.php b/wp-activate.php index d470772f..0d5f1dca 100644 --- a/wp-activate.php +++ b/wp-activate.php @@ -1,4 +1,12 @@ ").appendTo("head")})(jQuery),function(e,t){var n=function(e,t){return this instanceof n?this._init(e,t):new n(e,t)};n.fn=n.prototype={_color:0,_alpha:1,error:!1,_hsl:{h:0,s:0,l:0},_hsv:{h:0,s:0,v:0},_hSpace:"hsl",_init:function(e){var n="noop";switch(typeof e){case"object":return e.a!==t&&this.a(e.a),n=e.r!==t?"fromRgb":e.l!==t?"fromHsl":e.v!==t?"fromHsv":n,this[n](e);case"string":return this.fromCSS(e);case"number":return this.fromInt(parseInt(e,10))}return this},_error:function(){return this.error=!0,this},clone:function(){var e=new n(this.toInt()),t=["_alpha","_hSpace","_hsl","_hsv","error"];for(var r=t.length-1;r>=0;r--)e[t[r]]=this[t[r]];return e},setHSpace:function(e){return this._hSpace=e==="hsv"?e:"hsl",this},noop:function(){return this},fromCSS:function(e){var t,n,r=/^(rgb|hs(l|v))a?\(/;this.error=!1,e=e.replace(/^\s+/,"").replace(/\s+$/,"").replace(/;$/,"");if(e.match(r)&&e.match(/\)$/)){n=e.replace(/(\s|%)/g,"").replace(r,"").replace(/,?\);?$/,"").split(",");if(n.length<3)return this._error();if(n.length===4){this.a(parseFloat(n.pop()));if(this.error)return this}for(var i=n.length-1;i>=0;i--){n[i]=parseInt(n[i],10);if(isNaN(n[i]))return this._error()}return e.match(/^rgb/)?this.fromRgb({r:n[0],g:n[1],b:n[2]}):e.match(/^hsv/)?this.fromHsv({h:n[0],s:n[1],v:n[2]}):this.fromHsl({h:n[0],s:n[1],l:n[2]})}return this.fromHex(e)},fromRgb:function(e,n){return typeof e!="object"||e.r===t||e.g===t||e.b===t?this._error():(this.error=!1,this.fromInt(parseInt((e.r<<16)+(e.g<<8)+e.b,10),n))},fromHex:function(e){return e=e.replace(/^#/,"").replace(/^0x/,""),e.length===3&&(e=e[0]+e[0]+e[1]+e[1]+e[2]+e[2]),this.error=!/^[0-9A-F]{6}$/i.test(e),this.fromInt(parseInt(e,16))},fromHsl:function(e){var n,r,i,s,o,u,a,f;return typeof e!="object"||e.h===t||e.s===t||e.l===t?this._error():(this._hsl=e,this._hSpace="hsl",u=e.h/360,a=e.s/100,f=e.l/100,a===0?n=r=i=f:(s=f<.5?f*(1+a):f+a-f*a,o=2*f-s,n=this.hue2rgb(o,s,u+1/3),r=this.hue2rgb(o,s,u),i=this.hue2rgb(o,s,u-1/3)),this.fromRgb({r:n*255,g:r*255,b:i*255},!0))},fromHsv:function(e){var n,r,i,s,o,u,a,f,l,c,h;if(typeof e!="object"||e.h===t||e.s===t||e.v===t)return this._error();this._hsv=e,this._hSpace="hsv",n=e.h/360,r=e.s/100,i=e.v/100,a=Math.floor(n*6),f=n*6-a,l=i*(1-r),c=i*(1-f*r),h=i*(1-(1-f)*r);switch(a%6){case 0:s=i,o=h,u=l;break;case 1:s=c,o=i,u=l;break;case 2:s=l,o=i,u=h;break;case 3:s=l,o=c,u=i;break;case 4:s=h,o=l,u=i;break;case 5:s=i,o=l,u=c}return this.fromRgb({r:s*255,g:o*255,b:u*255},!0)},fromInt:function(e,n){return this._color=parseInt(e,10),isNaN(this._color)&&(this._color=0),this._color>16777215?this._color=16777215:this._color<0&&(this._color=0),n===t&&(this._hsv.h=this._hsv.s=this._hsl.h=this._hsl.s=0),this},hue2rgb:function(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+(t-e)*6*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e},toString:function(){var e=parseInt(this._color,10).toString(16);if(this.error)return"";if(e.length<6)for(var t=6-e.length-1;t>=0;t--)e="0"+e;return"#"+e},toCSS:function(e,t){e=e||"hex",t=parseFloat(t||this._alpha);switch(e){case"rgb":case"rgba":var n=this.toRgb();return t<1?"rgba( "+n.r+", "+n.g+", "+n.b+", "+t+" )":"rgb( "+n.r+", "+n.g+", "+n.b+" )";case"hsl":case"hsla":var r=this.toHsl();return t<1?"hsla( "+r.h+", "+r.s+"%, "+r.l+"%, "+t+" )":"hsl( "+r.h+", "+r.s+"%, "+r.l+"% )";default:return this.toString()}},toRgb:function(){return{r:255&this._color>>16,g:255&this._color>>8,b:255&this._color}},toHsl:function(){var e=this.toRgb(),t=e.r/255,n=e.g/255,r=e.b/255,i=Math.max(t,n,r),s=Math.min(t,n,r),o,u,a=(i+s)/2;if(i===s)o=u=0;else{var f=i-s;u=a>.5?f/(2-i-s):f/(i+s);switch(i){case t:o=(n-r)/f+(nr?(t+.05)/(r+.05):(r+.05)/(t+.05)}throw"getDistanceLuminosityFrom requires a Color object"},getMaxContrastColor:function(){var e=this.toLuminosity(),t=e>=.5?"000000":"ffffff";return new n(t)},getGrayscaleContrastingColor:function(e){if(!e)return this.getMaxContrastColor();var t=e<5?5:e,n=this.getMaxContrastColor();e=n.getDistanceLuminosityFrom(this);if(e<=t)return n;var r=0===n.toInt()?1:-1;while(e>t)n=n.incrementLightness(r),e=n.getDistanceLuminosityFrom(this);return n},getReadableContrastingColor:function(e,r){if(!e instanceof n)return this;var i=r===t?5:r,s=e.getDistanceLuminosityFrom(this),o=e.getMaxContrastColor(),u=o.getDistanceLuminosityFrom(e);if(u<=i)return o;if(s>=i)return this;var a=0===o.toInt()?-1:1;while(sn.range[1]?n.range[1]:r),s[e]=r,this._spaceFunc("from",n.space,s))}},_spaceFunc:function(e,t,n){var r=t||this._hSpace,i=e+r.charAt(0).toUpperCase()+r.substr(1);return this[i](n)}};var r={h:{mod:360},s:{range:[0,100]},l:{space:"hsl",range:[0,100]},v:{space:"hsv",range:[0,100]},r:{space:"rgb",range:[0,255]},g:{space:"rgb",range:[0,255]},b:{space:"rgb",range:[0,255]}};for(var i in r)r.hasOwnProperty(i)&&(n.fn[i]=n.fn._partial(i));e.Color=n}(typeof exports=="object"&&exports||this); \ No newline at end of file diff --git a/wp-admin/js/link.dev.js b/wp-admin/js/link.dev.js deleted file mode 100644 index f8b4583d..00000000 --- a/wp-admin/js/link.dev.js +++ /dev/null @@ -1,67 +0,0 @@ -jQuery(document).ready( function($) { - - var newCat, noSyncChecks = false, syncChecks, catAddAfter; - - $('#link_name').focus(); - // postboxes - postboxes.add_postbox_toggles('link'); - - // category tabs - $('#category-tabs a').click(function(){ - var t = $(this).attr('href'); - $(this).parent().addClass('tabs').siblings('li').removeClass('tabs'); - $('.tabs-panel').hide(); - $(t).show(); - if ( '#categories-all' == t ) - deleteUserSetting('cats'); - else - setUserSetting('cats','pop'); - return false; - }); - if ( getUserSetting('cats') ) - $('#category-tabs a[href="#categories-pop"]').click(); - - // Ajax Cat - newCat = $('#newcat').one( 'focus', function() { $(this).val( '' ).removeClass( 'form-input-tip' ) } ); - $('#link-category-add-submit').click( function() { newCat.focus(); } ); - syncChecks = function() { - if ( noSyncChecks ) - return; - noSyncChecks = true; - var th = $(this), c = th.is(':checked'), id = th.val().toString(); - $('#in-link-category-' + id + ', #in-popular-category-' + id).prop( 'checked', c ); - noSyncChecks = false; - }; - - catAddAfter = function( r, s ) { - $(s.what + ' response_data', r).each( function() { - var t = $($(this).text()); - t.find( 'label' ).each( function() { - var th = $(this), val = th.find('input').val(), id = th.find('input')[0].id, name = $.trim( th.text() ), o; - $('#' + id).change( syncChecks ); - o = $( '' ).text( name ); - } ); - } ); - }; - - $('#categorychecklist').wpList( { - alt: '', - what: 'link-category', - response: 'category-ajax-response', - addAfter: catAddAfter - } ); - - $('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');}); - $('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');}); - if ( 'pop' == getUserSetting('cats') ) - $('a[href="#categories-pop"]').click(); - - $('#category-add-toggle').click( function() { - $(this).parents('div:first').toggleClass( 'wp-hidden-children' ); - $('#category-tabs a[href="#categories-all"]').click(); - $('#newcategory').focus(); - return false; - } ); - - $('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change(); -}); diff --git a/wp-admin/js/link.js b/wp-admin/js/link.js index 3f5433a4..f8b4583d 100644 --- a/wp-admin/js/link.js +++ b/wp-admin/js/link.js @@ -1 +1,67 @@ -jQuery(document).ready(function(c){var b,a=false,d,e;c("#link_name").focus();postboxes.add_postbox_toggles("link");c("#category-tabs a").click(function(){var f=c(this).attr("href");c(this).parent().addClass("tabs").siblings("li").removeClass("tabs");c(".tabs-panel").hide();c(f).show();if("#categories-all"==f){deleteUserSetting("cats")}else{setUserSetting("cats","pop")}return false});if(getUserSetting("cats")){c('#category-tabs a[href="#categories-pop"]').click()}b=c("#newcat").one("focus",function(){c(this).val("").removeClass("form-input-tip")});c("#link-category-add-submit").click(function(){b.focus()});d=function(){if(a){return}a=true;var f=c(this),h=f.is(":checked"),g=f.val().toString();c("#in-link-category-"+g+", #in-popular-category-"+g).prop("checked",h);a=false};e=function(g,f){c(f.what+" response_data",g).each(function(){var h=c(c(this).text());h.find("label").each(function(){var j=c(this),l=j.find("input").val(),m=j.find("input")[0].id,i=c.trim(j.text()),k;c("#"+m).change(d);k=c('').text(i)})})};c("#categorychecklist").wpList({alt:"",what:"link-category",response:"category-ajax-response",addAfter:e});c('a[href="#categories-all"]').click(function(){deleteUserSetting("cats")});c('a[href="#categories-pop"]').click(function(){setUserSetting("cats","pop")});if("pop"==getUserSetting("cats")){c('a[href="#categories-pop"]').click()}c("#category-add-toggle").click(function(){c(this).parents("div:first").toggleClass("wp-hidden-children");c('#category-tabs a[href="#categories-all"]').click();c("#newcategory").focus();return false});c(".categorychecklist :checkbox").change(d).filter(":checked").change()}); \ No newline at end of file +jQuery(document).ready( function($) { + + var newCat, noSyncChecks = false, syncChecks, catAddAfter; + + $('#link_name').focus(); + // postboxes + postboxes.add_postbox_toggles('link'); + + // category tabs + $('#category-tabs a').click(function(){ + var t = $(this).attr('href'); + $(this).parent().addClass('tabs').siblings('li').removeClass('tabs'); + $('.tabs-panel').hide(); + $(t).show(); + if ( '#categories-all' == t ) + deleteUserSetting('cats'); + else + setUserSetting('cats','pop'); + return false; + }); + if ( getUserSetting('cats') ) + $('#category-tabs a[href="#categories-pop"]').click(); + + // Ajax Cat + newCat = $('#newcat').one( 'focus', function() { $(this).val( '' ).removeClass( 'form-input-tip' ) } ); + $('#link-category-add-submit').click( function() { newCat.focus(); } ); + syncChecks = function() { + if ( noSyncChecks ) + return; + noSyncChecks = true; + var th = $(this), c = th.is(':checked'), id = th.val().toString(); + $('#in-link-category-' + id + ', #in-popular-category-' + id).prop( 'checked', c ); + noSyncChecks = false; + }; + + catAddAfter = function( r, s ) { + $(s.what + ' response_data', r).each( function() { + var t = $($(this).text()); + t.find( 'label' ).each( function() { + var th = $(this), val = th.find('input').val(), id = th.find('input')[0].id, name = $.trim( th.text() ), o; + $('#' + id).change( syncChecks ); + o = $( '' ).text( name ); + } ); + } ); + }; + + $('#categorychecklist').wpList( { + alt: '', + what: 'link-category', + response: 'category-ajax-response', + addAfter: catAddAfter + } ); + + $('a[href="#categories-all"]').click(function(){deleteUserSetting('cats');}); + $('a[href="#categories-pop"]').click(function(){setUserSetting('cats','pop');}); + if ( 'pop' == getUserSetting('cats') ) + $('a[href="#categories-pop"]').click(); + + $('#category-add-toggle').click( function() { + $(this).parents('div:first').toggleClass( 'wp-hidden-children' ); + $('#category-tabs a[href="#categories-all"]').click(); + $('#newcategory').focus(); + return false; + } ); + + $('.categorychecklist :checkbox').change( syncChecks ).filter( ':checked' ).change(); +}); diff --git a/wp-admin/js/link.min.js b/wp-admin/js/link.min.js new file mode 100644 index 00000000..3f5433a4 --- /dev/null +++ b/wp-admin/js/link.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function(c){var b,a=false,d,e;c("#link_name").focus();postboxes.add_postbox_toggles("link");c("#category-tabs a").click(function(){var f=c(this).attr("href");c(this).parent().addClass("tabs").siblings("li").removeClass("tabs");c(".tabs-panel").hide();c(f).show();if("#categories-all"==f){deleteUserSetting("cats")}else{setUserSetting("cats","pop")}return false});if(getUserSetting("cats")){c('#category-tabs a[href="#categories-pop"]').click()}b=c("#newcat").one("focus",function(){c(this).val("").removeClass("form-input-tip")});c("#link-category-add-submit").click(function(){b.focus()});d=function(){if(a){return}a=true;var f=c(this),h=f.is(":checked"),g=f.val().toString();c("#in-link-category-"+g+", #in-popular-category-"+g).prop("checked",h);a=false};e=function(g,f){c(f.what+" response_data",g).each(function(){var h=c(c(this).text());h.find("label").each(function(){var j=c(this),l=j.find("input").val(),m=j.find("input")[0].id,i=c.trim(j.text()),k;c("#"+m).change(d);k=c('').text(i)})})};c("#categorychecklist").wpList({alt:"",what:"link-category",response:"category-ajax-response",addAfter:e});c('a[href="#categories-all"]').click(function(){deleteUserSetting("cats")});c('a[href="#categories-pop"]').click(function(){setUserSetting("cats","pop")});if("pop"==getUserSetting("cats")){c('a[href="#categories-pop"]').click()}c("#category-add-toggle").click(function(){c(this).parents("div:first").toggleClass("wp-hidden-children");c('#category-tabs a[href="#categories-all"]').click();c("#newcategory").focus();return false});c(".categorychecklist :checkbox").change(d).filter(":checked").change()}); \ No newline at end of file diff --git a/wp-admin/js/media-gallery.dev.js b/wp-admin/js/media-gallery.dev.js deleted file mode 100644 index 38e4f7b4..00000000 --- a/wp-admin/js/media-gallery.dev.js +++ /dev/null @@ -1,25 +0,0 @@ -jQuery(function($){ - $( 'body' ).bind( 'click.wp-gallery', function(e){ - var target = $( e.target ), id, img_size; - - if ( target.hasClass( 'wp-set-header' ) ) { - ( window.dialogArguments || opener || parent || top ).location.href = target.data( 'location' ); - e.preventDefault(); - } else if ( target.hasClass( 'wp-set-background' ) ) { - id = target.data( 'attachment-id' ); - img_size = $( 'input[name="attachments[' + id + '][image-size]"]:checked').val(); - - jQuery.post(ajaxurl, { - action: 'set-background-image', - attachment_id: id, - size: img_size - }, function(){ - var win = window.dialogArguments || opener || parent || top; - win.tb_remove(); - win.location.reload(); - }); - - e.preventDefault(); - } - }); -}); diff --git a/wp-admin/js/media-gallery.js b/wp-admin/js/media-gallery.js index 81e51131..38e4f7b4 100644 --- a/wp-admin/js/media-gallery.js +++ b/wp-admin/js/media-gallery.js @@ -1 +1,25 @@ -jQuery(function(a){a("body").bind("click.wp-gallery",function(d){var c=a(d.target),f,b;if(c.hasClass("wp-set-header")){(window.dialogArguments||opener||parent||top).location.href=c.data("location");d.preventDefault()}else{if(c.hasClass("wp-set-background")){f=c.data("attachment-id");b=a('input[name="attachments['+f+'][image-size]"]:checked').val();jQuery.post(ajaxurl,{action:"set-background-image",attachment_id:f,size:b},function(){var e=window.dialogArguments||opener||parent||top;e.tb_remove();e.location.reload()});d.preventDefault()}}})}); \ No newline at end of file +jQuery(function($){ + $( 'body' ).bind( 'click.wp-gallery', function(e){ + var target = $( e.target ), id, img_size; + + if ( target.hasClass( 'wp-set-header' ) ) { + ( window.dialogArguments || opener || parent || top ).location.href = target.data( 'location' ); + e.preventDefault(); + } else if ( target.hasClass( 'wp-set-background' ) ) { + id = target.data( 'attachment-id' ); + img_size = $( 'input[name="attachments[' + id + '][image-size]"]:checked').val(); + + jQuery.post(ajaxurl, { + action: 'set-background-image', + attachment_id: id, + size: img_size + }, function(){ + var win = window.dialogArguments || opener || parent || top; + win.tb_remove(); + win.location.reload(); + }); + + e.preventDefault(); + } + }); +}); diff --git a/wp-admin/js/media-gallery.min.js b/wp-admin/js/media-gallery.min.js new file mode 100644 index 00000000..81e51131 --- /dev/null +++ b/wp-admin/js/media-gallery.min.js @@ -0,0 +1 @@ +jQuery(function(a){a("body").bind("click.wp-gallery",function(d){var c=a(d.target),f,b;if(c.hasClass("wp-set-header")){(window.dialogArguments||opener||parent||top).location.href=c.data("location");d.preventDefault()}else{if(c.hasClass("wp-set-background")){f=c.data("attachment-id");b=a('input[name="attachments['+f+'][image-size]"]:checked').val();jQuery.post(ajaxurl,{action:"set-background-image",attachment_id:f,size:b},function(){var e=window.dialogArguments||opener||parent||top;e.tb_remove();e.location.reload()});d.preventDefault()}}})}); \ No newline at end of file diff --git a/wp-admin/js/media-upload.dev.js b/wp-admin/js/media-upload.dev.js deleted file mode 100644 index 9b998ff2..00000000 --- a/wp-admin/js/media-upload.dev.js +++ /dev/null @@ -1,88 +0,0 @@ -// send html to the post editor - -var wpActiveEditor; - -function send_to_editor(h) { - var ed, mce = typeof(tinymce) != 'undefined', qt = typeof(QTags) != 'undefined'; - - if ( !wpActiveEditor ) { - if ( mce && tinymce.activeEditor ) { - ed = tinymce.activeEditor; - wpActiveEditor = ed.id; - } else if ( !qt ) { - return false; - } - } else if ( mce ) { - if ( tinymce.activeEditor && (tinymce.activeEditor.id == 'mce_fullscreen' || tinymce.activeEditor.id == 'wp_mce_fullscreen') ) - ed = tinymce.activeEditor; - else - ed = tinymce.get(wpActiveEditor); - } - - if ( ed && !ed.isHidden() ) { - // restore caret position on IE - if ( tinymce.isIE && ed.windowManager.insertimagebookmark ) - ed.selection.moveToBookmark(ed.windowManager.insertimagebookmark); - - if ( h.indexOf('[caption') === 0 ) { - if ( ed.wpSetImgCaption ) - h = ed.wpSetImgCaption(h); - } else if ( h.indexOf('[gallery') === 0 ) { - if ( ed.plugins.wpgallery ) - h = ed.plugins.wpgallery._do_gallery(h); - } else if ( h.indexOf('[embed') === 0 ) { - if ( ed.plugins.wordpress ) - h = ed.plugins.wordpress._setEmbed(h); - } - - ed.execCommand('mceInsertContent', false, h); - } else if ( qt ) { - QTags.insertContent(h); - } else { - document.getElementById(wpActiveEditor).value += h; - } - - try{tb_remove();}catch(e){}; -} - -// thickbox settings -var tb_position; -(function($) { - tb_position = function() { - var tbWindow = $('#TB_window'), width = $(window).width(), H = $(window).height(), W = ( 720 < width ) ? 720 : width, adminbar_height = 0; - - if ( $('body.admin-bar').length ) - adminbar_height = 28; - - if ( tbWindow.size() ) { - tbWindow.width( W - 50 ).height( H - 45 - adminbar_height ); - $('#TB_iframeContent').width( W - 50 ).height( H - 75 - adminbar_height ); - tbWindow.css({'margin-left': '-' + parseInt((( W - 50 ) / 2),10) + 'px'}); - if ( typeof document.body.style.maxWidth != 'undefined' ) - tbWindow.css({'top': 20 + adminbar_height + 'px','margin-top':'0'}); - }; - - return $('a.thickbox').each( function() { - var href = $(this).attr('href'); - if ( ! href ) return; - href = href.replace(/&width=[0-9]+/g, ''); - href = href.replace(/&height=[0-9]+/g, ''); - $(this).attr( 'href', href + '&width=' + ( W - 80 ) + '&height=' + ( H - 85 - adminbar_height ) ); - }); - }; - - $(window).resize(function(){ tb_position(); }); - - // store caret position in IE - $(document).ready(function($){ - $('a.thickbox').click(function(){ - var ed; - - if ( typeof(tinymce) != 'undefined' && tinymce.isIE && ( ed = tinymce.get(wpActiveEditor) ) && !ed.isHidden() ) { - ed.focus(); - ed.windowManager.insertimagebookmark = ed.selection.getBookmark(); - } - }); - }); - -})(jQuery); diff --git a/wp-admin/js/media-upload.js b/wp-admin/js/media-upload.js index 7d1b9bee..9fc2e819 100644 --- a/wp-admin/js/media-upload.js +++ b/wp-admin/js/media-upload.js @@ -1 +1,88 @@ -var wpActiveEditor;function send_to_editor(c){var b,a=typeof(tinymce)!="undefined",f=typeof(QTags)!="undefined";if(!wpActiveEditor){if(a&&tinymce.activeEditor){b=tinymce.activeEditor;wpActiveEditor=b.id}else{if(!f){return false}}}else{if(a){if(tinymce.activeEditor&&(tinymce.activeEditor.id=="mce_fullscreen"||tinymce.activeEditor.id=="wp_mce_fullscreen")){b=tinymce.activeEditor}else{b=tinymce.get(wpActiveEditor)}}}if(b&&!b.isHidden()){if(tinymce.isIE&&b.windowManager.insertimagebookmark){b.selection.moveToBookmark(b.windowManager.insertimagebookmark)}if(c.indexOf("[caption")===0){if(b.wpSetImgCaption){c=b.wpSetImgCaption(c)}}else{if(c.indexOf("[gallery")===0){if(b.plugins.wpgallery){c=b.plugins.wpgallery._do_gallery(c)}}else{if(c.indexOf("[embed")===0){if(b.plugins.wordpress){c=b.plugins.wordpress._setEmbed(c)}}}}b.execCommand("mceInsertContent",false,c)}else{if(f){QTags.insertContent(c)}else{document.getElementById(wpActiveEditor).value+=c}}try{tb_remove()}catch(d){}}var tb_position;(function(a){tb_position=function(){var f=a("#TB_window"),e=a(window).width(),d=a(window).height(),c=(720]*?>/g, '' ); - } - if ( er ) { - $('#find-posts-response').html(er); - } - } - }; - - $(document).ready(function() { - $('#find-posts-submit').click(function(e) { - if ( '' == $('#find-posts-response').html() ) - e.preventDefault(); - }); - $( '#find-posts .find-box-search :input' ).keypress( function( event ) { - if ( 13 == event.which ) { - findPosts.send(); - return false; - } - } ); - $( '#find-posts-search' ).click( findPosts.send ); - $( '#find-posts-close' ).click( findPosts.close ); - $('#doaction, #doaction2').click(function(e){ - $('select[name^="action"]').each(function(){ - if ( $(this).val() == 'attach' ) { - e.preventDefault(); - findPosts.open(); - } - }); - }); - }); -})(jQuery); diff --git a/wp-admin/js/media.js b/wp-admin/js/media.js index 2fe5c0f9..b4ed0fb6 100644 --- a/wp-admin/js/media.js +++ b/wp-admin/js/media.js @@ -1 +1,124 @@ -var findPosts;(function(a){findPosts={open:function(d,c){var b=document.documentElement.scrollTop||a(document).scrollTop();if(d&&c){a("#affected").attr("name",d).val(c)}a("#find-posts").show().draggable({handle:"#find-posts-head"}).css({top:b+50+"px",left:"50%",marginLeft:"-250px"});a("#find-posts-input").focus().keyup(function(f){if(f.which==27){findPosts.close()}});return false},close:function(){a("#find-posts-response").html("");a("#find-posts").draggable("destroy").hide()},send:function(){var b={ps:a("#find-posts-input").val(),action:"find_posts",_ajax_nonce:a("#_ajax_nonce").val(),post_type:a('input[name="find-posts-what"]:checked').val()};a.ajax({type:"POST",url:ajaxurl,data:b,success:function(c){findPosts.show(c)},error:function(c){findPosts.error(c)}})},show:function(b){if(typeof(b)=="string"){this.error({responseText:b});return}var c=wpAjax.parseAjaxResponse(b);if(c.errors){this.error({responseText:wpAjax.broken})}c=c.responses[0];a("#find-posts-response").html(c.data)},error:function(b){var c=b.statusText;if(b.responseText){c=b.responseText.replace(/<.[^<>]*?>/g,"")}if(c){a("#find-posts-response").html(c)}}};a(document).ready(function(){a("#find-posts-submit").click(function(b){if(""==a("#find-posts-response").html()){b.preventDefault()}});a("#find-posts .find-box-search :input").keypress(function(b){if(13==b.which){findPosts.send();return false}});a("#find-posts-search").click(findPosts.send);a("#find-posts-close").click(findPosts.close);a("#doaction, #doaction2").click(function(b){a('select[name^="action"]').each(function(){if(a(this).val()=="attach"){b.preventDefault();findPosts.open()}})})})})(jQuery); \ No newline at end of file + +var findPosts; +(function($){ + findPosts = { + open : function(af_name, af_val) { + var st = document.documentElement.scrollTop || $(document).scrollTop(), + overlay = $( '.ui-find-overlay' ); + + if ( overlay.length == 0 ) { + $( 'body' ).append( '
' ); + findPosts.overlay(); + } + + overlay.show(); + + if ( af_name && af_val ) { + $('#affected').attr('name', af_name).val(af_val); + } + $('#find-posts').show().draggable({ + handle: '#find-posts-head' + }).css({'top':st + 50 + 'px','left':'50%','marginLeft':'-328px'}); + + $('#find-posts-input').focus().keyup(function(e){ + if (e.which == 27) { findPosts.close(); } // close on Escape + }); + + // Pull some results up by default + findPosts.send(); + + return false; + }, + + close : function() { + $('#find-posts-response').html(''); + $('#find-posts').draggable('destroy').hide(); + $( '.ui-find-overlay' ).hide(); + }, + + overlay : function() { + $( '.ui-find-overlay' ).css( + { 'z-index': '999', 'width': $( document ).width() + 'px', 'height': $( document ).height() + 'px' } + ).on('click', function () { + findPosts.close(); + }); + }, + + send : function() { + var post = { + ps: $('#find-posts-input').val(), + action: 'find_posts', + _ajax_nonce: $('#_ajax_nonce').val() + }, + spinner = $( '.find-box-search .spinner' ); + + spinner.show(); + + $.ajax({ + type : 'POST', + url : ajaxurl, + data : post, + success : function(x) { findPosts.show(x); spinner.hide(); }, + error : function(r) { findPosts.error(r); spinner.hide(); } + }); + }, + + show : function(x) { + + if ( typeof(x) == 'string' ) { + this.error({'responseText': x}); + return; + } + + var r = wpAjax.parseAjaxResponse(x); + + if ( r.errors ) { + this.error({'responseText': wpAjax.broken}); + } + r = r.responses[0]; + $('#find-posts-response').html(r.data); + + // Enable whole row to be clicked + $( '.found-posts td' ).on( 'click', function () { + $( this ).parent().find( '.found-radio input' ).prop( 'checked', true ); + }); + }, + + error : function(r) { + var er = r.statusText; + + if ( r.responseText ) { + er = r.responseText.replace( /<.[^<>]*?>/g, '' ); + } + if ( er ) { + $('#find-posts-response').html(er); + } + } + }; + + $(document).ready(function() { + $('#find-posts-submit').click(function(e) { + if ( '' == $('#find-posts-response').html() ) + e.preventDefault(); + }); + $( '#find-posts .find-box-search :input' ).keypress( function( event ) { + if ( 13 == event.which ) { + findPosts.send(); + return false; + } + } ); + $( '#find-posts-search' ).click( findPosts.send ); + $( '#find-posts-close' ).click( findPosts.close ); + $('#doaction, #doaction2').click(function(e){ + $('select[name^="action"]').each(function(){ + if ( $(this).val() == 'attach' ) { + e.preventDefault(); + findPosts.open(); + } + }); + }); + }); + $(window).resize(function() { + findPosts.overlay(); + }); +})(jQuery); diff --git a/wp-admin/js/media.min.js b/wp-admin/js/media.min.js new file mode 100644 index 00000000..1ddaf1a3 --- /dev/null +++ b/wp-admin/js/media.min.js @@ -0,0 +1 @@ +var findPosts;(function(a){findPosts={open:function(e,d){var c=document.documentElement.scrollTop||a(document).scrollTop(),b=a(".ui-find-overlay");if(b.length==0){a("body").append('
');findPosts.overlay()}b.show();if(e&&d){a("#affected").attr("name",e).val(d)}a("#find-posts").show().draggable({handle:"#find-posts-head"}).css({top:c+50+"px",left:"50%",marginLeft:"-328px"});a("#find-posts-input").focus().keyup(function(f){if(f.which==27){findPosts.close()}});findPosts.send();return false},close:function(){a("#find-posts-response").html("");a("#find-posts").draggable("destroy").hide();a(".ui-find-overlay").hide()},overlay:function(){a(".ui-find-overlay").css({"z-index":"999",width:a(document).width()+"px",height:a(document).height()+"px"}).on("click",function(){findPosts.close()})},send:function(){var b={ps:a("#find-posts-input").val(),action:"find_posts",_ajax_nonce:a("#_ajax_nonce").val()},c=a(".find-box-search .spinner");c.show();a.ajax({type:"POST",url:ajaxurl,data:b,success:function(d){findPosts.show(d);c.hide()},error:function(d){findPosts.error(d);c.hide()}})},show:function(b){if(typeof(b)=="string"){this.error({responseText:b});return}var c=wpAjax.parseAjaxResponse(b);if(c.errors){this.error({responseText:wpAjax.broken})}c=c.responses[0];a("#find-posts-response").html(c.data);a(".found-posts td").on("click",function(){a(this).parent().find(".found-radio input").prop("checked",true)})},error:function(b){var c=b.statusText;if(b.responseText){c=b.responseText.replace(/<.[^<>]*?>/g,"")}if(c){a("#find-posts-response").html(c)}}};a(document).ready(function(){a("#find-posts-submit").click(function(b){if(""==a("#find-posts-response").html()){b.preventDefault()}});a("#find-posts .find-box-search :input").keypress(function(b){if(13==b.which){findPosts.send();return false}});a("#find-posts-search").click(findPosts.send);a("#find-posts-close").click(findPosts.close);a("#doaction, #doaction2").click(function(b){a('select[name^="action"]').each(function(){if(a(this).val()=="attach"){b.preventDefault();findPosts.open()}})})});a(window).resize(function(){findPosts.overlay()})})(jQuery); \ No newline at end of file diff --git a/wp-admin/js/nav-menu.dev.js b/wp-admin/js/nav-menu.dev.js deleted file mode 100644 index 13668398..00000000 --- a/wp-admin/js/nav-menu.dev.js +++ /dev/null @@ -1,965 +0,0 @@ -/** - * WordPress Administration Navigation Menu - * Interface JS functions - * - * @version 2.0.0 - * - * @package WordPress - * @subpackage Administration - */ - -var wpNavMenu; - -(function($) { - - var api = wpNavMenu = { - - options : { - menuItemDepthPerLevel : 30, // Do not use directly. Use depthToPx and pxToDepth instead. - globalMaxDepth : 11 - }, - - menuList : undefined, // Set in init. - targetList : undefined, // Set in init. - menusChanged : false, - isRTL: !! ( 'undefined' != typeof isRtl && isRtl ), - negateIfRTL: ( 'undefined' != typeof isRtl && isRtl ) ? -1 : 1, - - // Functions that run on init. - init : function() { - api.menuList = $('#menu-to-edit'); - api.targetList = api.menuList; - - this.jQueryExtensions(); - - this.attachMenuEditListeners(); - - this.setupInputWithDefaultTitle(); - this.attachQuickSearchListeners(); - this.attachThemeLocationsListeners(); - - this.attachTabsPanelListeners(); - - this.attachUnsavedChangesListener(); - - if( api.menuList.length ) // If no menu, we're in the + tab. - this.initSortables(); - - this.initToggles(); - - this.initTabManager(); - }, - - jQueryExtensions : function() { - // jQuery extensions - $.fn.extend({ - menuItemDepth : function() { - var margin = api.isRTL ? this.eq(0).css('margin-right') : this.eq(0).css('margin-left'); - return api.pxToDepth( margin && -1 != margin.indexOf('px') ? margin.slice(0, -2) : 0 ); - }, - updateDepthClass : function(current, prev) { - return this.each(function(){ - var t = $(this); - prev = prev || t.menuItemDepth(); - $(this).removeClass('menu-item-depth-'+ prev ) - .addClass('menu-item-depth-'+ current ); - }); - }, - shiftDepthClass : function(change) { - return this.each(function(){ - var t = $(this), - depth = t.menuItemDepth(); - $(this).removeClass('menu-item-depth-'+ depth ) - .addClass('menu-item-depth-'+ (depth + change) ); - }); - }, - childMenuItems : function() { - var result = $(); - this.each(function(){ - var t = $(this), depth = t.menuItemDepth(), next = t.next(); - while( next.length && next.menuItemDepth() > depth ) { - result = result.add( next ); - next = next.next(); - } - }); - return result; - }, - updateParentMenuItemDBId : function() { - return this.each(function(){ - var item = $(this), - input = item.find('.menu-item-data-parent-id'), - depth = item.menuItemDepth(), - parent = item.prev(); - - if( depth == 0 ) { // Item is on the top level, has no parent - input.val(0); - } else { // Find the parent item, and retrieve its object id. - while( ! parent[0] || ! parent[0].className || -1 == parent[0].className.indexOf('menu-item') || ( parent.menuItemDepth() != depth - 1 ) ) - parent = parent.prev(); - input.val( parent.find('.menu-item-data-db-id').val() ); - } - }); - }, - hideAdvancedMenuItemFields : function() { - return this.each(function(){ - var that = $(this); - $('.hide-column-tog').not(':checked').each(function(){ - that.find('.field-' + $(this).val() ).addClass('hidden-field'); - }); - }); - }, - /** - * Adds selected menu items to the menu. - * - * @param jQuery metabox The metabox jQuery object. - */ - addSelectedToMenu : function(processMethod) { - if ( 0 == $('#menu-to-edit').length ) { - return false; - } - - return this.each(function() { - var t = $(this), menuItems = {}, - checkboxes = t.find('.tabs-panel-active .categorychecklist li input:checked'), - re = new RegExp('menu-item\\[(\[^\\]\]*)'); - - processMethod = processMethod || api.addMenuItemToBottom; - - // If no items are checked, bail. - if ( !checkboxes.length ) - return false; - - // Show the ajax spinner - t.find('img.waiting').show(); - - // Retrieve menu item data - $(checkboxes).each(function(){ - var t = $(this), - listItemDBIDMatch = re.exec( t.attr('name') ), - listItemDBID = 'undefined' == typeof listItemDBIDMatch[1] ? 0 : parseInt(listItemDBIDMatch[1], 10); - if ( this.className && -1 != this.className.indexOf('add-to-top') ) - processMethod = api.addMenuItemToTop; - menuItems[listItemDBID] = t.closest('li').getItemData( 'add-menu-item', listItemDBID ); - }); - - // Add the items - api.addItemToMenu(menuItems, processMethod, function(){ - // Deselect the items and hide the ajax spinner - checkboxes.removeAttr('checked'); - t.find('img.waiting').hide(); - }); - }); - }, - getItemData : function( itemType, id ) { - itemType = itemType || 'menu-item'; - - var itemData = {}, i, - fields = [ - 'menu-item-db-id', - 'menu-item-object-id', - 'menu-item-object', - 'menu-item-parent-id', - 'menu-item-position', - 'menu-item-type', - 'menu-item-title', - 'menu-item-url', - 'menu-item-description', - 'menu-item-attr-title', - 'menu-item-target', - 'menu-item-classes', - 'menu-item-xfn' - ]; - - if( !id && itemType == 'menu-item' ) { - id = this.find('.menu-item-data-db-id').val(); - } - - if( !id ) return itemData; - - this.find('input').each(function() { - var field; - i = fields.length; - while ( i-- ) { - if( itemType == 'menu-item' ) - field = fields[i] + '[' + id + ']'; - else if( itemType == 'add-menu-item' ) - field = 'menu-item[' + id + '][' + fields[i] + ']'; - - if ( - this.name && - field == this.name - ) { - itemData[fields[i]] = this.value; - } - } - }); - - return itemData; - }, - setItemData : function( itemData, itemType, id ) { // Can take a type, such as 'menu-item', or an id. - itemType = itemType || 'menu-item'; - - if( !id && itemType == 'menu-item' ) { - id = $('.menu-item-data-db-id', this).val(); - } - - if( !id ) return this; - - this.find('input').each(function() { - var t = $(this), field; - $.each( itemData, function( attr, val ) { - if( itemType == 'menu-item' ) - field = attr + '[' + id + ']'; - else if( itemType == 'add-menu-item' ) - field = 'menu-item[' + id + '][' + attr + ']'; - - if ( field == t.attr('name') ) { - t.val( val ); - } - }); - }); - return this; - } - }); - }, - - initToggles : function() { - // init postboxes - postboxes.add_postbox_toggles('nav-menus'); - - // adjust columns functions for menus UI - columns.useCheckboxesForHidden(); - columns.checked = function(field) { - $('.field-' + field).removeClass('hidden-field'); - } - columns.unchecked = function(field) { - $('.field-' + field).addClass('hidden-field'); - } - // hide fields - api.menuList.hideAdvancedMenuItemFields(); - }, - - initSortables : function() { - var currentDepth = 0, originalDepth, minDepth, maxDepth, - prev, next, prevBottom, nextThreshold, helperHeight, transport, - menuEdge = api.menuList.offset().left, - body = $('body'), maxChildDepth, - menuMaxDepth = initialMenuMaxDepth(); - - // Use the right edge if RTL. - menuEdge += api.isRTL ? api.menuList.width() : 0; - - api.menuList.sortable({ - handle: '.menu-item-handle', - placeholder: 'sortable-placeholder', - start: function(e, ui) { - var height, width, parent, children, tempHolder; - - // handle placement for rtl orientation - if ( api.isRTL ) - ui.item[0].style.right = 'auto'; - - transport = ui.item.children('.menu-item-transport'); - - // Set depths. currentDepth must be set before children are located. - originalDepth = ui.item.menuItemDepth(); - updateCurrentDepth(ui, originalDepth); - - // Attach child elements to parent - // Skip the placeholder - parent = ( ui.item.next()[0] == ui.placeholder[0] ) ? ui.item.next() : ui.item; - children = parent.childMenuItems(); - transport.append( children ); - - // Update the height of the placeholder to match the moving item. - height = transport.outerHeight(); - // If there are children, account for distance between top of children and parent - height += ( height > 0 ) ? (ui.placeholder.css('margin-top').slice(0, -2) * 1) : 0; - height += ui.helper.outerHeight(); - helperHeight = height; - height -= 2; // Subtract 2 for borders - ui.placeholder.height(height); - - // Update the width of the placeholder to match the moving item. - maxChildDepth = originalDepth; - children.each(function(){ - var depth = $(this).menuItemDepth(); - maxChildDepth = (depth > maxChildDepth) ? depth : maxChildDepth; - }); - width = ui.helper.find('.menu-item-handle').outerWidth(); // Get original width - width += api.depthToPx(maxChildDepth - originalDepth); // Account for children - width -= 2; // Subtract 2 for borders - ui.placeholder.width(width); - - // Update the list of menu items. - tempHolder = ui.placeholder.next(); - tempHolder.css( 'margin-top', helperHeight + 'px' ); // Set the margin to absorb the placeholder - ui.placeholder.detach(); // detach or jQuery UI will think the placeholder is a menu item - $(this).sortable( "refresh" ); // The children aren't sortable. We should let jQ UI know. - ui.item.after( ui.placeholder ); // reattach the placeholder. - tempHolder.css('margin-top', 0); // reset the margin - - // Now that the element is complete, we can update... - updateSharedVars(ui); - }, - stop: function(e, ui) { - var children, depthChange = currentDepth - originalDepth; - - // Return child elements to the list - children = transport.children().insertAfter(ui.item); - - // Update depth classes - if( depthChange != 0 ) { - ui.item.updateDepthClass( currentDepth ); - children.shiftDepthClass( depthChange ); - updateMenuMaxDepth( depthChange ); - } - // Register a change - api.registerChange(); - // Update the item data. - ui.item.updateParentMenuItemDBId(); - - // address sortable's incorrectly-calculated top in opera - ui.item[0].style.top = 0; - - // handle drop placement for rtl orientation - if ( api.isRTL ) { - ui.item[0].style.left = 'auto'; - ui.item[0].style.right = 0; - } - - // The width of the tab bar might have changed. Just in case. - api.refreshMenuTabs( true ); - }, - change: function(e, ui) { - // Make sure the placeholder is inside the menu. - // Otherwise fix it, or we're in trouble. - if( ! ui.placeholder.parent().hasClass('menu') ) - (prev.length) ? prev.after( ui.placeholder ) : api.menuList.prepend( ui.placeholder ); - - updateSharedVars(ui); - }, - sort: function(e, ui) { - var offset = ui.helper.offset(), - edge = api.isRTL ? offset.left + ui.helper.width() : offset.left, - depth = api.negateIfRTL * api.pxToDepth( edge - menuEdge ); - // Check and correct if depth is not within range. - // Also, if the dragged element is dragged upwards over - // an item, shift the placeholder to a child position. - if ( depth > maxDepth || offset.top < prevBottom ) depth = maxDepth; - else if ( depth < minDepth ) depth = minDepth; - - if( depth != currentDepth ) - updateCurrentDepth(ui, depth); - - // If we overlap the next element, manually shift downwards - if( nextThreshold && offset.top + helperHeight > nextThreshold ) { - next.after( ui.placeholder ); - updateSharedVars( ui ); - $(this).sortable( "refreshPositions" ); - } - } - }); - - function updateSharedVars(ui) { - var depth; - - prev = ui.placeholder.prev(); - next = ui.placeholder.next(); - - // Make sure we don't select the moving item. - if( prev[0] == ui.item[0] ) prev = prev.prev(); - if( next[0] == ui.item[0] ) next = next.next(); - - prevBottom = (prev.length) ? prev.offset().top + prev.height() : 0; - nextThreshold = (next.length) ? next.offset().top + next.height() / 3 : 0; - minDepth = (next.length) ? next.menuItemDepth() : 0; - - if( prev.length ) - maxDepth = ( (depth = prev.menuItemDepth() + 1) > api.options.globalMaxDepth ) ? api.options.globalMaxDepth : depth; - else - maxDepth = 0; - } - - function updateCurrentDepth(ui, depth) { - ui.placeholder.updateDepthClass( depth, currentDepth ); - currentDepth = depth; - } - - function initialMenuMaxDepth() { - if( ! body[0].className ) return 0; - var match = body[0].className.match(/menu-max-depth-(\d+)/); - return match && match[1] ? parseInt(match[1]) : 0; - } - - function updateMenuMaxDepth( depthChange ) { - var depth, newDepth = menuMaxDepth; - if ( depthChange === 0 ) { - return; - } else if ( depthChange > 0 ) { - depth = maxChildDepth + depthChange; - if( depth > menuMaxDepth ) - newDepth = depth; - } else if ( depthChange < 0 && maxChildDepth == menuMaxDepth ) { - while( ! $('.menu-item-depth-' + newDepth, api.menuList).length && newDepth > 0 ) - newDepth--; - } - // Update the depth class. - body.removeClass( 'menu-max-depth-' + menuMaxDepth ).addClass( 'menu-max-depth-' + newDepth ); - menuMaxDepth = newDepth; - } - }, - - attachMenuEditListeners : function() { - var that = this; - $('#update-nav-menu').bind('click', function(e) { - if ( e.target && e.target.className ) { - if ( -1 != e.target.className.indexOf('item-edit') ) { - return that.eventOnClickEditLink(e.target); - } else if ( -1 != e.target.className.indexOf('menu-save') ) { - return that.eventOnClickMenuSave(e.target); - } else if ( -1 != e.target.className.indexOf('menu-delete') ) { - return that.eventOnClickMenuDelete(e.target); - } else if ( -1 != e.target.className.indexOf('item-delete') ) { - return that.eventOnClickMenuItemDelete(e.target); - } else if ( -1 != e.target.className.indexOf('item-cancel') ) { - return that.eventOnClickCancelLink(e.target); - } - } - }); - $('#add-custom-links input[type="text"]').keypress(function(e){ - if ( e.keyCode === 13 ) { - e.preventDefault(); - $("#submit-customlinkdiv").click(); - } - }); - }, - - /** - * An interface for managing default values for input elements - * that is both JS and accessibility-friendly. - * - * Input elements that add the class 'input-with-default-title' - * will have their values set to the provided HTML title when empty. - */ - setupInputWithDefaultTitle : function() { - var name = 'input-with-default-title'; - - $('.' + name).each( function(){ - var $t = $(this), title = $t.attr('title'), val = $t.val(); - $t.data( name, title ); - - if( '' == val ) $t.val( title ); - else if ( title == val ) return; - else $t.removeClass( name ); - }).focus( function(){ - var $t = $(this); - if( $t.val() == $t.data(name) ) - $t.val('').removeClass( name ); - }).blur( function(){ - var $t = $(this); - if( '' == $t.val() ) - $t.addClass( name ).val( $t.data(name) ); - }); - }, - - attachThemeLocationsListeners : function() { - var loc = $('#nav-menu-theme-locations'), params = {}; - params['action'] = 'menu-locations-save'; - params['menu-settings-column-nonce'] = $('#menu-settings-column-nonce').val(); - loc.find('input[type="submit"]').click(function() { - loc.find('select').each(function() { - params[this.name] = $(this).val(); - }); - loc.find('.waiting').show(); - $.post( ajaxurl, params, function(r) { - loc.find('.waiting').hide(); - }); - return false; - }); - }, - - attachQuickSearchListeners : function() { - var searchTimer; - - $('.quick-search').keypress(function(e){ - var t = $(this); - - if( 13 == e.which ) { - api.updateQuickSearchResults( t ); - return false; - } - - if( searchTimer ) clearTimeout(searchTimer); - - searchTimer = setTimeout(function(){ - api.updateQuickSearchResults( t ); - }, 400); - }).attr('autocomplete','off'); - }, - - updateQuickSearchResults : function(input) { - var panel, params, - minSearchLength = 2, - q = input.val(); - - if( q.length < minSearchLength ) return; - - panel = input.parents('.tabs-panel'); - params = { - 'action': 'menu-quick-search', - 'response-format': 'markup', - 'menu': $('#menu').val(), - 'menu-settings-column-nonce': $('#menu-settings-column-nonce').val(), - 'q': q, - 'type': input.attr('name') - }; - - $('img.waiting', panel).show(); - - $.post( ajaxurl, params, function(menuMarkup) { - api.processQuickSearchQueryResponse(menuMarkup, params, panel); - }); - }, - - addCustomLink : function( processMethod ) { - var url = $('#custom-menu-item-url').val(), - label = $('#custom-menu-item-name').val(); - - processMethod = processMethod || api.addMenuItemToBottom; - - if ( '' == url || 'http://' == url ) - return false; - - // Show the ajax spinner - $('.customlinkdiv img.waiting').show(); - this.addLinkToMenu( url, label, processMethod, function() { - // Remove the ajax spinner - $('.customlinkdiv img.waiting').hide(); - // Set custom link form back to defaults - $('#custom-menu-item-name').val('').blur(); - $('#custom-menu-item-url').val('http://'); - }); - }, - - addLinkToMenu : function(url, label, processMethod, callback) { - processMethod = processMethod || api.addMenuItemToBottom; - callback = callback || function(){}; - - api.addItemToMenu({ - '-1': { - 'menu-item-type': 'custom', - 'menu-item-url': url, - 'menu-item-title': label - } - }, processMethod, callback); - }, - - addItemToMenu : function(menuItem, processMethod, callback) { - var menu = $('#menu').val(), - nonce = $('#menu-settings-column-nonce').val(); - - processMethod = processMethod || function(){}; - callback = callback || function(){}; - - params = { - 'action': 'add-menu-item', - 'menu': menu, - 'menu-settings-column-nonce': nonce, - 'menu-item': menuItem - }; - - $.post( ajaxurl, params, function(menuMarkup) { - var ins = $('#menu-instructions'); - processMethod(menuMarkup, params); - if( ! ins.hasClass('menu-instructions-inactive') && ins.siblings().length ) - ins.addClass('menu-instructions-inactive'); - callback(); - }); - }, - - /** - * Process the add menu item request response into menu list item. - * - * @param string menuMarkup The text server response of menu item markup. - * @param object req The request arguments. - */ - addMenuItemToBottom : function( menuMarkup, req ) { - $(menuMarkup).hideAdvancedMenuItemFields().appendTo( api.targetList ); - }, - - addMenuItemToTop : function( menuMarkup, req ) { - $(menuMarkup).hideAdvancedMenuItemFields().prependTo( api.targetList ); - }, - - attachUnsavedChangesListener : function() { - $('#menu-management input, #menu-management select, #menu-management, #menu-management textarea').change(function(){ - api.registerChange(); - }); - - if ( 0 != $('#menu-to-edit').length ) { - window.onbeforeunload = function(){ - if ( api.menusChanged ) - return navMenuL10n.saveAlert; - }; - } else { - // Make the post boxes read-only, as they can't be used yet - $('#menu-settings-column').find('input,select').prop('disabled', true).end().find('a').attr('href', '#').unbind('click'); - } - }, - - registerChange : function() { - api.menusChanged = true; - }, - - attachTabsPanelListeners : function() { - $('#menu-settings-column').bind('click', function(e) { - var selectAreaMatch, panelId, wrapper, items, - target = $(e.target); - - if ( target.hasClass('nav-tab-link') ) { - panelId = /#(.*)$/.exec(e.target.href); - if ( panelId && panelId[1] ) - panelId = panelId[1] - else - return false; - - wrapper = target.parents('.inside').first(); - - // upon changing tabs, we want to uncheck all checkboxes - $('input', wrapper).removeAttr('checked'); - - $('.tabs-panel-active', wrapper).removeClass('tabs-panel-active').addClass('tabs-panel-inactive'); - $('#' + panelId, wrapper).removeClass('tabs-panel-inactive').addClass('tabs-panel-active'); - - $('.tabs', wrapper).removeClass('tabs'); - target.parent().addClass('tabs'); - - // select the search bar - $('.quick-search', wrapper).focus(); - - return false; - } else if ( target.hasClass('select-all') ) { - selectAreaMatch = /#(.*)$/.exec(e.target.href); - if ( selectAreaMatch && selectAreaMatch[1] ) { - items = $('#' + selectAreaMatch[1] + ' .tabs-panel-active .menu-item-title input'); - if( items.length === items.filter(':checked').length ) - items.removeAttr('checked'); - else - items.prop('checked', true); - return false; - } - } else if ( target.hasClass('submit-add-to-menu') ) { - api.registerChange(); - - if ( e.target.id && 'submit-customlinkdiv' == e.target.id ) - api.addCustomLink( api.addMenuItemToBottom ); - else if ( e.target.id && -1 != e.target.id.indexOf('submit-') ) - $('#' + e.target.id.replace(/submit-/, '')).addSelectedToMenu( api.addMenuItemToBottom ); - return false; - } else if ( target.hasClass('page-numbers') ) { - $.post( ajaxurl, e.target.href.replace(/.*\?/, '').replace(/action=([^&]*)/, '') + '&action=menu-get-metabox', - function( resp ) { - if ( -1 == resp.indexOf('replace-id') ) - return; - - var metaBoxData = $.parseJSON(resp), - toReplace = document.getElementById(metaBoxData['replace-id']), - placeholder = document.createElement('div'), - wrap = document.createElement('div'); - - if ( ! metaBoxData['markup'] || ! toReplace ) - return; - - wrap.innerHTML = metaBoxData['markup'] ? metaBoxData['markup'] : ''; - - toReplace.parentNode.insertBefore( placeholder, toReplace ); - placeholder.parentNode.removeChild( toReplace ); - - placeholder.parentNode.insertBefore( wrap, placeholder ); - - placeholder.parentNode.removeChild( placeholder ); - - } - ); - - return false; - } - }); - }, - - initTabManager : function() { - var fixed = $('.nav-tabs-wrapper'), - fluid = fixed.children('.nav-tabs'), - active = fluid.children('.nav-tab-active'), - tabs = fluid.children('.nav-tab'), - tabsWidth = 0, - fixedRight, fixedLeft, - arrowLeft, arrowRight, resizeTimer, css = {}, - marginFluid = api.isRTL ? 'margin-right' : 'margin-left', - marginFixed = api.isRTL ? 'margin-left' : 'margin-right', - msPerPx = 2; - - /** - * Refreshes the menu tabs. - * Will show and hide arrows where necessary. - * Scrolls to the active tab by default. - * - * @param savePosition {boolean} Optional. Prevents scrolling so - * that the current position is maintained. Default false. - **/ - api.refreshMenuTabs = function( savePosition ) { - var fixedWidth = fixed.width(), - margin = 0, css = {}; - fixedLeft = fixed.offset().left; - fixedRight = fixedLeft + fixedWidth; - - if( !savePosition ) - active.makeTabVisible(); - - // Prevent space from building up next to the last tab if there's more to show - if( tabs.last().isTabVisible() ) { - margin = fixed.width() - tabsWidth; - margin = margin > 0 ? 0 : margin; - css[marginFluid] = margin + 'px'; - fluid.animate( css, 100, "linear" ); - } - - // Show the arrows only when necessary - if( fixedWidth > tabsWidth ) - arrowLeft.add( arrowRight ).hide(); - else - arrowLeft.add( arrowRight ).show(); - } - - $.fn.extend({ - makeTabVisible : function() { - var t = this.eq(0), left, right, css = {}, shift = 0; - - if( ! t.length ) return this; - - left = t.offset().left; - right = left + t.outerWidth(); - - if( right > fixedRight ) - shift = fixedRight - right; - else if ( left < fixedLeft ) - shift = fixedLeft - left; - - if( ! shift ) return this; - - css[marginFluid] = "+=" + api.negateIfRTL * shift + 'px'; - fluid.animate( css, Math.abs( shift ) * msPerPx, "linear" ); - return this; - }, - isTabVisible : function() { - var t = this.eq(0), - left = t.offset().left, - right = left + t.outerWidth(); - return ( right <= fixedRight && left >= fixedLeft ) ? true : false; - } - }); - - // Find the width of all tabs - tabs.each(function(){ - tabsWidth += $(this).outerWidth(true); - }); - - // Set up fixed margin for overflow, unset padding - css['padding'] = 0; - css[marginFixed] = (-1 * tabsWidth) + 'px'; - fluid.css( css ); - - // Build tab navigation - arrowLeft = $(''); - arrowRight = $(''); - // Attach to the document - fixed.wrap('")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.rightu||a.bottomi&&a.rights&&a.bottom").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;ic&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i),j===!1?!1:(this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0,!0))},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);return this._slide(a,this._handleIndex,c),!1},_mouseStop:function(a){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;return this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e,this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};return this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c1){this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);return}if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;return Math.abs(c)*2>=b&&(d+=c>0?b:-b),parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.20"})})(jQuery); \ No newline at end of file +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r,i=this.options,s=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="",u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(i.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),i.range&&(i.range===!0&&(i.values||(i.values=[this._valueMin(),this._valueMin()]),i.values.length&&i.values.length!==2&&(i.values=[i.values[0],i.values[0]])),this.range=e("
").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(i.range==="min"||i.range==="max"?" ui-slider-range-"+i.range:""))),r=i.values&&i.values.length||1;for(t=s.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery); \ No newline at end of file diff --git a/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js b/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js index 593dfb96..963c4de2 100644 --- a/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js +++ b/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js @@ -1,5 +1,5 @@ -/*! jQuery UI - v1.8.20 - 2012-04-30 -* https://github.com/jquery/jquery-ui +/*! jQuery UI - v1.9.2 - 2012-11-23 +* http://jqueryui.com * Includes: jquery.ui.sortable.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f)return e=a(this),!1});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}return this.currentItem=e,this._removeCurrentsFromItems(),!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(!b)return;a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return e||(b.style.visibility="hidden"),b},update:function(a,b){if(e&&!d.forcePlaceholderSize)return;b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.topthis.containment[3]?u-this.offset.click.topthis.containment[2]?a-this.offset.click.left=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
  • #{label}
  • "},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash)return e.selected=a,!1}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1)return this.blur(),!1;e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected"))return e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur(),!1;if(!f.length)return e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur(),!1}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){return typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$='"+a+"']"))),a},destroy:function(){var b=this.options;return this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie),this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);return j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e])),this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();return d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0])),this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)==-1)return;return this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b])),this},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;return a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a]))),this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;return this.anchors.eq(a).trigger(this.options.event+".tabs"),this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}return this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs"),this},abort:function(){return this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup(),this},url:function(a,b){return this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b),this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.20"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a1&&e.href.replace(r,"")===location.href.replace(r,"").replace(/\s/g,"%20")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options,r=n.active,i=location.hash.substring(1);this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(r===null){i&&this.tabs.each(function(t,n){if(e(n).attr("aria-controls")===i)return r=t,!1}),r===null&&(r=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(r===null||r===-1)r=this.tabs.length?0:!1}r!==!1&&(r=this.tabs.index(this.tabs.eq(r)),r===-1&&(r=n.collapsible?!1:0)),n.active=r,!n.collapsible&&n.active===!1&&this.anchors.length&&(n.active=0),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
    ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
  • #{label}
  • "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
    "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r,i,s=this._superApply(arguments);return s?(e==="beforeActivate"?(r=n.newTab.length?n.newTab:n.oldTab,i=n.newPanel.length?n.newPanel:n.oldPanel,s=this._super("select",t,{tab:r.find(".ui-tabs-anchor")[0],panel:i[0],index:r.closest("li").index()})):e==="activate"&&n.newTab.length&&(s=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),s):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery); \ No newline at end of file diff --git a/wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js b/wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js new file mode 100644 index 00000000..5077d911 --- /dev/null +++ b/wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.9.2 - 2012-11-23 +* http://jqueryui.com +* Includes: jquery.ui.tooltip.js +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
    ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
    ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery); \ No newline at end of file diff --git a/wp-includes/js/jquery/ui/jquery.ui.widget.min.js b/wp-includes/js/jquery/ui/jquery.ui.widget.min.js index 32362074..865bc98d 100644 --- a/wp-includes/js/jquery/ui/jquery.ui.widget.min.js +++ b/wp-includes/js/jquery/ui/jquery.ui.widget.min.js @@ -1,5 +1,5 @@ -/*! jQuery UI - v1.8.20 - 2012-04-30 -* https://github.com/jquery/jquery-ui +/*! jQuery UI - v1.9.2 - 2012-11-23 +* http://jqueryui.com * Includes: jquery.ui.widget.js -* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */ -(function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){return c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}}),d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;return e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e,f&&e.charAt(0)==="_"?h:(f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b)return h=f,!1}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))}),h)}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}return this._setOptions(e),this},_setOptions:function(b){var c=this;return a.each(b,function(a,b){c._setOption(a,b)}),this},_setOption:function(a,b){return this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);return this.element.trigger(c,d),!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}})(jQuery); \ No newline at end of file +* Copyright 2012 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a=t.split(".")[0];t=t.split(".")[1],i=a+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[a]=e[a]||{},s=e[a][t],o=e[a][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,i){e.isFunction(i)&&(r[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},r=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=r,s=i.apply(this,arguments),this._super=t,this._superApply=n,s}}())}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},r,{constructor:o,namespace:a,widgetName:t,widgetBaseClass:i,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u'); + }); + }, + + // ### toText( content ) + // Scans an HTML `content` string and replaces any view instances with + // their respective text representations. + toText: function( content ) { + return content.replace( /<(?:div|span)[^>]+data-wp-view="([^"]+)"[^>]*>.*?]+data-wp-view-end[^>]*><\/span><\/(?:div|span)>/g, function( match, id ) { + var instance = instances[ id ], + view; + + if ( instance ) + view = wp.mce.view.get( instance.options.viewType ); + + return instance && view ? view.text( instance ) : ''; + }); + }, + + // ### Remove internal TinyMCE attributes. + removeInternalAttrs: function( attrs ) { + var result = {}; + _.each( attrs, function( value, attr ) { + if ( -1 === attr.indexOf('data-mce') ) + result[ attr ] = value; + }); + return result; + }, + + // ### Parse an attribute string and removes internal TinyMCE attributes. + attrs: function( content ) { + return wp.mce.view.removeInternalAttrs( wp.html.attrs( content ) ); + }, + + // ### instance( scope ) + // + // Accepts a MCE view wrapper `node` (i.e. a node with the + // `wp-view-wrap` class). + instance: function( node ) { + var id = $( node ).data('wp-view'); + + if ( id ) + return instances[ id ]; + }, + + // ### Select a view. + // + // Accepts a MCE view wrapper `node` (i.e. a node with the + // `wp-view-wrap` class). + select: function( node ) { + var $node = $(node); + + // Bail if node is already selected. + if ( $node.hasClass('selected') ) + return; + + $node.addClass('selected'); + $( node.firstChild ).trigger('select'); + }, + + // ### Deselect a view. + // + // Accepts a MCE view wrapper `node` (i.e. a node with the + // `wp-view-wrap` class). + deselect: function( node ) { + var $node = $(node); + + // Bail if node is already selected. + if ( ! $node.hasClass('selected') ) + return; + + $node.removeClass('selected'); + $( node.firstChild ).trigger('deselect'); + } + }; + +}(jQuery)); \ No newline at end of file diff --git a/wp-includes/js/mce-view.min.js b/wp-includes/js/mce-view.min.js new file mode 100644 index 00000000..53e236ad --- /dev/null +++ b/wp-includes/js/mce-view.min.js @@ -0,0 +1 @@ +window.wp=window.wp||{};(function(b){var a={},c={};wp.mce=wp.mce||{};wp.mce.view={defaults:{pattern:{view:Backbone.View,text:function(d){return d.options.original},toView:function(e){if(!this.pattern){return}this.pattern.lastIndex=0;var d=this.pattern.exec(e);if(!d){return}return{index:d.index,content:d[0],options:{original:d[0],results:d}}}},shortcode:{view:Backbone.View,text:function(d){return d.options.shortcode.string()},toView:function(e){var d=wp.shortcode.next(this.shortcode,e);if(!d){return}return{index:d.index,content:d.content,options:{shortcode:d.shortcode}}}}},add:function(i,e){var g,d,h,f;if(e.extend){g=wp.mce.view.get(e.extend)}else{if(e.shortcode){g=wp.mce.view.defaults.shortcode}else{g=wp.mce.view.defaults.pattern}}_.defaults(e,g);e.id=i;f={remove:function(){delete c[this.el.id];this.$el.parent().remove();if(d){d.apply(this,arguments)}return this}};if(_.isFunction(e.view)){h=e.view}else{h=g.view;d=e.view.remove;_.defaults(f,e.view)}if(!d&&!h._mceview){d=h.prototype.remove}e.view=h.extend(f,{_mceview:true});a[i]=e},get:function(d){return a[d]},remove:function(d){delete a[d]},toViews:function(e){var d=[{content:e}],f;_.each(a,function(h,g){f=d.slice();d=[];_.each(f,function(k){var j=k.content,i;if(k.processed){d.push(k);return}while(j&&(i=h.toView(j))){if(i.index){d.push({content:j.substring(0,i.index)})}d.push({content:wp.mce.view.toView(g,i.options),processed:true});j=j.slice(i.index+i.content.length)}if(j){d.push({content:j})}})});return _.pluck(d,"content").join("")},toView:function(e,g){var f=wp.mce.view.get(e),d,h;if(!f){return""}d=new f.view(_.extend(g||{},{viewType:e}));h=d.el.id=d.el.id||_.uniqueId("__wpmce-");c[h]=d;d.$wrapper=b();return wp.html.string({tag:"span"===d.tagName?"span":"div",attrs:{"class":"wp-view-wrap wp-view-type-"+e,"data-wp-view":h,contenteditable:false}})},render:function(d){b(".wp-view-wrap",d).each(function(){var f=b(this),e=wp.mce.view.instance(this);if(!e){return}e.$wrapper=f;e.render();e.$el.detach();f.empty().append(e.el).append('')})},toText:function(d){return d.replace(/<(?:div|span)[^>]+data-wp-view="([^"]+)"[^>]*>.*?]+data-wp-view-end[^>]*><\/span><\/(?:div|span)>/g,function(g,h){var e=c[h],f;if(e){f=wp.mce.view.get(e.options.viewType)}return e&&f?f.text(e):""})},removeInternalAttrs:function(e){var d={};_.each(e,function(g,f){if(-1===f.indexOf("data-mce")){d[f]=g}});return d},attrs:function(d){return wp.mce.view.removeInternalAttrs(wp.html.attrs(d))},instance:function(d){var e=b(d).data("wp-view");if(e){return c[e]}},select:function(e){var d=b(e);if(d.hasClass("selected")){return}d.addClass("selected");b(e.firstChild).trigger("select")},deselect:function(e){var d=b(e);if(!d.hasClass("selected")){return}d.removeClass("selected");b(e.firstChild).trigger("deselect")}}}(jQuery)); \ No newline at end of file diff --git a/wp-includes/js/media-editor.js b/wp-includes/js/media-editor.js new file mode 100644 index 00000000..34777677 --- /dev/null +++ b/wp-includes/js/media-editor.js @@ -0,0 +1,646 @@ +// WordPress, TinyMCE, and Media +// ----------------------------- +(function($){ + // Stores the editors' `wp.media.controller.Frame` instances. + var workflows = {}; + + wp.media.string = { + // Joins the `props` and `attachment` objects, + // outputting the proper object format based on the + // attachment's type. + props: function( props, attachment ) { + var link, linkUrl, size, sizes, fallbacks; + + // Final fallbacks run after all processing has been completed. + fallbacks = function( props ) { + // Generate alt fallbacks and strip tags. + if ( 'image' === props.type && ! props.alt ) { + props.alt = props.caption || props.title || ''; + props.alt = props.alt.replace( /<\/?[^>]+>/g, '' ); + } + + return props; + }; + + props = props ? _.clone( props ) : {}; + + if ( attachment && attachment.type ) + props.type = attachment.type; + + if ( 'image' === props.type ) { + props = _.defaults( props || {}, { + align: getUserSetting( 'align', 'none' ), + size: getUserSetting( 'imgsize', 'medium' ), + url: '', + classes: [] + }); + } + + // All attachment-specific settings follow. + if ( ! attachment ) + return fallbacks( props ); + + props.title = props.title || attachment.title; + + link = props.link || getUserSetting( 'urlbutton', 'post' ); + if ( 'file' === link ) + linkUrl = attachment.url; + else if ( 'post' === link ) + linkUrl = attachment.link; + else if ( 'custom' === link ) + linkUrl = props.linkUrl; + props.linkUrl = linkUrl || ''; + + // Format properties for images. + if ( 'image' === attachment.type ) { + props.classes.push( 'wp-image-' + attachment.id ); + + sizes = attachment.sizes; + size = sizes && sizes[ props.size ] ? sizes[ props.size ] : attachment; + + _.extend( props, _.pick( attachment, 'align', 'caption', 'alt' ), { + width: size.width, + height: size.height, + src: size.url, + captionId: 'attachment_' + attachment.id + }); + + // Format properties for non-images. + } else { + props.title = props.title || attachment.filename; + props.rel = props.rel || 'attachment wp-att-' + attachment.id; + } + + return fallbacks( props ); + }, + + link: function( props, attachment ) { + var options; + + props = wp.media.string.props( props, attachment ); + + options = { + tag: 'a', + content: props.title, + attrs: { + href: props.linkUrl + } + }; + + if ( props.rel ) + options.attrs.rel = props.rel; + + return wp.html.string( options ); + }, + + image: function( props, attachment ) { + var img = {}, + options, classes, shortcode, html; + + props = wp.media.string.props( props, attachment ); + classes = props.classes || []; + + img.src = props.url; + _.extend( img, _.pick( props, 'width', 'height', 'alt' ) ); + + // Only assign the align class to the image if we're not printing + // a caption, since the alignment is sent to the shortcode. + if ( props.align && ! props.caption ) + classes.push( 'align' + props.align ); + + if ( props.size ) + classes.push( 'size-' + props.size ); + + img['class'] = _.compact( classes ).join(' '); + + // Generate `img` tag options. + options = { + tag: 'img', + attrs: img, + single: true + }; + + // Generate the `a` element options, if they exist. + if ( props.linkUrl ) { + options = { + tag: 'a', + attrs: { + href: props.linkUrl + }, + content: options + }; + } + + html = wp.html.string( options ); + + // Generate the caption shortcode. + if ( props.caption ) { + shortcode = {}; + + if ( img.width ) + shortcode.width = img.width; + + if ( props.captionId ) + shortcode.id = props.captionId; + + if ( props.align ) + shortcode.align = 'align' + props.align; + + html = wp.shortcode.string({ + tag: 'caption', + attrs: shortcode, + content: html + ' ' + props.caption + }); + } + + return html; + } + }; + + wp.media.gallery = (function() { + var galleries = {}; + + return { + defaults: { + order: 'ASC', + id: wp.media.view.settings.post.id, + itemtag: 'dl', + icontag: 'dt', + captiontag: 'dd', + columns: 3, + size: 'thumbnail', + orderby: 'menu_order ID' + }, + + attachments: function( shortcode ) { + var shortcodeString = shortcode.string(), + result = galleries[ shortcodeString ], + attrs, args, query, others; + + delete galleries[ shortcodeString ]; + + if ( result ) + return result; + + // Fill the default shortcode attributes. + attrs = _.defaults( shortcode.attrs.named, wp.media.gallery.defaults ); + args = _.pick( attrs, 'orderby', 'order' ); + + args.type = 'image'; + args.perPage = -1; + + // Mark the `orderby` override attribute. + if ( 'rand' === attrs.orderby ) + attrs._orderbyRandom = true; + + // Map the `orderby` attribute to the corresponding model property. + if ( ! attrs.orderby || /^menu_order(?: ID)?$/i.test( attrs.orderby ) ) + args.orderby = 'menuOrder'; + + // Map the `ids` param to the correct query args. + if ( attrs.ids ) { + args.post__in = attrs.ids.split(','); + args.orderby = 'post__in'; + } else if ( attrs.include ) { + args.post__in = attrs.include.split(','); + } + + if ( attrs.exclude ) + args.post__not_in = attrs.exclude.split(','); + + if ( ! args.post__in ) + args.uploadedTo = attrs.id; + + // Collect the attributes that were not included in `args`. + others = _.omit( attrs, 'id', 'ids', 'include', 'exclude', 'orderby', 'order' ); + + query = wp.media.query( args ); + query.gallery = new Backbone.Model( others ); + return query; + }, + + shortcode: function( attachments ) { + var props = attachments.props.toJSON(), + attrs = _.pick( props, 'orderby', 'order' ), + shortcode, clone; + + if ( attachments.gallery ) + _.extend( attrs, attachments.gallery.toJSON() ); + + // Convert all gallery shortcodes to use the `ids` property. + // Ignore `post__in` and `post__not_in`; the attachments in + // the collection will already reflect those properties. + attrs.ids = attachments.pluck('id'); + + // Copy the `uploadedTo` post ID. + if ( props.uploadedTo ) + attrs.id = props.uploadedTo; + + // Check if the gallery is randomly ordered. + if ( attrs._orderbyRandom ) + attrs.orderby = 'rand'; + delete attrs._orderbyRandom; + + // If the `ids` attribute is set and `orderby` attribute + // is the default value, clear it for cleaner output. + if ( attrs.ids && 'post__in' === attrs.orderby ) + delete attrs.orderby; + + // Remove default attributes from the shortcode. + _.each( wp.media.gallery.defaults, function( value, key ) { + if ( value === attrs[ key ] ) + delete attrs[ key ]; + }); + + shortcode = new wp.shortcode({ + tag: 'gallery', + attrs: attrs, + type: 'single' + }); + + // Use a cloned version of the gallery. + clone = new wp.media.model.Attachments( attachments.models, { + props: props + }); + clone.gallery = attachments.gallery; + galleries[ shortcode.string() ] = clone; + + return shortcode; + }, + + edit: function( content ) { + var shortcode = wp.shortcode.next( 'gallery', content ), + defaultPostId = wp.media.gallery.defaults.id, + attachments, selection; + + // Bail if we didn't match the shortcode or all of the content. + if ( ! shortcode || shortcode.content !== content ) + return; + + // Ignore the rest of the match object. + shortcode = shortcode.shortcode; + + if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) ) + shortcode.set( 'id', defaultPostId ); + + attachments = wp.media.gallery.attachments( shortcode ); + + selection = new wp.media.model.Selection( attachments.models, { + props: attachments.props.toJSON(), + multiple: true + }); + + selection.gallery = attachments.gallery; + + // Fetch the query's attachments, and then break ties from the + // query to allow for sorting. + selection.more().done( function() { + // Break ties with the query. + selection.props.set({ query: false }); + selection.unmirror(); + selection.props.unset('orderby'); + }); + + // Destroy the previous gallery frame. + if ( this.frame ) + this.frame.dispose(); + + // Store the current gallery frame. + this.frame = wp.media({ + frame: 'post', + state: 'gallery-edit', + title: wp.media.view.l10n.editGalleryTitle, + editing: true, + multiple: true, + selection: selection + }).open(); + + return this.frame; + } + }; + }()); + + wp.media.featuredImage = { + get: function() { + return wp.media.view.settings.post.featuredImageId; + }, + + set: function( id ) { + var settings = wp.media.view.settings; + + settings.post.featuredImageId = id; + + wp.media.post( 'set-post-thumbnail', { + json: true, + post_id: settings.post.id, + thumbnail_id: settings.post.featuredImageId, + _wpnonce: settings.post.nonce + }).done( function( html ) { + $( '.inside', '#postimagediv' ).html( html ); + }); + }, + + frame: function() { + if ( this._frame ) + return this._frame; + + this._frame = wp.media({ + state: 'featured-image', + states: [ new wp.media.controller.FeaturedImage() ] + }); + + this._frame.on( 'toolbar:create:featured-image', function( toolbar ) { + this.createSelectToolbar( toolbar, { + text: wp.media.view.l10n.setFeaturedImage + }); + }, this._frame ); + + this._frame.state('featured-image').on( 'select', this.select ); + return this._frame; + }, + + select: function() { + var settings = wp.media.view.settings, + selection = this.get('selection').single(); + + if ( ! settings.post.featuredImageId ) + return; + + wp.media.featuredImage.set( selection ? selection.id : -1 ); + }, + + init: function() { + // Open the content media manager to the 'featured image' tab when + // the post thumbnail is clicked. + $('#postimagediv').on( 'click', '#set-post-thumbnail', function( event ) { + event.preventDefault(); + // Stop propagation to prevent thickbox from activating. + event.stopPropagation(); + + wp.media.featuredImage.frame().open(); + + // Update the featured image id when the 'remove' link is clicked. + }).on( 'click', '#remove-post-thumbnail', function() { + wp.media.view.settings.post.featuredImageId = -1; + }); + } + }; + + $( wp.media.featuredImage.init ); + + wp.media.editor = { + insert: function( h ) { + var mce = typeof(tinymce) != 'undefined', + qt = typeof(QTags) != 'undefined', + wpActiveEditor = window.wpActiveEditor, + ed; + + // Delegate to the global `send_to_editor` if it exists. + // This attempts to play nice with any themes/plugins that have + // overridden the insert functionality. + if ( window.send_to_editor ) + return window.send_to_editor.apply( this, arguments ); + + if ( ! wpActiveEditor ) { + if ( mce && tinymce.activeEditor ) { + ed = tinymce.activeEditor; + wpActiveEditor = window.wpActiveEditor = ed.id; + } else if ( !qt ) { + return false; + } + } else if ( mce ) { + if ( tinymce.activeEditor && (tinymce.activeEditor.id == 'mce_fullscreen' || tinymce.activeEditor.id == 'wp_mce_fullscreen') ) + ed = tinymce.activeEditor; + else + ed = tinymce.get(wpActiveEditor); + } + + if ( ed && !ed.isHidden() ) { + // restore caret position on IE + if ( tinymce.isIE && ed.windowManager.insertimagebookmark ) + ed.selection.moveToBookmark(ed.windowManager.insertimagebookmark); + + if ( h.indexOf('[caption') !== -1 ) { + if ( ed.wpSetImgCaption ) + h = ed.wpSetImgCaption(h); + } else if ( h.indexOf('[gallery') !== -1 ) { + if ( ed.plugins.wpgallery ) + h = ed.plugins.wpgallery._do_gallery(h); + } else if ( h.indexOf('[embed') === 0 ) { + if ( ed.plugins.wordpress ) + h = ed.plugins.wordpress._setEmbed(h); + } + + ed.execCommand('mceInsertContent', false, h); + } else if ( qt ) { + QTags.insertContent(h); + } else { + document.getElementById(wpActiveEditor).value += h; + } + + // If the old thickbox remove function exists, call it in case + // a theme/plugin overloaded it. + if ( window.tb_remove ) + try { window.tb_remove(); } catch( e ) {} + }, + + add: function( id, options ) { + var workflow = this.get( id ); + + if ( workflow ) + return workflow; + + workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { + frame: 'post', + state: 'insert', + title: wp.media.view.l10n.addMedia, + multiple: true + } ) ); + + workflow.on( 'insert', function( selection ) { + var state = workflow.state(); + + selection = selection || state.get('selection'); + + if ( ! selection ) + return; + + $.when.apply( $, selection.map( function( attachment ) { + var display = state.display( attachment ).toJSON(); + return this.send.attachment( display, attachment.toJSON() ); + }, this ) ).done( function() { + wp.media.editor.insert( _.toArray( arguments ).join("\n\n") ); + }); + }, this ); + + workflow.state('gallery-edit').on( 'update', function( selection ) { + this.insert( wp.media.gallery.shortcode( selection ).string() ); + }, this ); + + workflow.state('embed').on( 'select', function() { + var state = workflow.state(), + type = state.get('type'), + embed = state.props.toJSON(); + + embed.url = embed.url || ''; + + if ( 'link' === type ) { + _.defaults( embed, { + title: embed.url, + linkUrl: embed.url + }); + + this.send.link( embed ).done( function( resp ) { + wp.media.editor.insert( resp ); + }); + + } else if ( 'image' === type ) { + _.defaults( embed, { + title: embed.url, + linkUrl: '', + align: 'none', + link: 'none' + }); + + if ( 'none' === embed.link ) + embed.linkUrl = ''; + else if ( 'file' === embed.link ) + embed.linkUrl = embed.url; + + this.insert( wp.media.string.image( embed ) ); + } + }, this ); + + workflow.state('featured-image').on( 'select', wp.media.featuredImage.select ); + workflow.setState( workflow.options.state ); + return workflow; + }, + + id: function( id ) { + if ( id ) + return id; + + // If an empty `id` is provided, default to `wpActiveEditor`. + id = wpActiveEditor; + + // If that doesn't work, fall back to `tinymce.activeEditor.id`. + if ( ! id && typeof tinymce !== 'undefined' && tinymce.activeEditor ) + id = tinymce.activeEditor.id; + + // Last but not least, fall back to the empty string. + id = id || ''; + return id; + }, + + get: function( id ) { + id = this.id( id ); + return workflows[ id ]; + }, + + remove: function( id ) { + id = this.id( id ); + delete workflows[ id ]; + }, + + send: { + attachment: function( props, attachment ) { + var caption = attachment.caption, + options, html; + + // If captions are disabled, clear the caption. + if ( ! wp.media.view.settings.captions ) + delete attachment.caption; + + props = wp.media.string.props( props, attachment ); + + options = { + id: attachment.id, + post_content: attachment.description, + post_excerpt: caption + }; + + if ( props.linkUrl ) + options.url = props.linkUrl; + + if ( 'image' === attachment.type ) { + html = wp.media.string.image( props ); + + _.each({ + align: 'align', + size: 'image-size', + alt: 'image_alt' + }, function( option, prop ) { + if ( props[ prop ] ) + options[ option ] = props[ prop ]; + }); + + } else { + html = wp.media.string.link( props ); + options.post_title = props.title; + } + + return wp.media.post( 'send-attachment-to-editor', { + nonce: wp.media.view.settings.nonce.sendToEditor, + attachment: options, + html: html, + post_id: wp.media.view.settings.post.id + }); + }, + + link: function( embed ) { + return wp.media.post( 'send-link-to-editor', { + nonce: wp.media.view.settings.nonce.sendToEditor, + src: embed.linkUrl, + title: embed.title, + html: wp.media.string.link( embed ), + post_id: wp.media.view.settings.post.id + }); + } + }, + + open: function( id ) { + var workflow, editor; + + id = this.id( id ); + + // Save a bookmark of the caret position in IE. + if ( typeof tinymce !== 'undefined' ) { + editor = tinymce.get( id ); + + if ( tinymce.isIE && editor && ! editor.isHidden() ) { + editor.focus(); + editor.windowManager.insertimagebookmark = editor.selection.getBookmark(); + } + } + + workflow = this.get( id ); + + // Initialize the editor's workflow if we haven't yet. + if ( ! workflow ) + workflow = this.add( id ); + + return workflow.open(); + }, + + init: function() { + $(document.body).on( 'click', '.insert-media', function( event ) { + var $this = $(this), + editor = $this.data('editor'); + + event.preventDefault(); + + // Remove focus from the `.insert-media` button. + // Prevents Opera from showing the outline of the button + // above the modal. + // + // See: http://core.trac.wordpress.org/ticket/22445 + $this.blur(); + + wp.media.editor.open( editor ); + }); + } + }; + + _.bindAll( wp.media.editor, 'open' ); + $( wp.media.editor.init ); +}(jQuery)); diff --git a/wp-includes/js/media-editor.min.js b/wp-includes/js/media-editor.min.js new file mode 100644 index 00000000..1598ba29 --- /dev/null +++ b/wp-includes/js/media-editor.min.js @@ -0,0 +1 @@ +(function(b){var a={};wp.media.string={props:function(f,i){var h,c,e,g,d;d=function(j){if("image"===j.type&&!j.alt){j.alt=j.caption||j.title||"";j.alt=j.alt.replace(/<\/?[^>]+>/g,"")}return j};f=f?_.clone(f):{};if(i&&i.type){f.type=i.type}if("image"===f.type){f=_.defaults(f||{},{align:getUserSetting("align","none"),size:getUserSetting("imgsize","medium"),url:"",classes:[]})}if(!i){return d(f)}f.title=f.title||i.title;h=f.link||getUserSetting("urlbutton","post");if("file"===h){c=i.url}else{if("post"===h){c=i.link}else{if("custom"===h){c=f.linkUrl}}}f.linkUrl=c||"";if("image"===i.type){f.classes.push("wp-image-"+i.id);g=i.sizes;e=g&&g[f.size]?g[f.size]:i;_.extend(f,_.pick(i,"align","caption","alt"),{width:e.width,height:e.height,src:e.url,captionId:"attachment_"+i.id})}else{f.title=f.title||i.filename;f.rel=f.rel||"attachment wp-att-"+i.id}return d(f)},link:function(d,e){var c;d=wp.media.string.props(d,e);c={tag:"a",content:d.title,attrs:{href:d.linkUrl}};if(d.rel){c.attrs.rel=d.rel}return wp.html.string(c)},image:function(g,i){var c={},d,f,h,e;g=wp.media.string.props(g,i);f=g.classes||[];c.src=g.url;_.extend(c,_.pick(g,"width","height","alt"));if(g.align&&!g.caption){f.push("align"+g.align)}if(g.size){f.push("size-"+g.size)}c["class"]=_.compact(f).join(" ");d={tag:"img",attrs:c,single:true};if(g.linkUrl){d={tag:"a",attrs:{href:g.linkUrl},content:d}}e=wp.html.string(d);if(g.caption){h={};if(c.width){h.width=c.width}if(g.captionId){h.id=g.captionId}if(g.align){h.align="align"+g.align}e=wp.shortcode.string({tag:"caption",attrs:h,content:e+" "+g.caption})}return e}};wp.media.gallery=(function(){var c={};return{defaults:{order:"ASC",id:wp.media.view.settings.post.id,itemtag:"dl",icontag:"dt",captiontag:"dd",columns:3,size:"thumbnail",orderby:"menu_order ID"},attachments:function(h){var j=h.string(),d=c[j],f,e,i,g;delete c[j];if(d){return d}f=_.defaults(h.attrs.named,wp.media.gallery.defaults);e=_.pick(f,"orderby","order");e.type="image";e.perPage=-1;if("rand"===f.orderby){f._orderbyRandom=true}if(!f.orderby||/^menu_order(?: ID)?$/i.test(f.orderby)){e.orderby="menuOrder"}if(f.ids){e.post__in=f.ids.split(",");e.orderby="post__in"}else{if(f.include){e.post__in=f.include.split(",")}}if(f.exclude){e.post__not_in=f.exclude.split(",")}if(!e.post__in){e.uploadedTo=f.id}g=_.omit(f,"id","ids","include","exclude","orderby","order");i=wp.media.query(e);i.gallery=new Backbone.Model(g);return i},shortcode:function(d){var f=d.props.toJSON(),e=_.pick(f,"orderby","order"),g,h;if(d.gallery){_.extend(e,d.gallery.toJSON())}e.ids=d.pluck("id");if(f.uploadedTo){e.id=f.uploadedTo}if(e._orderbyRandom){e.orderby="rand"}delete e._orderbyRandom;if(e.ids&&"post__in"===e.orderby){delete e.orderby}_.each(wp.media.gallery.defaults,function(j,i){if(j===e[i]){delete e[i]}});g=new wp.shortcode({tag:"gallery",attrs:e,type:"single"});h=new wp.media.model.Attachments(d.models,{props:f});h.gallery=d.gallery;c[g.string()]=h;return g},edit:function(g){var f=wp.shortcode.next("gallery",g),h=wp.media.gallery.defaults.id,d,e;if(!f||f.content!==g){return}f=f.shortcode;if(_.isUndefined(f.get("id"))&&!_.isUndefined(h)){f.set("id",h)}d=wp.media.gallery.attachments(f);e=new wp.media.model.Selection(d.models,{props:d.props.toJSON(),multiple:true});e.gallery=d.gallery;e.more().done(function(){e.props.set({query:false});e.unmirror();e.props.unset("orderby")});if(this.frame){this.frame.dispose()}this.frame=wp.media({frame:"post",state:"gallery-edit",title:wp.media.view.l10n.editGalleryTitle,editing:true,multiple:true,selection:e}).open();return this.frame}}}());wp.media.featuredImage={get:function(){return wp.media.view.settings.post.featuredImageId},set:function(d){var c=wp.media.view.settings;c.post.featuredImageId=d;wp.media.post("set-post-thumbnail",{json:true,post_id:c.post.id,thumbnail_id:c.post.featuredImageId,_wpnonce:c.post.nonce}).done(function(e){b(".inside","#postimagediv").html(e)})},frame:function(){if(this._frame){return this._frame}this._frame=wp.media({state:"featured-image",states:[new wp.media.controller.FeaturedImage()]});this._frame.on("toolbar:create:featured-image",function(c){this.createSelectToolbar(c,{text:wp.media.view.l10n.setFeaturedImage})},this._frame);this._frame.state("featured-image").on("select",this.select);return this._frame},select:function(){var d=wp.media.view.settings,c=this.get("selection").single();if(!d.post.featuredImageId){return}wp.media.featuredImage.set(c?c.id:-1)},init:function(){b("#postimagediv").on("click","#set-post-thumbnail",function(c){c.preventDefault();c.stopPropagation();wp.media.featuredImage.frame().open()}).on("click","#remove-post-thumbnail",function(){wp.media.view.settings.post.featuredImageId=-1})}};b(wp.media.featuredImage.init);wp.media.editor={insert:function(g){var d=typeof(tinymce)!="undefined",j=typeof(QTags)!="undefined",c=window.wpActiveEditor,f;if(window.send_to_editor){return window.send_to_editor.apply(this,arguments)}if(!c){if(d&&tinymce.activeEditor){f=tinymce.activeEditor;c=window.wpActiveEditor=f.id}else{if(!j){return false}}}else{if(d){if(tinymce.activeEditor&&(tinymce.activeEditor.id=="mce_fullscreen"||tinymce.activeEditor.id=="wp_mce_fullscreen")){f=tinymce.activeEditor}else{f=tinymce.get(c)}}}if(f&&!f.isHidden()){if(tinymce.isIE&&f.windowManager.insertimagebookmark){f.selection.moveToBookmark(f.windowManager.insertimagebookmark)}if(g.indexOf("[caption")!==-1){if(f.wpSetImgCaption){g=f.wpSetImgCaption(g)}}else{if(g.indexOf("[gallery")!==-1){if(f.plugins.wpgallery){g=f.plugins.wpgallery._do_gallery(g)}}else{if(g.indexOf("[embed")===0){if(f.plugins.wordpress){g=f.plugins.wordpress._setEmbed(g)}}}}f.execCommand("mceInsertContent",false,g)}else{if(j){QTags.insertContent(g)}else{document.getElementById(c).value+=g}}if(window.tb_remove){try{window.tb_remove()}catch(i){}}},add:function(e,c){var d=this.get(e);if(d){return d}d=a[e]=wp.media(_.defaults(c||{},{frame:"post",state:"insert",title:wp.media.view.l10n.addMedia,multiple:true}));d.on("insert",function(f){var g=d.state();f=f||g.get("selection");if(!f){return}b.when.apply(b,f.map(function(i){var h=g.display(i).toJSON();return this.send.attachment(h,i.toJSON())},this)).done(function(){wp.media.editor.insert(_.toArray(arguments).join("\n\n"))})},this);d.state("gallery-edit").on("update",function(f){this.insert(wp.media.gallery.shortcode(f).string())},this);d.state("embed").on("select",function(){var g=d.state(),f=g.get("type"),h=g.props.toJSON();h.url=h.url||"";if("link"===f){_.defaults(h,{title:h.url,linkUrl:h.url});this.send.link(h).done(function(i){wp.media.editor.insert(i)})}else{if("image"===f){_.defaults(h,{title:h.url,linkUrl:"",align:"none",link:"none"});if("none"===h.link){h.linkUrl=""}else{if("file"===h.link){h.linkUrl=h.url}}this.insert(wp.media.string.image(h))}}},this);d.state("featured-image").on("select",wp.media.featuredImage.select);d.setState(d.options.state);return d},id:function(c){if(c){return c}c=wpActiveEditor;if(!c&&typeof tinymce!=="undefined"&&tinymce.activeEditor){c=tinymce.activeEditor.id}c=c||"";return c},get:function(c){c=this.id(c);return a[c]},remove:function(c){c=this.id(c);delete a[c]},send:{attachment:function(f,g){var c=g.caption,d,e;if(!wp.media.view.settings.captions){delete g.caption}f=wp.media.string.props(f,g);d={id:g.id,post_content:g.description,post_excerpt:c};if(f.linkUrl){d.url=f.linkUrl}if("image"===g.type){e=wp.media.string.image(f);_.each({align:"align",size:"image-size",alt:"image_alt"},function(h,i){if(f[i]){d[h]=f[i]}})}else{e=wp.media.string.link(f);d.post_title=f.title}return wp.media.post("send-attachment-to-editor",{nonce:wp.media.view.settings.nonce.sendToEditor,attachment:d,html:e,post_id:wp.media.view.settings.post.id})},link:function(c){return wp.media.post("send-link-to-editor",{nonce:wp.media.view.settings.nonce.sendToEditor,src:c.linkUrl,title:c.title,html:wp.media.string.link(c),post_id:wp.media.view.settings.post.id})}},open:function(e){var d,c;e=this.id(e);if(typeof tinymce!=="undefined"){c=tinymce.get(e);if(tinymce.isIE&&c&&!c.isHidden()){c.focus();c.windowManager.insertimagebookmark=c.selection.getBookmark()}}d=this.get(e);if(!d){d=this.add(e)}return d.open()},init:function(){b(document.body).on("click",".insert-media",function(d){var e=b(this),c=e.data("editor");d.preventDefault();e.blur();wp.media.editor.open(c)})}};_.bindAll(wp.media.editor,"open");b(wp.media.editor.init)}(jQuery)); \ No newline at end of file diff --git a/wp-includes/js/media-models.js b/wp-includes/js/media-models.js new file mode 100644 index 00000000..34cce0b7 --- /dev/null +++ b/wp-includes/js/media-models.js @@ -0,0 +1,908 @@ +window.wp = window.wp || {}; + +(function($){ + var Attachment, Attachments, Query, compare, l10n, media; + + /** + * wp.media( attributes ) + * + * Handles the default media experience. Automatically creates + * and opens a media frame, and returns the result. + * Does nothing if the controllers do not exist. + * + * @param {object} attributes The properties passed to the main media controller. + * @return {object} A media workflow. + */ + media = wp.media = function( attributes ) { + var MediaFrame = media.view.MediaFrame, + frame; + + if ( ! MediaFrame ) + return; + + attributes = _.defaults( attributes || {}, { + frame: 'select' + }); + + if ( 'select' === attributes.frame && MediaFrame.Select ) + frame = new MediaFrame.Select( attributes ); + else if ( 'post' === attributes.frame && MediaFrame.Post ) + frame = new MediaFrame.Post( attributes ); + + delete attributes.frame; + + return frame; + }; + + _.extend( media, { model: {}, view: {}, controller: {}, frames: {} }); + + // Link any localized strings. + l10n = media.model.l10n = typeof _wpMediaModelsL10n === 'undefined' ? {} : _wpMediaModelsL10n; + + // Link any settings. + media.model.settings = l10n.settings || {}; + delete l10n.settings; + + /** + * ======================================================================== + * UTILITIES + * ======================================================================== + */ + + /** + * A basic comparator. + * + * @param {mixed} a The primary parameter to compare. + * @param {mixed} b The primary parameter to compare. + * @param {string} ac The fallback parameter to compare, a's cid. + * @param {string} bc The fallback parameter to compare, b's cid. + * @return {number} -1: a should come before b. + * 0: a and b are of the same rank. + * 1: b should come before a. + */ + compare = function( a, b, ac, bc ) { + if ( _.isEqual( a, b ) ) + return ac === bc ? 0 : (ac > bc ? -1 : 1); + else + return a > b ? -1 : 1; + }; + + _.extend( media, { + /** + * media.template( id ) + * + * Fetches a template by id. + * + * @param {string} id A string that corresponds to a DOM element with an id prefixed with "tmpl-". + * For example, "attachment" maps to "tmpl-attachment". + * @return {function} A function that lazily-compiles the template requested. + */ + template: _.memoize( function( id ) { + var compiled, + options = { + evaluate: /<#([\s\S]+?)#>/g, + interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, + escape: /\{\{([^\}]+?)\}\}(?!\})/g, + variable: 'data' + }; + + return function( data ) { + compiled = compiled || _.template( $( '#tmpl-' + id ).html(), null, options ); + return compiled( data ); + }; + }), + + /** + * media.post( [action], [data] ) + * + * Sends a POST request to WordPress. + * + * @param {string} action The slug of the action to fire in WordPress. + * @param {object} data The data to populate $_POST with. + * @return {$.promise} A jQuery promise that represents the request. + */ + post: function( action, data ) { + return media.ajax({ + data: _.isObject( action ) ? action : _.extend( data || {}, { action: action }) + }); + }, + + /** + * media.ajax( [action], [options] ) + * + * Sends a POST request to WordPress. + * + * @param {string} action The slug of the action to fire in WordPress. + * @param {object} options The options passed to jQuery.ajax. + * @return {$.promise} A jQuery promise that represents the request. + */ + ajax: function( action, options ) { + if ( _.isObject( action ) ) { + options = action; + } else { + options = options || {}; + options.data = _.extend( options.data || {}, { action: action }); + } + + options = _.defaults( options || {}, { + type: 'POST', + url: media.model.settings.ajaxurl, + context: this + }); + + return $.Deferred( function( deferred ) { + // Transfer success/error callbacks. + if ( options.success ) + deferred.done( options.success ); + if ( options.error ) + deferred.fail( options.error ); + + delete options.success; + delete options.error; + + // Use with PHP's wp_send_json_success() and wp_send_json_error() + $.ajax( options ).done( function( response ) { + // Treat a response of `1` as successful for backwards + // compatibility with existing handlers. + if ( response === '1' || response === 1 ) + response = { success: true }; + + if ( _.isObject( response ) && ! _.isUndefined( response.success ) ) + deferred[ response.success ? 'resolveWith' : 'rejectWith' ]( this, [response.data] ); + else + deferred.rejectWith( this, [response] ); + }).fail( function() { + deferred.rejectWith( this, arguments ); + }); + }).promise(); + }, + + // Scales a set of dimensions to fit within bounding dimensions. + fit: function( dimensions ) { + var width = dimensions.width, + height = dimensions.height, + maxWidth = dimensions.maxWidth, + maxHeight = dimensions.maxHeight, + constraint; + + // Compare ratios between the two values to determine which + // max to constrain by. If a max value doesn't exist, then the + // opposite side is the constraint. + if ( ! _.isUndefined( maxWidth ) && ! _.isUndefined( maxHeight ) ) { + constraint = ( width / height > maxWidth / maxHeight ) ? 'width' : 'height'; + } else if ( _.isUndefined( maxHeight ) ) { + constraint = 'width'; + } else if ( _.isUndefined( maxWidth ) && height > maxHeight ) { + constraint = 'height'; + } + + // If the value of the constrained side is larger than the max, + // then scale the values. Otherwise return the originals; they fit. + if ( 'width' === constraint && width > maxWidth ) { + return { + width : maxWidth, + height: Math.round( maxWidth * height / width ) + }; + } else if ( 'height' === constraint && height > maxHeight ) { + return { + width : Math.round( maxHeight * width / height ), + height: maxHeight + }; + } else { + return { + width : width, + height: height + }; + } + }, + + // Truncates a string by injecting an ellipsis into the middle. + // Useful for filenames. + truncate: function( string, length, replacement ) { + length = length || 30; + replacement = replacement || '…'; + + if ( string.length <= length ) + return string; + + return string.substr( 0, length / 2 ) + replacement + string.substr( -1 * length / 2 ); + } + }); + + + /** + * ======================================================================== + * MODELS + * ======================================================================== + */ + + /** + * wp.media.attachment + */ + media.attachment = function( id ) { + return Attachment.get( id ); + }; + + /** + * wp.media.model.Attachment + */ + Attachment = media.model.Attachment = Backbone.Model.extend({ + sync: function( method, model, options ) { + // If the attachment does not yet have an `id`, return an instantly + // rejected promise. Otherwise, all of our requests will fail. + if ( _.isUndefined( this.id ) ) + return $.Deferred().rejectWith( this ).promise(); + + // Overload the `read` request so Attachment.fetch() functions correctly. + if ( 'read' === method ) { + options = options || {}; + options.context = this; + options.data = _.extend( options.data || {}, { + action: 'get-attachment', + id: this.id + }); + return media.ajax( options ); + + // Overload the `update` request so properties can be saved. + } else if ( 'update' === method ) { + // If we do not have the necessary nonce, fail immeditately. + if ( ! this.get('nonces') || ! this.get('nonces').update ) + return $.Deferred().rejectWith( this ).promise(); + + options = options || {}; + options.context = this; + + // Set the action and ID. + options.data = _.extend( options.data || {}, { + action: 'save-attachment', + id: this.id, + nonce: this.get('nonces').update, + post_id: media.model.settings.post.id + }); + + // Record the values of the changed attributes. + if ( options.changes ) { + _.each( options.changes, function( value, key ) { + options.changes[ key ] = this.get( key ); + }, this ); + + options.data.changes = options.changes; + delete options.changes; + } + + return media.ajax( options ); + + // Overload the `delete` request so attachments can be removed. + // This will permanently delete an attachment. + } else if ( 'delete' === method ) { + options = options || {}; + + if ( ! options.wait ) + this.destroyed = true; + + options.context = this; + options.data = _.extend( options.data || {}, { + action: 'delete-post', + id: this.id, + _wpnonce: this.get('nonces')['delete'] + }); + + return media.ajax( options ).done( function() { + this.destroyed = true; + }).fail( function() { + this.destroyed = false; + }); + } + }, + + parse: function( resp, xhr ) { + if ( ! resp ) + return resp; + + // Convert date strings into Date objects. + resp.date = new Date( resp.date ); + resp.modified = new Date( resp.modified ); + return resp; + }, + + saveCompat: function( data, options ) { + var model = this; + + // If we do not have the necessary nonce, fail immeditately. + if ( ! this.get('nonces') || ! this.get('nonces').update ) + return $.Deferred().rejectWith( this ).promise(); + + return media.post( 'save-attachment-compat', _.defaults({ + id: this.id, + nonce: this.get('nonces').update, + post_id: media.model.settings.post.id + }, data ) ).done( function( resp, status, xhr ) { + model.set( model.parse( resp, xhr ), options ); + }); + } + }, { + create: function( attrs ) { + return Attachments.all.push( attrs ); + }, + + get: _.memoize( function( id, attachment ) { + return Attachments.all.push( attachment || { id: id } ); + }) + }); + + /** + * wp.media.model.Attachments + */ + Attachments = media.model.Attachments = Backbone.Collection.extend({ + model: Attachment, + + initialize: function( models, options ) { + options = options || {}; + + this.props = new Backbone.Model(); + this.filters = options.filters || {}; + + // Bind default `change` events to the `props` model. + this.props.on( 'change', this._changeFilteredProps, this ); + + this.props.on( 'change:order', this._changeOrder, this ); + this.props.on( 'change:orderby', this._changeOrderby, this ); + this.props.on( 'change:query', this._changeQuery, this ); + + // Set the `props` model and fill the default property values. + this.props.set( _.defaults( options.props || {} ) ); + + // Observe another `Attachments` collection if one is provided. + if ( options.observe ) + this.observe( options.observe ); + }, + + // Automatically sort the collection when the order changes. + _changeOrder: function( model, order ) { + if ( this.comparator ) + this.sort(); + }, + + // Set the default comparator only when the `orderby` property is set. + _changeOrderby: function( model, orderby ) { + // If a different comparator is defined, bail. + if ( this.comparator && this.comparator !== Attachments.comparator ) + return; + + if ( orderby && 'post__in' !== orderby ) + this.comparator = Attachments.comparator; + else + delete this.comparator; + }, + + // If the `query` property is set to true, query the server using + // the `props` values, and sync the results to this collection. + _changeQuery: function( model, query ) { + if ( query ) { + this.props.on( 'change', this._requery, this ); + this._requery(); + } else { + this.props.off( 'change', this._requery, this ); + } + }, + + _changeFilteredProps: function( model, options ) { + // If this is a query, updating the collection will be handled by + // `this._requery()`. + if ( this.props.get('query') ) + return; + + var changed = _.chain( options.changes ).map( function( t, prop ) { + var filter = Attachments.filters[ prop ], + term = model.get( prop ); + + if ( ! filter ) + return; + + if ( term && ! this.filters[ prop ] ) + this.filters[ prop ] = filter; + else if ( ! term && this.filters[ prop ] === filter ) + delete this.filters[ prop ]; + else + return; + + // Record the change. + return true; + }, this ).any().value(); + + if ( ! changed ) + return; + + // If no `Attachments` model is provided to source the searches + // from, then automatically generate a source from the existing + // models. + if ( ! this._source ) + this._source = new Attachments( this.models ); + + this.reset( this._source.filter( this.validator, this ) ); + }, + + validateDestroyed: false, + + validator: function( attachment ) { + if ( ! this.validateDestroyed && attachment.destroyed ) + return false; + return _.all( this.filters, function( filter, key ) { + return !! filter.call( this, attachment ); + }, this ); + }, + + validate: function( attachment, options ) { + var valid = this.validator( attachment ), + hasAttachment = !! this.getByCid( attachment.cid ); + + if ( ! valid && hasAttachment ) + this.remove( attachment, options ); + else if ( valid && ! hasAttachment ) + this.add( attachment, options ); + + return this; + }, + + validateAll: function( attachments, options ) { + options = options || {}; + + _.each( attachments.models, function( attachment ) { + this.validate( attachment, { silent: true }); + }, this ); + + if ( ! options.silent ) + this.trigger( 'reset', this, options ); + + return this; + }, + + observe: function( attachments ) { + this.observers = this.observers || []; + this.observers.push( attachments ); + + attachments.on( 'add change remove', this._validateHandler, this ); + attachments.on( 'reset', this._validateAllHandler, this ); + + this.validateAll( attachments ); + return this; + }, + + unobserve: function( attachments ) { + if ( attachments ) { + attachments.off( null, null, this ); + this.observers = _.without( this.observers, attachments ); + + } else { + _.each( this.observers, function( attachments ) { + attachments.off( null, null, this ); + }, this ); + delete this.observers; + } + + return this; + }, + + _validateHandler: function( attachment, attachments, options ) { + // If we're not mirroring this `attachments` collection, + // only retain the `silent` option. + options = attachments === this.mirroring ? options : { + silent: options && options.silent + }; + + return this.validate( attachment, options ); + }, + + _validateAllHandler: function( attachments, options ) { + return this.validateAll( attachments, options ); + }, + + mirror: function( attachments ) { + if ( this.mirroring && this.mirroring === attachments ) + return this; + + this.unmirror(); + this.mirroring = attachments; + + // Clear the collection silently. A `reset` event will be fired + // when `observe()` calls `validateAll()`. + this.reset( [], { silent: true } ); + this.observe( attachments ); + + return this; + }, + + unmirror: function() { + if ( ! this.mirroring ) + return; + + this.unobserve( this.mirroring ); + delete this.mirroring; + }, + + more: function( options ) { + var deferred = $.Deferred(), + mirroring = this.mirroring, + attachments = this; + + if ( ! mirroring || ! mirroring.more ) + return deferred.resolveWith( this ).promise(); + + // If we're mirroring another collection, forward `more` to + // the mirrored collection. Account for a race condition by + // checking if we're still mirroring that collection when + // the request resolves. + mirroring.more( options ).done( function() { + if ( this === attachments.mirroring ) + deferred.resolveWith( this ); + }); + + return deferred.promise(); + }, + + hasMore: function() { + return this.mirroring ? this.mirroring.hasMore() : false; + }, + + parse: function( resp, xhr ) { + return _.map( resp, function( attrs ) { + var attachment = Attachment.get( attrs.id ); + return attachment.set( attachment.parse( attrs, xhr ) ); + }); + }, + + _requery: function() { + if ( this.props.get('query') ) + this.mirror( Query.get( this.props.toJSON() ) ); + }, + + // If this collection is sorted by `menuOrder`, recalculates and saves + // the menu order to the database. + saveMenuOrder: function() { + if ( 'menuOrder' !== this.props.get('orderby') ) + return; + + // Removes any uploading attachments, updates each attachment's + // menu order, and returns an object with an { id: menuOrder } + // mapping to pass to the request. + var attachments = this.chain().filter( function( attachment ) { + return ! _.isUndefined( attachment.id ); + }).map( function( attachment, index ) { + // Indices start at 1. + index = index + 1; + attachment.set( 'menuOrder', index ); + return [ attachment.id, index ]; + }).object().value(); + + if ( _.isEmpty( attachments ) ) + return; + + return media.post( 'save-attachment-order', { + nonce: media.model.settings.post.nonce, + post_id: media.model.settings.post.id, + attachments: attachments + }); + } + }, { + comparator: function( a, b, options ) { + var key = this.props.get('orderby'), + order = this.props.get('order') || 'DESC', + ac = a.cid, + bc = b.cid; + + a = a.get( key ); + b = b.get( key ); + + if ( 'date' === key || 'modified' === key ) { + a = a || new Date(); + b = b || new Date(); + } + + // If `options.ties` is set, don't enforce the `cid` tiebreaker. + if ( options && options.ties ) + ac = bc = null; + + return ( 'DESC' === order ) ? compare( a, b, ac, bc ) : compare( b, a, bc, ac ); + }, + + filters: { + // Note that this client-side searching is *not* equivalent + // to our server-side searching. + search: function( attachment ) { + if ( ! this.props.get('search') ) + return true; + + return _.any(['title','filename','description','caption','name'], function( key ) { + var value = attachment.get( key ); + return value && -1 !== value.search( this.props.get('search') ); + }, this ); + }, + + type: function( attachment ) { + var type = this.props.get('type'); + return ! type || -1 !== type.indexOf( attachment.get('type') ); + }, + + uploadedTo: function( attachment ) { + var uploadedTo = this.props.get('uploadedTo'); + if ( _.isUndefined( uploadedTo ) ) + return true; + + return uploadedTo === attachment.get('uploadedTo'); + } + } + }); + + Attachments.all = new Attachments(); + + /** + * wp.media.query + */ + media.query = function( props ) { + return new Attachments( null, { + props: _.extend( _.defaults( props || {}, { orderby: 'date' } ), { query: true } ) + }); + }; + + /** + * wp.media.model.Query + * + * A set of attachments that corresponds to a set of consecutively paged + * queries on the server. + * + * Note: Do NOT change this.args after the query has been initialized. + * Things will break. + */ + Query = media.model.Query = Attachments.extend({ + initialize: function( models, options ) { + var allowed; + + options = options || {}; + Attachments.prototype.initialize.apply( this, arguments ); + + this.args = options.args; + this._hasMore = true; + this.created = new Date(); + + this.filters.order = function( attachment ) { + var orderby = this.props.get('orderby'), + order = this.props.get('order'); + + if ( ! this.comparator ) + return true; + + // We want any items that can be placed before the last + // item in the set. If we add any items after the last + // item, then we can't guarantee the set is complete. + if ( this.length ) { + return 1 !== this.comparator( attachment, this.last(), { ties: true }); + + // Handle the case where there are no items yet and + // we're sorting for recent items. In that case, we want + // changes that occurred after we created the query. + } else if ( 'DESC' === order && ( 'date' === orderby || 'modified' === orderby ) ) { + return attachment.get( orderby ) >= this.created; + + // If we're sorting by menu order and we have no items, + // accept any items that have the default menu order (0). + } else if ( 'ASC' === order && 'menuOrder' === orderby ) { + return attachment.get( orderby ) === 0; + } + + // Otherwise, we don't want any items yet. + return false; + }; + + // Observe the central `wp.Uploader.queue` collection to watch for + // new matches for the query. + // + // Only observe when a limited number of query args are set. There + // are no filters for other properties, so observing will result in + // false positives in those queries. + allowed = [ 's', 'order', 'orderby', 'posts_per_page', 'post_mime_type', 'post_parent' ]; + if ( wp.Uploader && _( this.args ).chain().keys().difference( allowed ).isEmpty().value() ) + this.observe( wp.Uploader.queue ); + }, + + hasMore: function() { + return this._hasMore; + }, + + more: function( options ) { + var query = this; + + if ( this._more && 'pending' === this._more.state() ) + return this._more; + + if ( ! this.hasMore() ) + return $.Deferred().resolveWith( this ).promise(); + + options = options || {}; + options.add = true; + + return this._more = this.fetch( options ).done( function( resp ) { + if ( _.isEmpty( resp ) || -1 === this.args.posts_per_page || resp.length < this.args.posts_per_page ) + query._hasMore = false; + }); + }, + + sync: function( method, model, options ) { + var fallback; + + // Overload the read method so Attachment.fetch() functions correctly. + if ( 'read' === method ) { + options = options || {}; + options.context = this; + options.data = _.extend( options.data || {}, { + action: 'query-attachments', + post_id: media.model.settings.post.id + }); + + // Clone the args so manipulation is non-destructive. + args = _.clone( this.args ); + + // Determine which page to query. + if ( -1 !== args.posts_per_page ) + args.paged = Math.floor( this.length / args.posts_per_page ) + 1; + + options.data.query = args; + return media.ajax( options ); + + // Otherwise, fall back to Backbone.sync() + } else { + fallback = Attachments.prototype.sync ? Attachments.prototype : Backbone; + return fallback.sync.apply( this, arguments ); + } + } + }, { + defaultProps: { + orderby: 'date', + order: 'DESC' + }, + + defaultArgs: { + posts_per_page: 40 + }, + + orderby: { + allowed: [ 'name', 'author', 'date', 'title', 'modified', 'uploadedTo', 'id', 'post__in', 'menuOrder' ], + valuemap: { + 'id': 'ID', + 'uploadedTo': 'parent', + 'menuOrder': 'menu_order ID' + } + }, + + propmap: { + 'search': 's', + 'type': 'post_mime_type', + 'perPage': 'posts_per_page', + 'menuOrder': 'menu_order', + 'uploadedTo': 'post_parent' + }, + + // Caches query objects so queries can be easily reused. + get: (function(){ + var queries = []; + + return function( props, options ) { + var args = {}, + orderby = Query.orderby, + defaults = Query.defaultProps, + query; + + // Remove the `query` property. This isn't linked to a query, + // this *is* the query. + delete props.query; + + // Fill default args. + _.defaults( props, defaults ); + + // Normalize the order. + props.order = props.order.toUpperCase(); + if ( 'DESC' !== props.order && 'ASC' !== props.order ) + props.order = defaults.order.toUpperCase(); + + // Ensure we have a valid orderby value. + if ( ! _.contains( orderby.allowed, props.orderby ) ) + props.orderby = defaults.orderby; + + // Generate the query `args` object. + // Correct any differing property names. + _.each( props, function( value, prop ) { + if ( _.isNull( value ) ) + return; + + args[ Query.propmap[ prop ] || prop ] = value; + }); + + // Fill any other default query args. + _.defaults( args, Query.defaultArgs ); + + // `props.orderby` does not always map directly to `args.orderby`. + // Substitute exceptions specified in orderby.keymap. + args.orderby = orderby.valuemap[ props.orderby ] || props.orderby; + + // Search the query cache for matches. + query = _.find( queries, function( query ) { + return _.isEqual( query.args, args ); + }); + + // Otherwise, create a new query and add it to the cache. + if ( ! query ) { + query = new Query( [], _.extend( options || {}, { + props: props, + args: args + } ) ); + queries.push( query ); + } + + return query; + }; + }()) + }); + + /** + * wp.media.model.Selection + * + * Used to manage a selection of attachments in the views. + */ + media.model.Selection = Attachments.extend({ + initialize: function( models, options ) { + Attachments.prototype.initialize.apply( this, arguments ); + this.multiple = options && options.multiple; + + // Refresh the `single` model whenever the selection changes. + // Binds `single` instead of using the context argument to ensure + // it receives no parameters. + this.on( 'add remove reset', _.bind( this.single, this, false ) ); + }, + + // Override the selection's add method. + // If the workflow does not support multiple + // selected attachments, reset the selection. + add: function( models, options ) { + if ( ! this.multiple ) + this.remove( this.models ); + + return Attachments.prototype.add.call( this, models, options ); + }, + + single: function( model ) { + var previous = this._single; + + // If a `model` is provided, use it as the single model. + if ( model ) + this._single = model; + + // If the single model isn't in the selection, remove it. + if ( this._single && ! this.getByCid( this._single.cid ) ) + delete this._single; + + this._single = this._single || this.last(); + + // If single has changed, fire an event. + if ( this._single !== previous ) { + if ( previous ) { + previous.trigger( 'selection:unsingle', previous, this ); + + // If the model was already removed, trigger the collection + // event manually. + if ( ! this.getByCid( previous.cid ) ) + this.trigger( 'selection:unsingle', previous, this ); + } + if ( this._single ) + this._single.trigger( 'selection:single', this._single, this ); + } + + // Return the single model, or the last model as a fallback. + return this._single; + } + }); + + // Clean up. Prevents mobile browsers caching + $(window).on('unload', function(){ + window.wp = null; + }); + +}(jQuery)); \ No newline at end of file diff --git a/wp-includes/js/media-models.min.js b/wp-includes/js/media-models.min.js new file mode 100644 index 00000000..9acf7751 --- /dev/null +++ b/wp-includes/js/media-models.min.js @@ -0,0 +1 @@ +window.wp=window.wp||{};(function(f){var d,c,a,e,b,g;g=wp.media=function(h){var i=g.view.MediaFrame,j;if(!i){return}h=_.defaults(h||{},{frame:"select"});if("select"===h.frame&&i.Select){j=new i.Select(h)}else{if("post"===h.frame&&i.Post){j=new i.Post(h)}}delete h.frame;return j};_.extend(g,{model:{},view:{},controller:{},frames:{}});b=g.model.l10n=typeof _wpMediaModelsL10n==="undefined"?{}:_wpMediaModelsL10n;g.model.settings=b.settings||{};delete b.settings;e=function(i,h,j,k){if(_.isEqual(i,h)){return j===k?0:(j>k?-1:1)}else{return i>h?-1:1}};_.extend(g,{template:_.memoize(function(j){var i,h={evaluate:/<#([\s\S]+?)#>/g,interpolate:/\{\{\{([\s\S]+?)\}\}\}/g,escape:/\{\{([^\}]+?)\}\}(?!\})/g,variable:"data"};return function(k){i=i||_.template(f("#tmpl-"+j).html(),null,h);return i(k)}}),post:function(i,h){return g.ajax({data:_.isObject(i)?i:_.extend(h||{},{action:i})})},ajax:function(i,h){if(_.isObject(i)){h=i}else{h=h||{};h.data=_.extend(h.data||{},{action:i})}h=_.defaults(h||{},{type:"POST",url:g.model.settings.ajaxurl,context:this});return f.Deferred(function(j){if(h.success){j.done(h.success)}if(h.error){j.fail(h.error)}delete h.success;delete h.error;f.ajax(h).done(function(k){if(k==="1"||k===1){k={success:true}}if(_.isObject(k)&&!_.isUndefined(k.success)){j[k.success?"resolveWith":"rejectWith"](this,[k.data])}else{j.rejectWith(this,[k])}}).fail(function(){j.rejectWith(this,arguments)})}).promise()},fit:function(l){var i=l.width,h=l.height,k=l.maxWidth,j=l.maxHeight,m;if(!_.isUndefined(k)&&!_.isUndefined(j)){m=(i/h>k/j)?"width":"height"}else{if(_.isUndefined(j)){m="width"}else{if(_.isUndefined(k)&&h>j){m="height"}}}if("width"===m&&i>k){return{width:k,height:Math.round(k*h/i)}}else{if("height"===m&&h>j){return{width:Math.round(j*i/h),height:j}}else{return{width:i,height:h}}}},truncate:function(h,j,i){j=j||30;i=i||"…";if(h.length<=j){return h}return h.substr(0,j/2)+i+h.substr(-1*j/2)}});g.attachment=function(h){return d.get(h)};d=g.model.Attachment=Backbone.Model.extend({sync:function(j,i,h){if(_.isUndefined(this.id)){return f.Deferred().rejectWith(this).promise()}if("read"===j){h=h||{};h.context=this;h.data=_.extend(h.data||{},{action:"get-attachment",id:this.id});return g.ajax(h)}else{if("update"===j){if(!this.get("nonces")||!this.get("nonces").update){return f.Deferred().rejectWith(this).promise()}h=h||{};h.context=this;h.data=_.extend(h.data||{},{action:"save-attachment",id:this.id,nonce:this.get("nonces").update,post_id:g.model.settings.post.id});if(h.changes){_.each(h.changes,function(l,k){h.changes[k]=this.get(k)},this);h.data.changes=h.changes;delete h.changes}return g.ajax(h)}else{if("delete"===j){h=h||{};if(!h.wait){this.destroyed=true}h.context=this;h.data=_.extend(h.data||{},{action:"delete-post",id:this.id,_wpnonce:this.get("nonces")["delete"]});return g.ajax(h).done(function(){this.destroyed=true}).fail(function(){this.destroyed=false})}}}},parse:function(i,h){if(!i){return i}i.date=new Date(i.date);i.modified=new Date(i.modified);return i},saveCompat:function(j,i){var h=this;if(!this.get("nonces")||!this.get("nonces").update){return f.Deferred().rejectWith(this).promise()}return g.post("save-attachment-compat",_.defaults({id:this.id,nonce:this.get("nonces").update,post_id:g.model.settings.post.id},j)).done(function(m,k,l){h.set(h.parse(m,l),i)})}},{create:function(h){return c.all.push(h)},get:_.memoize(function(i,h){return c.all.push(h||{id:i})})});c=g.model.Attachments=Backbone.Collection.extend({model:d,initialize:function(i,h){h=h||{};this.props=new Backbone.Model();this.filters=h.filters||{};this.props.on("change",this._changeFilteredProps,this);this.props.on("change:order",this._changeOrder,this);this.props.on("change:orderby",this._changeOrderby,this);this.props.on("change:query",this._changeQuery,this);this.props.set(_.defaults(h.props||{}));if(h.observe){this.observe(h.observe)}},_changeOrder:function(i,h){if(this.comparator){this.sort()}},_changeOrderby:function(h,i){if(this.comparator&&this.comparator!==c.comparator){return}if(i&&"post__in"!==i){this.comparator=c.comparator}else{delete this.comparator}},_changeQuery:function(h,i){if(i){this.props.on("change",this._requery,this);this._requery()}else{this.props.off("change",this._requery,this)}},_changeFilteredProps:function(i,h){if(this.props.get("query")){return}var j=_.chain(h.changes).map(function(l,n){var m=c.filters[n],k=i.get(n);if(!m){return}if(k&&!this.filters[n]){this.filters[n]=m}else{if(!k&&this.filters[n]===m){delete this.filters[n]}else{return}}return true},this).any().value();if(!j){return}if(!this._source){this._source=new c(this.models)}this.reset(this._source.filter(this.validator,this))},validateDestroyed:false,validator:function(h){if(!this.validateDestroyed&&h.destroyed){return false}return _.all(this.filters,function(j,i){return !!j.call(this,h)},this)},validate:function(k,i){var j=this.validator(k),h=!!this.getByCid(k.cid);if(!j&&h){this.remove(k,i)}else{if(j&&!h){this.add(k,i)}}return this},validateAll:function(h,i){i=i||{};_.each(h.models,function(j){this.validate(j,{silent:true})},this);if(!i.silent){this.trigger("reset",this,i)}return this},observe:function(h){this.observers=this.observers||[];this.observers.push(h);h.on("add change remove",this._validateHandler,this);h.on("reset",this._validateAllHandler,this);this.validateAll(h);return this},unobserve:function(h){if(h){h.off(null,null,this);this.observers=_.without(this.observers,h)}else{_.each(this.observers,function(i){i.off(null,null,this)},this);delete this.observers}return this},_validateHandler:function(j,h,i){i=h===this.mirroring?i:{silent:i&&i.silent};return this.validate(j,i)},_validateAllHandler:function(h,i){return this.validateAll(h,i)},mirror:function(h){if(this.mirroring&&this.mirroring===h){return this}this.unmirror();this.mirroring=h;this.reset([],{silent:true});this.observe(h);return this},unmirror:function(){if(!this.mirroring){return}this.unobserve(this.mirroring);delete this.mirroring},more:function(j){var i=f.Deferred(),k=this.mirroring,h=this;if(!k||!k.more){return i.resolveWith(this).promise()}k.more(j).done(function(){if(this===h.mirroring){i.resolveWith(this)}});return i.promise()},hasMore:function(){return this.mirroring?this.mirroring.hasMore():false},parse:function(i,h){return _.map(i,function(j){var k=d.get(j.id);return k.set(k.parse(j,h))})},_requery:function(){if(this.props.get("query")){this.mirror(a.get(this.props.toJSON()))}},saveMenuOrder:function(){if("menuOrder"!==this.props.get("orderby")){return}var h=this.chain().filter(function(i){return !_.isUndefined(i.id)}).map(function(j,i){i=i+1;j.set("menuOrder",i);return[j.id,i]}).object().value();if(_.isEmpty(h)){return}return g.post("save-attachment-order",{nonce:g.model.settings.post.nonce,post_id:g.model.settings.post.id,attachments:h})}},{comparator:function(j,i,k){var l=this.props.get("orderby"),h=this.props.get("order")||"DESC",m=j.cid,n=i.cid;j=j.get(l);i=i.get(l);if("date"===l||"modified"===l){j=j||new Date();i=i||new Date()}if(k&&k.ties){m=n=null}return("DESC"===h)?e(j,i,m,n):e(i,j,n,m)},filters:{search:function(h){if(!this.props.get("search")){return true}return _.any(["title","filename","description","caption","name"],function(i){var j=h.get(i);return j&&-1!==j.search(this.props.get("search"))},this)},type:function(i){var h=this.props.get("type");return !h||-1!==h.indexOf(i.get("type"))},uploadedTo:function(i){var h=this.props.get("uploadedTo");if(_.isUndefined(h)){return true}return h===i.get("uploadedTo")}}});c.all=new c();g.query=function(h){return new c(null,{props:_.extend(_.defaults(h||{},{orderby:"date"}),{query:true})})};a=g.model.Query=c.extend({initialize:function(j,h){var i;h=h||{};c.prototype.initialize.apply(this,arguments);this.args=h.args;this._hasMore=true;this.created=new Date();this.filters.order=function(m){var l=this.props.get("orderby"),k=this.props.get("order");if(!this.comparator){return true}if(this.length){return 1!==this.comparator(m,this.last(),{ties:true})}else{if("DESC"===k&&("date"===l||"modified"===l)){return m.get(l)>=this.created}else{if("ASC"===k&&"menuOrder"===l){return m.get(l)===0}}}return false};i=["s","order","orderby","posts_per_page","post_mime_type","post_parent"];if(wp.Uploader&&_(this.args).chain().keys().difference(i).isEmpty().value()){this.observe(wp.Uploader.queue)}},hasMore:function(){return this._hasMore},more:function(h){var i=this;if(this._more&&"pending"===this._more.state()){return this._more}if(!this.hasMore()){return f.Deferred().resolveWith(this).promise()}h=h||{};h.add=true;return this._more=this.fetch(h).done(function(j){if(_.isEmpty(j)||-1===this.args.posts_per_page||j.length If `options.silent` is true, no DOM modifications will be made. + // + // `options.add` – *boolean, `false`* + // > Use `Views.add()` as a shortcut for setting `options.add` to true. + // + // > By default, the provided `views` will replace + // any existing views associated with the selector. If `options.add` + // is true, the provided `views` will be added to the existing views. + // + // `options.at` – *integer, `undefined`* + // > When adding, to insert `views` at a specific index, use + // `options.at`. By default, `views` are added to the end of the array. + set: function( selector, views, options ) { + var existing, next; + + if ( ! _.isString( selector ) ) { + options = views; + views = selector; + selector = ''; + } + + options = options || {}; + views = _.isArray( views ) ? views : [ views ]; + existing = this.get( selector ); + next = views; + + if ( existing ) { + if ( options.add ) { + if ( _.isUndefined( options.at ) ) { + next = existing.concat( views ); + } else { + next = existing; + next.splice.apply( next, [ options.at, 0 ].concat( views ) ); + } + } else { + _.each( next, function( view ) { + view.__detach = true; + }); + + _.each( existing, function( view ) { + if ( view.__detach ) + view.$el.detach(); + else + view.dispose(); + }); + + _.each( next, function( view ) { + delete view.__detach; + }); + } + } + + this._views[ selector ] = next; + + _.each( views, function( subview ) { + var constructor = subview.Views || media.Views, + subviews = subview.views = subview.views || new constructor( subview ); + subviews.parent = this.view; + subviews.selector = selector; + }, this ); + + if ( ! options.silent ) + this._attach( selector, views, _.extend({ ready: this._isReady() }, options ) ); + + return this; + }, + + // ### Add subview(s) to existing subviews + // + // An alias to `Views.set()`, which defaults `options.add` to true. + // + // Adds any number of `views` to a `selector`. + // + // When no `selector` is provided, the root selector (the empty string) + // is used. `views` accepts a `Backbone.View` instance or an array of + // `Backbone.View` instances. + // + // Use `Views.set()` when setting `options.add` to `false`. + // + // Accepts an `options` object. By default, provided `views` will be + // inserted at the end of the array of existing views. To insert + // `views` at a specific index, use `options.at`. If `options.silent` + // is true, no DOM modifications will be made. + // + // For more information on the `options` object, see `Views.set()`. + add: function( selector, views, options ) { + if ( ! _.isString( selector ) ) { + options = views; + views = selector; + selector = ''; + } + + return this.set( selector, views, _.extend({ add: true }, options ) ); + }, + + // ### Stop tracking subviews + // + // Stops tracking `views` registered to a `selector`. If no `views` are + // set, then all of the `selector`'s subviews will be unregistered and + // disposed. + // + // Accepts an `options` object. If `options.silent` is set, `dispose` + // will *not* be triggered on the unregistered views. + unset: function( selector, views, options ) { + var existing; + + if ( ! _.isString( selector ) ) { + options = views; + views = selector; + selector = ''; + } + + views = views || []; + + if ( existing = this.get( selector ) ) { + views = _.isArray( views ) ? views : [ views ]; + this._views[ selector ] = views.length ? _.difference( existing, views ) : []; + } + + if ( ! options || ! options.silent ) + _.invoke( views, 'dispose' ); + + return this; + }, + + // ### Detach all subviews + // + // Detaches all subviews from the DOM. + // + // Helps to preserve all subview events when re-rendering the master + // view. Used in conjunction with `Views.render()`. + detach: function() { + $( _.pluck( this.all(), 'el' ) ).detach(); + return this; + }, + + // ### Render all subviews + // + // Renders all subviews. Used in conjunction with `Views.detach()`. + render: function() { + var options = { + ready: this._isReady() + }; + + _.each( this._views, function( views, selector ) { + this._attach( selector, views, options ); + }, this ); + + this.rendered = true; + return this; + }, + + // ### Dispose all subviews + // + // Triggers the `dispose()` method on all subviews. Detaches the master + // view from its parent. Resets the internals of the views manager. + // + // Accepts an `options` object. If `options.silent` is set, `unset` + // will *not* be triggered on the master view's parent. + dispose: function( options ) { + if ( ! options || ! options.silent ) { + if ( this.parent && this.parent.views ) + this.parent.views.unset( this.selector, this.view, { silent: true }); + delete this.parent; + delete this.selector; + } + + _.invoke( this.all(), 'dispose' ); + this._views = []; + return this; + }, + + // ### Replace a selector's subviews + // + // By default, sets the `$target` selector's html to the subview `els`. + // + // Can be overridden in subclasses. + replace: function( $target, els ) { + $target.html( els ); + return this; + }, + + // ### Insert subviews into a selector + // + // By default, appends the subview `els` to the end of the `$target` + // selector. If `options.at` is set, inserts the subview `els` at the + // provided index. + // + // Can be overridden in subclasses. + insert: function( $target, els, options ) { + var at = options && options.at, + $children; + + if ( _.isNumber( at ) && ($children = $target.children()).length > at ) + $children.eq( at ).before( els ); + else + $target.append( els ); + + return this; + }, + + // ### Trigger the ready event + // + // **Only use this method if you know what you're doing.** + // For performance reasons, this method does not check if the view is + // actually attached to the DOM. It's taking your word for it. + // + // Fires the ready event on the current view and all attached subviews. + ready: function() { + this.view.trigger('ready'); + + // Find all attached subviews, and call ready on them. + _.chain( this.all() ).map( function( view ) { + return view.views; + }).flatten().where({ attached: true }).invoke('ready'); + }, + + // #### Internal. Attaches a series of views to a selector. + // + // Checks to see if a matching selector exists, renders the views, + // performs the proper DOM operation, and then checks if the view is + // attached to the document. + _attach: function( selector, views, options ) { + var $selector = selector ? this.view.$( selector ) : this.view.$el, + managers; + + // Check if we found a location to attach the views. + if ( ! $selector.length ) + return this; + + managers = _.chain( views ).pluck('views').flatten().value(); + + // Render the views if necessary. + _.each( managers, function( manager ) { + if ( manager.rendered ) + return; + + manager.view.render(); + manager.rendered = true; + }, this ); + + // Insert or replace the views. + this[ options.add ? 'insert' : 'replace' ]( $selector, _.pluck( views, 'el' ), options ); + + // Set attached and trigger ready if the current view is already + // attached to the DOM. + _.each( managers, function( manager ) { + manager.attached = true; + + if ( options.ready ) + manager.ready(); + }, this ); + + return this; + }, + + // #### Internal. Checks if the current view is in the DOM. + _isReady: function() { + var node = this.view.el; + while ( node ) { + if ( node === document.body ) + return true; + node = node.parentNode; + } + + return false; + } + }); + + // wp.media.View + // ------------- + // + // The base view class. + media.View = Backbone.View.extend({ + // The constructor for the `Views` manager. + Views: media.Views, + + constructor: function( options ) { + this.views = new this.Views( this, this.views ); + this.on( 'ready', this.ready, this ); + + if ( options && options.controller ) + this.controller = options.controller; + + Backbone.View.apply( this, arguments ); + }, + + dispose: function() { + // Undelegating events, removing events from the model, and + // removing events from the controller mirror the code for + // `Backbone.View.dispose` in Backbone master. + this.undelegateEvents(); + + if ( this.model && this.model.off ) + this.model.off( null, null, this ); + + if ( this.collection && this.collection.off ) + this.collection.off( null, null, this ); + + // Unbind controller events. + if ( this.controller && this.controller.off ) + this.controller.off( null, null, this ); + + // Recursively dispose child views. + if ( this.views ) + this.views.dispose(); + + return this; + }, + + remove: function() { + this.dispose(); + return Backbone.View.prototype.remove.apply( this, arguments ); + }, + + render: function() { + var options; + + if ( this.prepare ) + options = this.prepare(); + + this.views.detach(); + + if ( this.template ) { + options = options || {}; + this.trigger( 'prepare', options ); + this.$el.html( this.template( options ) ); + } + + this.views.render(); + return this; + }, + + prepare: function() { + return this.options; + }, + + ready: function() {} + }); + + /** + * wp.media.view.Frame + */ + media.view.Frame = media.View.extend({ + initialize: function() { + this._createRegions(); + this._createStates(); + }, + + _createRegions: function() { + // Clone the regions array. + this.regions = this.regions ? this.regions.slice() : []; + + // Initialize regions. + _.each( this.regions, function( region ) { + this[ region ] = new media.controller.Region({ + view: this, + id: region, + selector: '.media-frame-' + region + }); + }, this ); + }, + + _createStates: function() { + // Create the default `states` collection. + this.states = new Backbone.Collection( null, { + model: media.controller.State + }); + + // Ensure states have a reference to the frame. + this.states.on( 'add', function( model ) { + model.frame = this; + model.trigger('ready'); + }, this ); + + if ( this.options.states ) + this.states.add( this.options.states ); + }, + + reset: function() { + this.states.invoke( 'trigger', 'reset' ); + return this; + } + }); + + // Make the `Frame` a `StateMachine`. + _.extend( media.view.Frame.prototype, media.controller.StateMachine.prototype ); + + /** + * wp.media.view.MediaFrame + */ + media.view.MediaFrame = media.view.Frame.extend({ + className: 'media-frame', + template: media.template('media-frame'), + regions: ['menu','title','content','toolbar','router'], + + initialize: function() { + media.view.Frame.prototype.initialize.apply( this, arguments ); + + _.defaults( this.options, { + title: '', + modal: true, + uploader: true + }); + + // Ensure core UI is enabled. + this.$el.addClass('wp-core-ui'); + + // Initialize modal container view. + if ( this.options.modal ) { + this.modal = new media.view.Modal({ + controller: this, + title: this.options.title + }); + + this.modal.content( this ); + } + + // Force the uploader off if the upload limit has been exceeded or + // if the browser isn't supported. + if ( wp.Uploader.limitExceeded || ! wp.Uploader.browser.supported ) + this.options.uploader = false; + + // Initialize window-wide uploader. + if ( this.options.uploader ) { + this.uploader = new media.view.UploaderWindow({ + controller: this, + uploader: { + dropzone: this.modal ? this.modal.$el : this.$el, + container: this.$el + } + }); + this.views.set( '.media-frame-uploader', this.uploader ); + } + + this.on( 'attach', _.bind( this.views.ready, this.views ), this ); + + // Bind default title creation. + this.on( 'title:create:default', this.createTitle, this ); + this.title.mode('default'); + + // Bind default menu. + this.on( 'menu:create:default', this.createMenu, this ); + }, + + render: function() { + // Activate the default state if no active state exists. + if ( ! this.state() && this.options.state ) + this.setState( this.options.state ); + + return media.view.Frame.prototype.render.apply( this, arguments ); + }, + + createTitle: function( title ) { + title.view = new media.View({ + controller: this, + tagName: 'h1' + }); + }, + + createMenu: function( menu ) { + menu.view = new media.view.Menu({ + controller: this + }); + }, + + createToolbar: function( toolbar ) { + toolbar.view = new media.view.Toolbar({ + controller: this + }); + }, + + createRouter: function( router ) { + router.view = new media.view.Router({ + controller: this + }); + }, + + createIframeStates: function( options ) { + var settings = media.view.settings, + tabs = settings.tabs, + tabUrl = settings.tabUrl, + $postId; + + if ( ! tabs || ! tabUrl ) + return; + + // Add the post ID to the tab URL if it exists. + $postId = $('#post_ID'); + if ( $postId.length ) + tabUrl += '&post_id=' + $postId.val(); + + // Generate the tab states. + _.each( tabs, function( title, id ) { + var frame = this.state( 'iframe:' + id ).set( _.defaults({ + tab: id, + src: tabUrl + '&tab=' + id, + title: title, + content: 'iframe', + menu: 'default' + }, options ) ); + }, this ); + + this.on( 'content:create:iframe', this.iframeContent, this ); + this.on( 'menu:render:default', this.iframeMenu, this ); + this.on( 'open', this.hijackThickbox, this ); + this.on( 'close', this.restoreThickbox, this ); + }, + + iframeContent: function( content ) { + this.$el.addClass('hide-toolbar'); + content.view = new media.view.Iframe({ + controller: this + }); + }, + + iframeMenu: function( view ) { + var views = {}; + + if ( ! view ) + return; + + _.each( media.view.settings.tabs, function( title, id ) { + views[ 'iframe:' + id ] = { + text: this.state( 'iframe:' + id ).get('title'), + priority: 200 + }; + }, this ); + + view.set( views ); + }, + + hijackThickbox: function() { + var frame = this; + + if ( ! window.tb_remove || this._tb_remove ) + return; + + this._tb_remove = window.tb_remove; + window.tb_remove = function() { + frame.close(); + frame.reset(); + frame.setState( frame.options.state ); + frame._tb_remove.call( window ); + }; + }, + + restoreThickbox: function() { + if ( ! this._tb_remove ) + return; + + window.tb_remove = this._tb_remove; + delete this._tb_remove; + } + }); + + // Map some of the modal's methods to the frame. + _.each(['open','close','attach','detach','escape'], function( method ) { + media.view.MediaFrame.prototype[ method ] = function( view ) { + if ( this.modal ) + this.modal[ method ].apply( this.modal, arguments ); + return this; + }; + }); + + /** + * wp.media.view.MediaFrame.Select + */ + media.view.MediaFrame.Select = media.view.MediaFrame.extend({ + initialize: function() { + media.view.MediaFrame.prototype.initialize.apply( this, arguments ); + + _.defaults( this.options, { + selection: [], + library: {}, + multiple: false, + state: 'library' + }); + + this.createSelection(); + this.createStates(); + this.bindHandlers(); + }, + + createSelection: function() { + var controller = this, + selection = this.options.selection; + + if ( ! (selection instanceof media.model.Selection) ) { + this.options.selection = new media.model.Selection( selection, { + multiple: this.options.multiple + }); + } + + this._selection = { + attachments: new Attachments(), + difference: [] + }; + }, + + createStates: function() { + var options = this.options; + + if ( this.options.states ) + return; + + // Add the default states. + this.states.add([ + // Main states. + new media.controller.Library({ + library: media.query( options.library ), + multiple: options.multiple, + title: options.title, + priority: 20 + }) + ]); + }, + + bindHandlers: function() { + this.on( 'router:create:browse', this.createRouter, this ); + this.on( 'router:render:browse', this.browseRouter, this ); + this.on( 'content:create:browse', this.browseContent, this ); + this.on( 'content:render:upload', this.uploadContent, this ); + this.on( 'toolbar:create:select', this.createSelectToolbar, this ); + }, + + // Routers + browseRouter: function( view ) { + view.set({ + upload: { + text: l10n.uploadFilesTitle, + priority: 20 + }, + browse: { + text: l10n.mediaLibraryTitle, + priority: 40 + } + }); + }, + + // Content + browseContent: function( content ) { + var state = this.state(); + + this.$el.removeClass('hide-toolbar'); + + // Browse our library of attachments. + content.view = new media.view.AttachmentsBrowser({ + controller: this, + collection: state.get('library'), + selection: state.get('selection'), + model: state, + sortable: state.get('sortable'), + search: state.get('searchable'), + filters: state.get('filterable'), + display: state.get('displaySettings'), + dragInfo: state.get('dragInfo'), + + AttachmentView: state.get('AttachmentView') + }); + }, + + uploadContent: function() { + this.$el.removeClass('hide-toolbar'); + this.content.set( new media.view.UploaderInline({ + controller: this + }) ); + }, + + // Toolbars + createSelectToolbar: function( toolbar, options ) { + options = options || this.options.button || {}; + options.controller = this; + + toolbar.view = new media.view.Toolbar.Select( options ); + } + }); + + /** + * wp.media.view.MediaFrame.Post + */ + media.view.MediaFrame.Post = media.view.MediaFrame.Select.extend({ + initialize: function() { + _.defaults( this.options, { + multiple: true, + editing: false, + state: 'insert' + }); + + media.view.MediaFrame.Select.prototype.initialize.apply( this, arguments ); + this.createIframeStates(); + }, + + createStates: function() { + var options = this.options; + + // Add the default states. + this.states.add([ + // Main states. + new media.controller.Library({ + id: 'insert', + title: l10n.insertMediaTitle, + priority: 20, + toolbar: 'main-insert', + filterable: 'all', + library: media.query( options.library ), + multiple: options.multiple ? 'reset' : false, + editable: true, + + // If the user isn't allowed to edit fields, + // can they still edit it locally? + allowLocalEdits: true, + + // Show the attachment display settings. + displaySettings: true, + // Update user settings when users adjust the + // attachment display settings. + displayUserSettings: true + }), + + new media.controller.Library({ + id: 'gallery', + title: l10n.createGalleryTitle, + priority: 40, + toolbar: 'main-gallery', + filterable: 'uploaded', + multiple: 'add', + editable: false, + + library: media.query( _.defaults({ + type: 'image' + }, options.library ) ) + }), + + // Embed states. + new media.controller.Embed(), + + // Gallery states. + new media.controller.GalleryEdit({ + library: options.selection, + editing: options.editing, + menu: 'gallery' + }), + + new media.controller.GalleryAdd() + ]); + + + if ( media.view.settings.post.featuredImageId ) { + this.states.add( new media.controller.FeaturedImage() ); + } + }, + + bindHandlers: function() { + media.view.MediaFrame.Select.prototype.bindHandlers.apply( this, arguments ); + this.on( 'menu:create:gallery', this.createMenu, this ); + this.on( 'toolbar:create:main-insert', this.createToolbar, this ); + this.on( 'toolbar:create:main-gallery', this.createToolbar, this ); + this.on( 'toolbar:create:featured-image', this.featuredImageToolbar, this ); + this.on( 'toolbar:create:main-embed', this.mainEmbedToolbar, this ); + + var handlers = { + menu: { + 'default': 'mainMenu', + 'gallery': 'galleryMenu' + }, + + content: { + 'embed': 'embedContent', + 'edit-selection': 'editSelectionContent' + }, + + toolbar: { + 'main-insert': 'mainInsertToolbar', + 'main-gallery': 'mainGalleryToolbar', + 'gallery-edit': 'galleryEditToolbar', + 'gallery-add': 'galleryAddToolbar' + } + }; + + _.each( handlers, function( regionHandlers, region ) { + _.each( regionHandlers, function( callback, handler ) { + this.on( region + ':render:' + handler, this[ callback ], this ); + }, this ); + }, this ); + }, + + // Menus + mainMenu: function( view ) { + view.set({ + 'library-separator': new media.View({ + className: 'separator', + priority: 100 + }) + }); + }, + + galleryMenu: function( view ) { + var lastState = this.lastState(), + previous = lastState && lastState.id, + frame = this; + + view.set({ + cancel: { + text: l10n.cancelGalleryTitle, + priority: 20, + click: function() { + if ( previous ) + frame.setState( previous ); + else + frame.close(); + } + }, + separateCancel: new media.View({ + className: 'separator', + priority: 40 + }) + }); + }, + + // Content + embedContent: function() { + var view = new media.view.Embed({ + controller: this, + model: this.state() + }).render(); + + this.content.set( view ); + view.url.focus(); + }, + + editSelectionContent: function() { + var state = this.state(), + selection = state.get('selection'), + view; + + view = new media.view.AttachmentsBrowser({ + controller: this, + collection: selection, + selection: selection, + model: state, + sortable: true, + search: false, + dragInfo: true, + + AttachmentView: media.view.Attachment.EditSelection + }).render(); + + view.toolbar.set( 'backToLibrary', { + text: l10n.returnToLibrary, + priority: -100, + + click: function() { + this.controller.content.mode('browse'); + } + }); + + // Browse our library of attachments. + this.content.set( view ); + }, + + // Toolbars + selectionStatusToolbar: function( view ) { + var editable = this.state().get('editable'); + + view.set( 'selection', new media.view.Selection({ + controller: this, + collection: this.state().get('selection'), + priority: -40, + + // If the selection is editable, pass the callback to + // switch the content mode. + editable: editable && function() { + this.controller.content.mode('edit-selection'); + } + }).render() ); + }, + + mainInsertToolbar: function( view ) { + var controller = this; + + this.selectionStatusToolbar( view ); + + view.set( 'insert', { + style: 'primary', + priority: 80, + text: l10n.insertIntoPost, + requires: { selection: true }, + + click: function() { + var state = controller.state(), + selection = state.get('selection'); + + controller.close(); + state.trigger( 'insert', selection ).reset(); + } + }); + }, + + mainGalleryToolbar: function( view ) { + var controller = this; + + this.selectionStatusToolbar( view ); + + view.set( 'gallery', { + style: 'primary', + text: l10n.createNewGallery, + priority: 60, + requires: { selection: true }, + + click: function() { + var selection = controller.state().get('selection'), + edit = controller.state('gallery-edit'), + models = selection.where({ type: 'image' }); + + edit.set( 'library', new media.model.Selection( models, { + props: selection.props.toJSON(), + multiple: true + }) ); + + this.controller.setState('gallery-edit'); + } + }); + }, + + featuredImageToolbar: function( toolbar ) { + this.createSelectToolbar( toolbar, { + text: l10n.setFeaturedImage, + state: this.options.state || 'upload' + }); + }, + + mainEmbedToolbar: function( toolbar ) { + toolbar.view = new media.view.Toolbar.Embed({ + controller: this + }); + }, + + galleryEditToolbar: function() { + var editing = this.state().get('editing'); + this.toolbar.set( new media.view.Toolbar({ + controller: this, + items: { + insert: { + style: 'primary', + text: editing ? l10n.updateGallery : l10n.insertGallery, + priority: 80, + requires: { library: true }, + + click: function() { + var controller = this.controller, + state = controller.state(); + + controller.close(); + state.trigger( 'update', state.get('library') ); + + controller.reset(); + // @todo: Make the state activated dynamic (instead of hardcoded). + controller.setState('upload'); + } + } + } + }) ); + }, + + galleryAddToolbar: function() { + this.toolbar.set( new media.view.Toolbar({ + controller: this, + items: { + insert: { + style: 'primary', + text: l10n.addToGallery, + priority: 80, + requires: { selection: true }, + + click: function() { + var controller = this.controller, + state = controller.state(), + edit = controller.state('gallery-edit'); + + edit.get('library').add( state.get('selection').models ); + state.trigger('reset'); + controller.setState('gallery-edit'); + } + } + } + }) ); + } + }); + + /** + * wp.media.view.Modal + */ + media.view.Modal = media.View.extend({ + tagName: 'div', + template: media.template('media-modal'), + + attributes: { + tabindex: 0 + }, + + events: { + 'click .media-modal-backdrop, .media-modal-close': 'escapeHandler', + 'keydown': 'keydown' + }, + + initialize: function() { + _.defaults( this.options, { + container: document.body, + title: '', + propagate: true, + freeze: true + }); + }, + + prepare: function() { + return { + title: this.options.title + }; + }, + + attach: function() { + if ( this.views.attached ) + return this; + + if ( ! this.views.rendered ) + this.render(); + + this.$el.appendTo( this.options.container ); + + // Manually mark the view as attached and trigger ready. + this.views.attached = true; + this.views.ready(); + + return this.propagate('attach'); + }, + + detach: function() { + if ( this.$el.is(':visible') ) + this.close(); + + this.$el.detach(); + this.views.attached = false; + return this.propagate('detach'); + }, + + open: function() { + var $el = this.$el, + options = this.options; + + if ( $el.is(':visible') ) + return this; + + if ( ! this.views.attached ) + this.attach(); + + // If the `freeze` option is set, record the window's scroll position. + if ( options.freeze ) { + this._freeze = { + scrollTop: $( window ).scrollTop() + }; + } + + $el.show().focus(); + return this.propagate('open'); + }, + + close: function( options ) { + var freeze = this._freeze; + + if ( ! this.views.attached || ! this.$el.is(':visible') ) + return this; + + this.$el.hide(); + this.propagate('close'); + + // If the `freeze` option is set, restore the container's scroll position. + if ( freeze ) { + $( window ).scrollTop( freeze.scrollTop ); + } + + if ( options && options.escape ) + this.propagate('escape'); + + return this; + }, + + escape: function() { + return this.close({ escape: true }); + }, + + escapeHandler: function( event ) { + event.preventDefault(); + this.escape(); + }, + + content: function( content ) { + this.views.set( '.media-modal-content', content ); + return this; + }, + + // Triggers a modal event and if the `propagate` option is set, + // forwards events to the modal's controller. + propagate: function( id ) { + this.trigger( id ); + + if ( this.options.propagate ) + this.controller.trigger( id ); + + return this; + }, + + keydown: function( event ) { + // Close the modal when escape is pressed. + if ( 27 === event.which ) { + event.preventDefault(); + this.escape(); + return; + } + } + }); + + // wp.media.view.FocusManager + // ---------------------------- + media.view.FocusManager = media.View.extend({ + events: { + keydown: 'recordTab', + focusin: 'updateIndex' + }, + + focus: function() { + if ( _.isUndefined( this.index ) ) + return; + + // Update our collection of `$tabbables`. + this.$tabbables = this.$(':tabbable'); + + // If tab is saved, focus it. + this.$tabbables.eq( this.index ).focus(); + }, + + recordTab: function( event ) { + // Look for the tab key. + if ( 9 !== event.keyCode ) + return; + + // First try to update the index. + if ( _.isUndefined( this.index ) ) + this.updateIndex( event ); + + // If we still don't have an index, bail. + if ( _.isUndefined( this.index ) ) + return; + + var index = this.index + ( event.shiftKey ? -1 : 1 ); + + if ( index >= 0 && index < this.$tabbables.length ) + this.index = index; + else + delete this.index; + }, + + updateIndex: function( event ) { + this.$tabbables = this.$(':tabbable'); + + var index = this.$tabbables.index( event.target ); + + if ( -1 === index ) + delete this.index; + else + this.index = index; + } + }); + + // wp.media.view.UploaderWindow + // ---------------------------- + media.view.UploaderWindow = media.View.extend({ + tagName: 'div', + className: 'uploader-window', + template: media.template('uploader-window'), + + initialize: function() { + var uploader; + + this.$browser = $('').hide().appendTo('body'); + + uploader = this.options.uploader = _.defaults( this.options.uploader || {}, { + dropzone: this.$el, + browser: this.$browser, + params: {} + }); + + // Ensure the dropzone is a jQuery collection. + if ( uploader.dropzone && ! (uploader.dropzone instanceof $) ) + uploader.dropzone = $( uploader.dropzone ); + + this.controller.on( 'activate', this.refresh, this ); + }, + + refresh: function() { + if ( this.uploader ) + this.uploader.refresh(); + }, + + ready: function() { + var postId = media.view.settings.post.id, + dropzone; + + // If the uploader already exists, bail. + if ( this.uploader ) + return; + + if ( postId ) + this.options.uploader.params.post_id = postId; + + this.uploader = new wp.Uploader( this.options.uploader ); + + dropzone = this.uploader.dropzone; + dropzone.on( 'dropzone:enter', _.bind( this.show, this ) ); + dropzone.on( 'dropzone:leave', _.bind( this.hide, this ) ); + }, + + show: function() { + var $el = this.$el.show(); + + // Ensure that the animation is triggered by waiting until + // the transparent element is painted into the DOM. + _.defer( function() { + $el.css({ opacity: 1 }); + }); + }, + + hide: function() { + var $el = this.$el.css({ opacity: 0 }); + + media.transition( $el ).done( function() { + // Transition end events are subject to race conditions. + // Make sure that the value is set as intended. + if ( '0' === $el.css('opacity') ) + $el.hide(); + }); + } + }); + + media.view.UploaderInline = media.View.extend({ + tagName: 'div', + className: 'uploader-inline', + template: media.template('uploader-inline'), + + initialize: function() { + _.defaults( this.options, { + message: '', + status: true + }); + + if ( ! this.options.$browser && this.controller.uploader ) + this.options.$browser = this.controller.uploader.$browser; + + if ( _.isUndefined( this.options.postId ) ) + this.options.postId = media.view.settings.post.id; + + if ( this.options.status ) { + this.views.set( '.upload-inline-status', new media.view.UploaderStatus({ + controller: this.controller + }) ); + } + }, + + dispose: function() { + if ( this.disposing ) + return media.View.prototype.dispose.apply( this, arguments ); + + // Run remove on `dispose`, so we can be sure to refresh the + // uploader with a view-less DOM. Track whether we're disposing + // so we don't trigger an infinite loop. + this.disposing = true; + return this.remove(); + }, + + remove: function() { + var result = media.View.prototype.remove.apply( this, arguments ); + + _.defer( _.bind( this.refresh, this ) ); + return result; + }, + + refresh: function() { + var uploader = this.controller.uploader; + + if ( uploader ) + uploader.refresh(); + }, + + ready: function() { + var $browser = this.options.$browser, + $placeholder; + + if ( this.controller.uploader ) { + $placeholder = this.$('.browser'); + + // Check if we've already replaced the placeholder. + if ( $placeholder[0] === $browser[0] ) + return; + + $browser.detach().text( $placeholder.text() ); + $browser[0].className = $placeholder[0].className; + $placeholder.replaceWith( $browser.show() ); + } + + this.refresh(); + return this; + } + }); + + /** + * wp.media.view.UploaderStatus + */ + media.view.UploaderStatus = media.View.extend({ + className: 'media-uploader-status', + template: media.template('uploader-status'), + + events: { + 'click .upload-dismiss-errors': 'dismiss' + }, + + initialize: function() { + this.queue = wp.Uploader.queue; + this.queue.on( 'add remove reset', this.visibility, this ); + this.queue.on( 'add remove reset change:percent', this.progress, this ); + this.queue.on( 'add remove reset change:uploading', this.info, this ); + + this.errors = wp.Uploader.errors; + this.errors.reset(); + this.errors.on( 'add remove reset', this.visibility, this ); + this.errors.on( 'add', this.error, this ); + }, + + dispose: function() { + wp.Uploader.queue.off( null, null, this ); + media.View.prototype.dispose.apply( this, arguments ); + return this; + }, + + visibility: function() { + this.$el.toggleClass( 'uploading', !! this.queue.length ); + this.$el.toggleClass( 'errors', !! this.errors.length ); + this.$el.toggle( !! this.queue.length || !! this.errors.length ); + }, + + ready: function() { + _.each({ + '$bar': '.media-progress-bar div', + '$index': '.upload-index', + '$total': '.upload-total', + '$filename': '.upload-filename' + }, function( selector, key ) { + this[ key ] = this.$( selector ); + }, this ); + + this.visibility(); + this.progress(); + this.info(); + }, + + progress: function() { + var queue = this.queue, + $bar = this.$bar, + memo = 0; + + if ( ! $bar || ! queue.length ) + return; + + $bar.width( ( queue.reduce( function( memo, attachment ) { + if ( ! attachment.get('uploading') ) + return memo + 100; + + var percent = attachment.get('percent'); + return memo + ( _.isNumber( percent ) ? percent : 100 ); + }, 0 ) / queue.length ) + '%' ); + }, + + info: function() { + var queue = this.queue, + index = 0, active; + + if ( ! queue.length ) + return; + + active = this.queue.find( function( attachment, i ) { + index = i; + return attachment.get('uploading'); + }); + + this.$index.text( index + 1 ); + this.$total.text( queue.length ); + this.$filename.html( active ? this.filename( active.get('filename') ) : '' ); + }, + + filename: function( filename ) { + return media.truncate( _.escape( filename ), 24 ); + }, + + error: function( error ) { + this.views.add( '.upload-errors', new media.view.UploaderStatusError({ + filename: this.filename( error.get('file').name ), + message: error.get('message') + }), { at: 0 }); + }, + + dismiss: function( event ) { + var errors = this.views.get('.upload-errors'); + + event.preventDefault(); + + if ( errors ) + _.invoke( errors, 'remove' ); + wp.Uploader.errors.reset(); + } + }); + + media.view.UploaderStatusError = media.View.extend({ + className: 'upload-error', + template: media.template('uploader-status-error') + }); + + /** + * wp.media.view.Toolbar + */ + media.view.Toolbar = media.View.extend({ + tagName: 'div', + className: 'media-toolbar', + + initialize: function() { + var state = this.controller.state(), + selection = this.selection = state.get('selection'), + library = this.library = state.get('library'); + + this._views = {}; + + // The toolbar is composed of two `PriorityList` views. + this.primary = new media.view.PriorityList(); + this.secondary = new media.view.PriorityList(); + this.primary.$el.addClass('media-toolbar-primary'); + this.secondary.$el.addClass('media-toolbar-secondary'); + + this.views.set([ this.secondary, this.primary ]); + + if ( this.options.items ) + this.set( this.options.items, { silent: true }); + + if ( ! this.options.silent ) + this.render(); + + if ( selection ) + selection.on( 'add remove reset', this.refresh, this ); + if ( library ) + library.on( 'add remove reset', this.refresh, this ); + }, + + dispose: function() { + if ( this.selection ) + this.selection.off( null, null, this ); + if ( this.library ) + this.library.off( null, null, this ); + return media.View.prototype.dispose.apply( this, arguments ); + }, + + ready: function() { + this.refresh(); + }, + + set: function( id, view, options ) { + var list; + options = options || {}; + + // Accept an object with an `id` : `view` mapping. + if ( _.isObject( id ) ) { + _.each( id, function( view, id ) { + this.set( id, view, { silent: true }); + }, this ); + + } else { + if ( ! ( view instanceof Backbone.View ) ) { + view.classes = [ 'media-button-' + id ].concat( view.classes || [] ); + view = new media.view.Button( view ).render(); + } + + view.controller = view.controller || this.controller; + + this._views[ id ] = view; + + list = view.options.priority < 0 ? 'secondary' : 'primary'; + this[ list ].set( id, view, options ); + } + + if ( ! options.silent ) + this.refresh(); + + return this; + }, + + get: function( id ) { + return this._views[ id ]; + }, + + unset: function( id, options ) { + delete this._views[ id ]; + this.primary.unset( id, options ); + this.secondary.unset( id, options ); + + if ( ! options || ! options.silent ) + this.refresh(); + return this; + }, + + refresh: function() { + var state = this.controller.state(), + library = state.get('library'), + selection = state.get('selection'); + + _.each( this._views, function( button ) { + if ( ! button.model || ! button.options || ! button.options.requires ) + return; + + var requires = button.options.requires, + disabled = false; + + if ( requires.selection && selection && ! selection.length ) + disabled = true; + else if ( requires.library && library && ! library.length ) + disabled = true; + + button.model.set( 'disabled', disabled ); + }); + } + }); + + // wp.media.view.Toolbar.Select + // ---------------------------- + media.view.Toolbar.Select = media.view.Toolbar.extend({ + initialize: function() { + var options = this.options, + controller = options.controller, + selection = controller.state().get('selection'); + + _.bindAll( this, 'clickSelect' ); + + _.defaults( options, { + event: 'select', + state: false, + reset: true, + close: true, + text: l10n.select, + + // Does the button rely on the selection? + requires: { + selection: true + } + }); + + options.items = _.defaults( options.items || {}, { + select: { + style: 'primary', + text: options.text, + priority: 80, + click: this.clickSelect, + requires: options.requires + } + }); + + media.view.Toolbar.prototype.initialize.apply( this, arguments ); + }, + + clickSelect: function() { + var options = this.options, + controller = this.controller; + + if ( options.close ) + controller.close(); + + if ( options.event ) + controller.state().trigger( options.event ); + + if ( options.reset ) + controller.reset(); + + if ( options.state ) + controller.setState( options.state ); + } + }); + + // wp.media.view.Toolbar.Embed + // --------------------------- + media.view.Toolbar.Embed = media.view.Toolbar.Select.extend({ + initialize: function() { + _.defaults( this.options, { + text: l10n.insertIntoPost, + requires: false + }); + + media.view.Toolbar.Select.prototype.initialize.apply( this, arguments ); + }, + + refresh: function() { + var url = this.controller.state().props.get('url'); + this.get('select').model.set( 'disabled', ! url || url === 'http://' ); + + media.view.Toolbar.Select.prototype.refresh.apply( this, arguments ); + } + }); + + /** + * wp.media.view.Button + */ + media.view.Button = media.View.extend({ + tagName: 'a', + className: 'media-button', + attributes: { href: '#' }, + + events: { + 'click': 'click' + }, + + defaults: { + text: '', + style: '', + size: 'large', + disabled: false + }, + + initialize: function() { + // Create a model with the provided `defaults`. + this.model = new Backbone.Model( this.defaults ); + + // If any of the `options` have a key from `defaults`, apply its + // value to the `model` and remove it from the `options object. + _.each( this.defaults, function( def, key ) { + var value = this.options[ key ]; + if ( _.isUndefined( value ) ) + return; + + this.model.set( key, value ); + delete this.options[ key ]; + }, this ); + + this.model.on( 'change', this.render, this ); + }, + + render: function() { + var classes = [ 'button', this.className ], + model = this.model.toJSON(); + + if ( model.style ) + classes.push( 'button-' + model.style ); + + if ( model.size ) + classes.push( 'button-' + model.size ); + + classes = _.uniq( classes.concat( this.options.classes ) ); + this.el.className = classes.join(' '); + + this.$el.attr( 'disabled', model.disabled ); + this.$el.text( this.model.get('text') ); + + return this; + }, + + click: function( event ) { + if ( '#' === this.attributes.href ) + event.preventDefault(); + + if ( this.options.click && ! this.model.get('disabled') ) + this.options.click.apply( this, arguments ); + } + }); + + /** + * wp.media.view.ButtonGroup + */ + media.view.ButtonGroup = media.View.extend({ + tagName: 'div', + className: 'button-group button-large media-button-group', + + initialize: function() { + this.buttons = _.map( this.options.buttons || [], function( button ) { + if ( button instanceof Backbone.View ) + return button; + else + return new media.view.Button( button ).render(); + }); + + delete this.options.buttons; + + if ( this.options.classes ) + this.$el.addClass( this.options.classes ); + }, + + render: function() { + this.$el.html( $( _.pluck( this.buttons, 'el' ) ).detach() ); + return this; + } + }); + + /** + * wp.media.view.PriorityList + */ + + media.view.PriorityList = media.View.extend({ + tagName: 'div', + + initialize: function() { + this._views = {}; + + this.set( _.extend( {}, this._views, this.options.views ), { silent: true }); + delete this.options.views; + + if ( ! this.options.silent ) + this.render(); + }, + + set: function( id, view, options ) { + var priority, views, index; + + options = options || {}; + + // Accept an object with an `id` : `view` mapping. + if ( _.isObject( id ) ) { + _.each( id, function( view, id ) { + this.set( id, view ); + }, this ); + return this; + } + + if ( ! (view instanceof Backbone.View) ) + view = this.toView( view, id, options ); + + view.controller = view.controller || this.controller; + + this.unset( id ); + + priority = view.options.priority || 10; + views = this.views.get() || []; + + _.find( views, function( existing, i ) { + if ( existing.options.priority > priority ) { + index = i; + return true; + } + }); + + this._views[ id ] = view; + this.views.add( view, { + at: _.isNumber( index ) ? index : views.length || 0 + }); + + return this; + }, + + get: function( id ) { + return this._views[ id ]; + }, + + unset: function( id ) { + var view = this.get( id ); + + if ( view ) + view.remove(); + + delete this._views[ id ]; + return this; + }, + + toView: function( options ) { + return new media.View( options ); + } + }); + + /** + * wp.media.view.MenuItem + */ + media.view.MenuItem = media.View.extend({ + tagName: 'a', + className: 'media-menu-item', + + attributes: { + href: '#' + }, + + events: { + 'click': '_click' + }, + + _click: function( event ) { + var clickOverride = this.options.click; + + if ( event ) + event.preventDefault(); + + if ( clickOverride ) + clickOverride.call( this ); + else + this.click(); + }, + + click: function() { + var state = this.options.state; + if ( state ) + this.controller.setState( state ); + }, + + render: function() { + var options = this.options; + + if ( options.text ) + this.$el.text( options.text ); + else if ( options.html ) + this.$el.html( options.html ); + + return this; + } + }); + + /** + * wp.media.view.Menu + */ + media.view.Menu = media.view.PriorityList.extend({ + tagName: 'div', + className: 'media-menu', + property: 'state', + ItemView: media.view.MenuItem, + region: 'menu', + + toView: function( options, id ) { + options = options || {}; + options[ this.property ] = options[ this.property ] || id; + return new this.ItemView( options ).render(); + }, + + ready: function() { + media.view.PriorityList.prototype.ready.apply( this, arguments ); + this.visibility(); + }, + + set: function() { + media.view.PriorityList.prototype.set.apply( this, arguments ); + this.visibility(); + }, + + unset: function() { + media.view.PriorityList.prototype.unset.apply( this, arguments ); + this.visibility(); + }, + + visibility: function() { + var region = this.region, + view = this.controller[ region ].get(), + views = this.views.get(), + hide = ! views || views.length < 2; + + if ( this === view ) + this.controller.$el.toggleClass( 'hide-' + region, hide ); + }, + + select: function( id ) { + var view = this.get( id ); + + if ( ! view ) + return; + + this.deselect(); + view.$el.addClass('active'); + }, + + deselect: function() { + this.$el.children().removeClass('active'); + } + }); + + /** + * wp.media.view.RouterItem + */ + media.view.RouterItem = media.view.MenuItem.extend({ + click: function() { + var contentMode = this.options.contentMode; + if ( contentMode ) + this.controller.content.mode( contentMode ); + } + }); + + /** + * wp.media.view.Router + */ + media.view.Router = media.view.Menu.extend({ + tagName: 'div', + className: 'media-router', + property: 'contentMode', + ItemView: media.view.RouterItem, + region: 'router', + + initialize: function() { + this.controller.on( 'content:render', this.update, this ); + media.view.Menu.prototype.initialize.apply( this, arguments ); + }, + + update: function() { + var mode = this.controller.content.mode(); + if ( mode ) + this.select( mode ); + } + }); + + + /** + * wp.media.view.Sidebar + */ + media.view.Sidebar = media.view.PriorityList.extend({ + className: 'media-sidebar' + }); + + /** + * wp.media.view.Attachment + */ + media.view.Attachment = media.View.extend({ + tagName: 'li', + className: 'attachment', + template: media.template('attachment'), + + events: { + 'click .attachment-preview': 'toggleSelectionHandler', + 'change [data-setting]': 'updateSetting', + 'change [data-setting] input': 'updateSetting', + 'change [data-setting] select': 'updateSetting', + 'change [data-setting] textarea': 'updateSetting', + 'click .close': 'removeFromLibrary', + 'click .check': 'removeFromSelection', + 'click a': 'preventDefault' + }, + + buttons: {}, + + initialize: function() { + var selection = this.options.selection; + + this.model.on( 'change:sizes change:uploading change:caption change:title', this.render, this ); + this.model.on( 'change:percent', this.progress, this ); + + // Update the selection. + this.model.on( 'add', this.select, this ); + this.model.on( 'remove', this.deselect, this ); + if ( selection ) + selection.on( 'reset', this.updateSelect, this ); + + // Update the model's details view. + this.model.on( 'selection:single selection:unsingle', this.details, this ); + this.details( this.model, this.controller.state().get('selection') ); + }, + + dispose: function() { + var selection = this.options.selection; + + // Make sure all settings are saved before removing the view. + this.updateAll(); + + if ( selection ) + selection.off( null, null, this ); + + media.View.prototype.dispose.apply( this, arguments ); + return this; + }, + + render: function() { + var options = _.defaults( this.model.toJSON(), { + orientation: 'landscape', + uploading: false, + type: '', + subtype: '', + icon: '', + filename: '', + caption: '', + title: '', + dateFormatted: '', + width: '', + height: '', + compat: false, + alt: '', + description: '' + }); + + options.buttons = this.buttons; + options.describe = this.controller.state().get('describe'); + + if ( 'image' === options.type ) + options.size = this.imageSize(); + + options.can = {}; + if ( options.nonces ) { + options.can.remove = !! options.nonces['delete']; + options.can.save = !! options.nonces.update; + } + + if ( this.controller.state().get('allowLocalEdits') ) + options.allowLocalEdits = true; + + this.views.detach(); + this.$el.html( this.template( options ) ); + + this.$el.toggleClass( 'uploading', options.uploading ); + if ( options.uploading ) + this.$bar = this.$('.media-progress-bar div'); + else + delete this.$bar; + + // Check if the model is selected. + this.updateSelect(); + + // Update the save status. + this.updateSave(); + + this.views.render(); + + return this; + }, + + progress: function() { + if ( this.$bar && this.$bar.length ) + this.$bar.width( this.model.get('percent') + '%' ); + }, + + toggleSelectionHandler: function( event ) { + var method; + + if ( event.shiftKey ) + method = 'between'; + else if ( event.ctrlKey || event.metaKey ) + method = 'toggle'; + + this.toggleSelection({ + method: method + }); + }, + + toggleSelection: function( options ) { + var collection = this.collection, + selection = this.options.selection, + model = this.model, + method = options && options.method, + single, between, models, singleIndex, modelIndex; + + if ( ! selection ) + return; + + single = selection.single(); + method = _.isUndefined( method ) ? selection.multiple : method; + + // If the `method` is set to `between`, select all models that + // exist between the current and the selected model. + if ( 'between' === method && single && selection.multiple ) { + // If the models are the same, short-circuit. + if ( single === model ) + return; + + singleIndex = collection.indexOf( single ); + modelIndex = collection.indexOf( this.model ); + + if ( singleIndex < modelIndex ) + models = collection.models.slice( singleIndex, modelIndex + 1 ); + else + models = collection.models.slice( modelIndex, singleIndex + 1 ); + + selection.add( models ).single( model ); + return; + + // If the `method` is set to `toggle`, just flip the selection + // status, regardless of whether the model is the single model. + } else if ( 'toggle' === method ) { + selection[ this.selected() ? 'remove' : 'add' ]( model ).single( model ); + return; + } + + if ( method !== 'add' ) + method = 'reset'; + + if ( this.selected() ) { + // If the model is the single model, remove it. + // If it is not the same as the single model, + // it now becomes the single model. + selection[ single === model ? 'remove' : 'single' ]( model ); + } else { + // If the model is not selected, run the `method` on the + // selection. By default, we `reset` the selection, but the + // `method` can be set to `add` the model to the selection. + selection[ method ]( model ).single( model ); + } + }, + + updateSelect: function() { + this[ this.selected() ? 'select' : 'deselect' ](); + }, + + selected: function() { + var selection = this.options.selection; + if ( selection ) + return !! selection.getByCid( this.model.cid ); + }, + + select: function( model, collection ) { + var selection = this.options.selection; + + // Check if a selection exists and if it's the collection provided. + // If they're not the same collection, bail; we're in another + // selection's event loop. + if ( ! selection || ( collection && collection !== selection ) ) + return; + + this.$el.addClass('selected'); + }, + + deselect: function( model, collection ) { + var selection = this.options.selection; + + // Check if a selection exists and if it's the collection provided. + // If they're not the same collection, bail; we're in another + // selection's event loop. + if ( ! selection || ( collection && collection !== selection ) ) + return; + + this.$el.removeClass('selected'); + }, + + details: function( model, collection ) { + var selection = this.options.selection, + details; + + if ( selection !== collection ) + return; + + details = selection.single(); + this.$el.toggleClass( 'details', details === this.model ); + }, + + preventDefault: function( event ) { + event.preventDefault(); + }, + + imageSize: function( size ) { + var sizes = this.model.get('sizes'); + + size = size || 'medium'; + + // Use the provided image size if possible. + if ( sizes && sizes[ size ] ) { + return _.clone( sizes[ size ] ); + } else { + return { + url: this.model.get('url'), + width: this.model.get('width'), + height: this.model.get('height'), + orientation: this.model.get('orientation') + }; + } + }, + + updateSetting: function( event ) { + var $setting = $( event.target ).closest('[data-setting]'), + setting, value; + + if ( ! $setting.length ) + return; + + setting = $setting.data('setting'); + value = event.target.value; + + if ( this.model.get( setting ) !== value ) + this.save( setting, value ); + }, + + // Pass all the arguments to the model's save method. + // + // Records the aggregate status of all save requests and updates the + // view's classes accordingly. + save: function() { + var view = this, + save = this._save = this._save || { status: 'ready' }, + request = this.model.save.apply( this.model, arguments ), + requests = save.requests ? $.when( request, save.requests ) : request; + + // If we're waiting to remove 'Saved.', stop. + if ( save.savedTimer ) + clearTimeout( save.savedTimer ); + + this.updateSave('waiting'); + save.requests = requests; + requests.always( function() { + // If we've performed another request since this one, bail. + if ( save.requests !== requests ) + return; + + view.updateSave( requests.state() === 'resolved' ? 'complete' : 'error' ); + save.savedTimer = setTimeout( function() { + view.updateSave('ready'); + delete save.savedTimer; + }, 2000 ); + }); + + }, + + updateSave: function( status ) { + var save = this._save = this._save || { status: 'ready' }; + + if ( status && status !== save.status ) { + this.$el.removeClass( 'save-' + save.status ); + save.status = status; + } + + this.$el.addClass( 'save-' + save.status ); + return this; + }, + + updateAll: function() { + var $settings = this.$('[data-setting]'), + model = this.model, + changed; + + changed = _.chain( $settings ).map( function( el ) { + var $input = $('input, textarea, select, [value]', el ), + setting, value; + + if ( ! $input.length ) + return; + + setting = $(el).data('setting'); + value = $input.val(); + + // Record the value if it changed. + if ( model.get( setting ) !== value ) + return [ setting, value ]; + }).compact().object().value(); + + if ( ! _.isEmpty( changed ) ) + model.save( changed ); + }, + + removeFromLibrary: function( event ) { + // Stop propagation so the model isn't selected. + event.stopPropagation(); + + this.collection.remove( this.model ); + }, + + removeFromSelection: function( event ) { + var selection = this.options.selection; + if ( ! selection ) + return; + + // Stop propagation so the model isn't selected. + event.stopPropagation(); + + selection.remove( this.model ); + } + }); + + /** + * wp.media.view.Attachment.Library + */ + media.view.Attachment.Library = media.view.Attachment.extend({ + buttons: { + check: true + } + }); + + /** + * wp.media.view.Attachment.EditLibrary + */ + media.view.Attachment.EditLibrary = media.view.Attachment.extend({ + buttons: { + close: true + } + }); + + /** + * wp.media.view.Attachments + */ + media.view.Attachments = media.View.extend({ + tagName: 'ul', + className: 'attachments', + + cssTemplate: media.template('attachments-css'), + + events: { + 'scroll': 'scroll' + }, + + initialize: function() { + this.el.id = _.uniqueId('__attachments-view-'); + + _.defaults( this.options, { + refreshSensitivity: 200, + refreshThreshold: 3, + AttachmentView: media.view.Attachment, + sortable: false, + resize: true + }); + + this._viewsByCid = {}; + + this.collection.on( 'add', function( attachment, attachments, options ) { + this.views.add( this.createAttachmentView( attachment ), { + at: options.index + }); + }, this ); + + this.collection.on( 'remove', function( attachment, attachments, options ) { + var view = this._viewsByCid[ attachment.cid ]; + delete this._viewsByCid[ attachment.cid ]; + + if ( view ) + view.remove(); + }, this ); + + this.collection.on( 'reset', this.render, this ); + + // Throttle the scroll handler. + this.scroll = _.chain( this.scroll ).bind( this ).throttle( this.options.refreshSensitivity ).value(); + + this.initSortable(); + + _.bindAll( this, 'css' ); + this.model.on( 'change:edge change:gutter', this.css, this ); + this._resizeCss = _.debounce( _.bind( this.css, this ), this.refreshSensitivity ); + if ( this.options.resize ) + $(window).on( 'resize.attachments', this._resizeCss ); + this.css(); + }, + + dispose: function() { + this.collection.props.off( null, null, this ); + $(window).off( 'resize.attachments', this._resizeCss ); + media.View.prototype.dispose.apply( this, arguments ); + }, + + css: function() { + var $css = $( '#' + this.el.id + '-css' ); + + if ( $css.length ) + $css.remove(); + + media.view.Attachments.$head().append( this.cssTemplate({ + id: this.el.id, + edge: this.edge(), + gutter: this.model.get('gutter') + }) ); + }, + + edge: function() { + var edge = this.model.get('edge'), + gutter, width, columns; + + if ( ! this.$el.is(':visible') ) + return edge; + + gutter = this.model.get('gutter') * 2; + width = this.$el.width() - gutter; + columns = Math.ceil( width / ( edge + gutter ) ); + edge = Math.floor( ( width - ( columns * gutter ) ) / columns ); + return edge; + }, + + initSortable: function() { + var collection = this.collection; + + if ( ! this.options.sortable || ! $.fn.sortable ) + return; + + this.$el.sortable( _.extend({ + // If the `collection` has a `comparator`, disable sorting. + disabled: !! collection.comparator, + + // Prevent attachments from being dragged outside the bounding + // box of the list. + containment: this.$el, + + // Change the position of the attachment as soon as the + // mouse pointer overlaps a thumbnail. + tolerance: 'pointer', + + // Record the initial `index` of the dragged model. + start: function( event, ui ) { + ui.item.data('sortableIndexStart', ui.item.index()); + }, + + // Update the model's index in the collection. + // Do so silently, as the view is already accurate. + update: function( event, ui ) { + var model = collection.at( ui.item.data('sortableIndexStart') ), + comparator = collection.comparator; + + // Temporarily disable the comparator to prevent `add` + // from re-sorting. + delete collection.comparator; + + // Silently shift the model to its new index. + collection.remove( model, { + silent: true + }).add( model, { + silent: true, + at: ui.item.index() + }); + + // Restore the comparator. + collection.comparator = comparator; + + // Fire the `reset` event to ensure other collections sync. + collection.trigger( 'reset', collection ); + + // If the collection is sorted by menu order, + // update the menu order. + collection.saveMenuOrder(); + } + }, this.options.sortable ) ); + + // If the `orderby` property is changed on the `collection`, + // check to see if we have a `comparator`. If so, disable sorting. + collection.props.on( 'change:orderby', function() { + this.$el.sortable( 'option', 'disabled', !! collection.comparator ); + }, this ); + + this.collection.props.on( 'change:orderby', this.refreshSortable, this ); + this.refreshSortable(); + }, + + refreshSortable: function() { + if ( ! this.options.sortable || ! $.fn.sortable ) + return; + + // If the `collection` has a `comparator`, disable sorting. + var collection = this.collection, + orderby = collection.props.get('orderby'), + enabled = 'menuOrder' === orderby || ! collection.comparator; + + this.$el.sortable( 'option', 'disabled', ! enabled ); + }, + + createAttachmentView: function( attachment ) { + var view = new this.options.AttachmentView({ + controller: this.controller, + model: attachment, + collection: this.collection, + selection: this.options.selection + }); + + return this._viewsByCid[ attachment.cid ] = view; + }, + + prepare: function() { + // Create all of the Attachment views, and replace + // the list in a single DOM operation. + if ( this.collection.length ) { + this.views.set( this.collection.map( this.createAttachmentView, this ) ); + + // If there are no elements, clear the views and load some. + } else { + this.views.unset(); + this.collection.more().done( this.scroll ); + } + }, + + ready: function() { + // Trigger the scroll event to check if we're within the + // threshold to query for additional attachments. + this.scroll(); + }, + + scroll: function( event ) { + // @todo: is this still necessary? + if ( ! this.$el.is(':visible') ) + return; + + if ( this.collection.hasMore() && this.el.scrollHeight < this.el.scrollTop + ( this.el.clientHeight * this.options.refreshThreshold ) ) { + this.collection.more().done( this.scroll ); + } + } + }, { + $head: (function() { + var $head; + return function() { + return $head = $head || $('head'); + }; + }()) + }); + + /** + * wp.media.view.Search + */ + media.view.Search = media.View.extend({ + tagName: 'input', + className: 'search', + + attributes: { + type: 'search', + placeholder: l10n.search + }, + + events: { + 'input': 'search', + 'keyup': 'search', + 'change': 'search', + 'search': 'search' + }, + + render: function() { + this.el.value = this.model.escape('search'); + return this; + }, + + search: function( event ) { + if ( event.target.value ) + this.model.set( 'search', event.target.value ); + else + this.model.unset('search'); + } + }); + + /** + * wp.media.view.AttachmentFilters + */ + media.view.AttachmentFilters = media.View.extend({ + tagName: 'select', + className: 'attachment-filters', + + events: { + change: 'change' + }, + + keys: [], + + initialize: function() { + this.createFilters(); + _.extend( this.filters, this.options.filters ); + + // Build `
    + diff --git a/wp-includes/js/tinymce/wp-tinymce-schema.js b/wp-includes/js/tinymce/wp-tinymce-schema.js new file mode 100644 index 00000000..999687e6 --- /dev/null +++ b/wp-includes/js/tinymce/wp-tinymce-schema.js @@ -0,0 +1,940 @@ +/** + * TinyMCE Schema.js + * + * Duck-punched by WordPress core to support a sane schema superset. + * + * Copyright, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://www.tinymce.com/license + * Contributing: http://www.tinymce.com/contributing + */ + +(function(tinymce) { + var mapCache = {}, makeMap = tinymce.makeMap, each = tinymce.each; + + function split(str, delim) { + return str.split(delim || ','); + }; + + /** + * Unpacks the specified lookup and string data it will also parse it into an object + * map with sub object for it's children. This will later also include the attributes. + */ + function unpack(lookup, data) { + var key, elements = {}; + + function replace(value) { + return value.replace(/[A-Z]+/g, function(key) { + return replace(lookup[key]); + }); + }; + + // Unpack lookup + for (key in lookup) { + if (lookup.hasOwnProperty(key)) + lookup[key] = replace(lookup[key]); + } + + // Unpack and parse data into object map + replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g, function(str, name, attributes, children) { + attributes = split(attributes, '|'); + + elements[name] = { + attributes : makeMap(attributes), + attributesOrder : attributes, + children : makeMap(children, '|', {'#comment' : {}}) + } + }); + + return elements; + }; + + /** + * Returns the HTML5 schema and caches it in the mapCache. + */ + function getHTML5() { + var html5 = mapCache.html5; + + if (!html5) { + html5 = mapCache.html5 = unpack({ + A : 'accesskey|class|contextmenu|dir|draggable|dropzone|hidden|id|inert|itemid|itemprop|itemref|itemscope|itemtype|lang|spellcheck|style|tabindex|title|translate|item|role|subject|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup', + B : '#|a|abbr|area|audio|b|bdi|bdo|br|button|canvas|cite|code|command|data|datalist|del|dfn|em|embed|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|math|meta|meter|noscript|object|output|progress|q|ruby|s|samp|script|select|small|span|strong|sub|sup|svg|textarea|time|u|var|video|wbr', + C : '#|a|abbr|area|address|article|aside|audio|b|bdi|bdo|blockquote|br|button|canvas|cite|code|command|data|datalist|del|details|dfn|dialog|div|dl|em|embed|fieldset|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|math|menu|meta|meter|nav|noscript|ol|object|output|p|pre|progress|q|ruby|s|samp|script|section|select|small|span|strong|style|sub|sup|svg|table|textarea|time|u|ul|var|video|wbr' + }, 'html[A|manifest][body|head]' + + 'head[A][base|command|link|meta|noscript|script|style|title]' + + 'title[A][#]' + + 'base[A|href|target][]' + + 'link[A|href|rel|media|type|sizes|crossorigin|hreflang][]' + + 'meta[A|http-equiv|name|content|charset][]' + + 'style[A|type|media|scoped][#]' + + 'script[A|charset|type|src|defer|async|crossorigin][#]' + + 'noscript[A][C]' + + 'body[A|onafterprint|onbeforeprint|onbeforeunload|onblur|onerror|onfocus|onfullscreenchange|onfullscreenerror|onhashchange|onload|onmessage|onoffline|ononline|onpagehide|onpageshow|onpopstate|onresize|onscroll|onstorage|onunload][C]' + + 'section[A][C]' + + 'nav[A][C]' + + 'article[A][C]' + + 'aside[A][C]' + + 'h1[A][B]' + + 'h2[A][B]' + + 'h3[A][B]' + + 'h4[A][B]' + + 'h5[A][B]' + + 'h6[A][B]' + + 'hgroup[A][h1|h2|h3|h4|h5|h6]' + + 'header[A][C]' + + 'footer[A][C]' + + 'address[A][C]' + + 'p[A][B]' + + 'br[A][]' + + 'pre[A][B]' + + 'dialog[A|open][C|dd|dt]' + + 'blockquote[A|cite][C]' + + 'ol[A|start|reversed][li]' + + 'ul[A][li]' + + 'li[A|value][C]' + + 'dl[A][dd|dt]' + + 'dt[A][C|B]' + + 'dd[A][C]' + + 'a[A|href|target|download|ping|rel|media|type][C|B]' + + 'em[A][B]' + + 'strong[A][B]' + + 'small[A][B]' + + 's[A][B]' + + 'cite[A][B]' + + 'q[A|cite][B]' + + 'dfn[A][B]' + + 'abbr[A][B]' + + 'code[A][B]' + + 'var[A][B]' + + 'samp[A][B]' + + 'kbd[A][B]' + + 'sub[A][B]' + + 'sup[A][B]' + + 'i[A][B]' + + 'b[A][B]' + + 'u[A][B]' + + 'mark[A][B]' + + 'progress[A|value|max][B]' + + 'meter[A|value|min|max|low|high|optimum][B]' + + 'time[A|datetime][B]' + + 'ruby[A][B|rt|rp]' + + 'rt[A][B]' + + 'rp[A][B]' + + 'bdi[A][B]' + + 'bdo[A][B]' + + 'span[A][B]' + + 'ins[A|cite|datetime][C|B]' + + 'del[A|cite|datetime][C|B]' + + 'figure[A][C|legend|figcaption]' + + 'figcaption[A][C]' + + 'img[A|alt|src|srcset|crossorigin|usemap|ismap|width|height][]' + + 'iframe[A|name|src|srcdoc|height|width|sandbox|seamless|allowfullscreen][C|B]' + + 'embed[A|src|height|width|type][]' + + 'object[A|data|type|typemustmatch|name|usemap|form|width|height][C|B|param]' + + 'param[A|name|value][]' + + 'summary[A][B]' + + 'details[A|open][C|legend|summary]' + + 'command[A|type|label|icon|disabled|checked|radiogroup|command][]' + + 'menu[A|type|label][C|li]' + + 'legend[A][C|B]' + + 'div[A][C]' + + 'source[A|src|type|media][]' + + 'track[A|kind|src|srclang|label|default][]' + + 'audio[A|src|autobuffer|autoplay|loop|controls|crossorigin|preload|mediagroup|muted][C|source|track]' + + 'video[A|src|autobuffer|autoplay|loop|controls|width|height|poster|crossorigin|preload|mediagroup|muted][C|source|track]' + + 'hr[A][]' + + 'form[A|accept-charset|action|autocomplete|enctype|method|name|novalidate|target][C]' + + 'fieldset[A|disabled|form|name][C|legend]' + + 'label[A|form|for][B]' + + 'input[A|type|accept|alt|autocomplete|autofocus|checked|dirname|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|height|inputmode|list|max|maxlength|min|multiple|name|pattern|placeholder|readonly|required|size|src|step|value|width|files][]' + + 'button[A|autofocus|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|name|type|value][B]' + + 'select[A|autofocus|disabled|form|multiple|name|required|size][option|optgroup]' + + 'data[A|value][B]' + + 'datalist[A][B|option]' + + 'optgroup[A|disabled|label][option]' + + 'option[A|disabled|selected|label|value][#]' + + 'textarea[A|autocomplete|autofocus|cols|dirname|disabled|form|inputmode|maxlength|name|placeholder|readonly|required|rows|wrap][#]' + + 'keygen[A|autofocus|challenge|disabled|form|keytype|name][]' + + 'output[A|for|form|name][B]' + + 'canvas[A|width|height][a|button|input]' + + 'map[A|name][C|B]' + + 'area[A|alt|coords|shape|href|target|download|ping|rel|media|hreflang|type][]' + + 'math[A][]' + + 'svg[A][]' + + 'table[A][caption|colgroup|thead|tfoot|tbody|tr]' + + 'caption[A][C]' + + 'colgroup[A|span][col]' + + 'col[A|span][]' + + 'thead[A][tr]' + + 'tfoot[A][tr]' + + 'tbody[A][tr]' + + 'tr[A][th|td]' + + 'th[A|headers|rowspan|colspan|scope][C]' + + 'td[A|headers|rowspan|colspan][C]' + + 'wbr[A][]' + ); + } + + return html5; + }; + + /** + * Returns the HTML4 schema and caches it in the mapCache. + */ + function getHTML4() { + var html4 = mapCache.html4; + + if (!html4) { + // This is the XHTML 1.0 transitional elements with it's attributes and children packed to reduce it's size + html4 = mapCache.html4 = unpack({ + Z : 'H|K|N|O|P', + Y : 'X|form|R|Q', + ZG : 'E|span|width|align|char|charoff|valign', + X : 'p|T|div|U|W|isindex|fieldset|table', + ZF : 'E|align|char|charoff|valign', + W : 'pre|hr|blockquote|address|center|noframes', + ZE : 'abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height', + ZD : '[E][S]', + U : 'ul|ol|dl|menu|dir', + ZC : 'p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q', + T : 'h1|h2|h3|h4|h5|h6', + ZB : 'X|S|Q', + S : 'R|P', + ZA : 'a|G|J|M|O|P', + R : 'a|H|K|N|O', + Q : 'noscript|P', + P : 'ins|del|script', + O : 'input|select|textarea|label|button', + N : 'M|L', + M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym', + L : 'sub|sup', + K : 'J|I', + J : 'tt|i|b|u|s|strike', + I : 'big|small|font|basefont', + H : 'G|F', + G : 'br|span|bdo', + F : 'object|applet|img|map|iframe', + E : 'A|B|C', + D : 'accesskey|tabindex|onfocus|onblur', + C : 'onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup', + B : 'lang|xml:lang|dir', + A : 'id|class|style|title' + }, 'script[id|charset|type|language|src|defer|xml:space][]' + + 'style[B|id|type|media|title|xml:space][]' + + 'object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]' + + 'param[id|name|value|valuetype|type][]' + + 'p[E|align][#|S]' + + 'a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]' + + 'br[A|clear][]' + + 'span[E][#|S]' + + 'bdo[A|C|B][#|S]' + + 'applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]' + + 'h1[E|align][#|S]' + + 'img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]' + + 'map[B|C|A|name][X|form|Q|area]' + + 'h2[E|align][#|S]' + + 'iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]' + + 'h3[E|align][#|S]' + + 'tt[E][#|S]' + + 'i[E][#|S]' + + 'b[E][#|S]' + + 'u[E][#|S]' + + 's[E][#|S]' + + 'strike[E][#|S]' + + 'big[E][#|S]' + + 'small[E][#|S]' + + 'font[A|B|size|color|face][#|S]' + + 'basefont[id|size|color|face][]' + + 'em[E][#|S]' + + 'strong[E][#|S]' + + 'dfn[E][#|S]' + + 'code[E][#|S]' + + 'q[E|cite][#|S]' + + 'samp[E][#|S]' + + 'kbd[E][#|S]' + + 'var[E][#|S]' + + 'cite[E][#|S]' + + 'abbr[E][#|S]' + + 'acronym[E][#|S]' + + 'sub[E][#|S]' + + 'sup[E][#|S]' + + 'input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]' + + 'select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]' + + 'optgroup[E|disabled|label][option]' + + 'option[E|selected|disabled|label|value][]' + + 'textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]' + + 'label[E|for|accesskey|onfocus|onblur][#|S]' + + 'button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + + 'h4[E|align][#|S]' + + 'ins[E|cite|datetime][#|Y]' + + 'h5[E|align][#|S]' + + 'del[E|cite|datetime][#|Y]' + + 'h6[E|align][#|S]' + + 'div[E|align][#|Y]' + + 'ul[E|type|compact][li]' + + 'li[E|type|value][#|Y]' + + 'ol[E|type|compact|start][li]' + + 'dl[E|compact][dt|dd]' + + 'dt[E][#|S]' + + 'dd[E][#|Y]' + + 'menu[E|compact][li]' + + 'dir[E|compact][li]' + + 'pre[E|width|xml:space][#|ZA]' + + 'hr[E|align|noshade|size|width][]' + + 'blockquote[E|cite][#|Y]' + + 'address[E][#|S|p]' + + 'center[E][#|Y]' + + 'noframes[E][#|Y]' + + 'isindex[A|B|prompt][]' + + 'fieldset[E][#|legend|Y]' + + 'legend[E|accesskey|align][#|S]' + + 'table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]' + + 'caption[E|align][#|S]' + + 'col[ZG][]' + + 'colgroup[ZG][col]' + + 'thead[ZF][tr]' + + 'tr[ZF|bgcolor][th|td]' + + 'th[E|ZE][#|Y]' + + 'form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]' + + 'noscript[E][#|Y]' + + 'td[E|ZE][#|Y]' + + 'tfoot[ZF][tr]' + + 'tbody[ZF][tr]' + + 'area[E|D|shape|coords|href|nohref|alt|target][]' + + 'base[id|href|target][]' + + 'body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]' + ); + } + + return html4; + }; + + /** + * WordPress Core + * + * Returns a schema that is the result of a deep merge between the HTML5 + * and HTML4 schemas. + */ + function getSaneSchema() { + var cachedMapCache = mapCache, + html5, html4; + + if ( mapCache.sane ) + return mapCache.sane; + + // Bust the mapCache so we're not dealing with the other schema objects. + mapCache = {}; + html5 = getHTML5(); + html4 = getHTML4(); + mapCache = cachedMapCache; + + each( html4, function( html4settings, tag ) { + var html5settings = html5[ tag ], + difference = []; + + // Merge tags missing in HTML5 mode. + if ( ! html5settings ) { + html5[ tag ] = html4settings; + return; + } + + // Merge attributes missing from this HTML5 tag. + each( html4settings.attributes, function( attribute, key ) { + if ( ! html5settings.attributes[ key ] ) + html5settings.attributes[ key ] = attribute; + }); + + // Merge any missing attributes into the attributes order. + each( html4settings.attributesOrder, function( key ) { + if ( -1 === tinymce.inArray( html5settings.attributesOrder, key ) ) + difference.push( key ); + }); + + html5settings.attributesOrder = html5settings.attributesOrder.concat( difference ); + + // Merge children missing from this HTML5 tag. + each( html4settings.children, function( child, key ) { + if ( ! html5settings.children[ key ] ) + html5settings.children[ key ] = child; + }); + }); + + return mapCache.sane = html5; + } + + /** + * Schema validator class. + * + * @class tinymce.html.Schema + * @example + * if (tinymce.activeEditor.schema.isValidChild('p', 'span')) + * alert('span is valid child of p.'); + * + * if (tinymce.activeEditor.schema.getElementRule('p')) + * alert('P is a valid element.'); + * + * @class tinymce.html.Schema + * @version 3.4 + */ + + /** + * Constructs a new Schema instance. + * + * @constructor + * @method Schema + * @param {Object} settings Name/value settings object. + */ + tinymce.html.Schema = function(settings) { + var self = this, elements = {}, children = {}, patternElements = [], validStyles, schemaItems; + var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, blockElementsMap, nonEmptyElementsMap, customElementsMap = {}; + + // Creates an lookup table map object for the specified option or the default value + function createLookupTable(option, default_value, extend) { + var value = settings[option]; + + if (!value) { + // Get cached default map or make it if needed + value = mapCache[option]; + + if (!value) { + value = makeMap(default_value, ' ', makeMap(default_value.toUpperCase(), ' ')); + value = tinymce.extend(value, extend); + + mapCache[option] = value; + } + } else { + // Create custom map + value = makeMap(value, ',', makeMap(value.toUpperCase(), ' ')); + } + + return value; + }; + + settings = settings || {}; + + /** + * WordPress core uses a sane schema in place of the default "HTML5" schema. + */ + schemaItems = settings.schema == "html5" ? getSaneSchema() : getHTML4(); + + // Allow all elements and attributes if verify_html is set to false + if (settings.verify_html === false) + settings.valid_elements = '*[*]'; + + // Build styles list + if (settings.valid_styles) { + validStyles = {}; + + // Convert styles into a rule list + each(settings.valid_styles, function(value, key) { + validStyles[key] = tinymce.explode(value); + }); + } + + // Setup map objects + whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea'); + selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr'); + shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link meta param embed source wbr'); + boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls'); + nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap); + textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + + 'blockquote center dir fieldset header footer article section hgroup aside nav figure'); + blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + + 'th tr td li ol ul caption dl dt dd noscript menu isindex samp option datalist select optgroup', textBlockElementsMap); + + // Converts a wildcard expression string to a regexp for example *a will become /.*a/. + function patternToRegExp(str) { + return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$'); + }; + + // Parses the specified valid_elements string and adds to the current rules + // This function is a bit hard to read since it's heavily optimized for speed + function addValidElements(valid_elements) { + var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, + prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value, + elementRuleRegExp = /^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/, + attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/, + hasPatternsRegExp = /[*?+]/; + + if (valid_elements) { + // Split valid elements into an array with rules + valid_elements = split(valid_elements); + + if (elements['@']) { + globalAttributes = elements['@'].attributes; + globalAttributesOrder = elements['@'].attributesOrder; + } + + // Loop all rules + for (ei = 0, el = valid_elements.length; ei < el; ei++) { + // Parse element rule + matches = elementRuleRegExp.exec(valid_elements[ei]); + if (matches) { + // Setup local names for matches + prefix = matches[1]; + elementName = matches[2]; + outputName = matches[3]; + attrData = matches[4]; + + // Create new attributes and attributesOrder + attributes = {}; + attributesOrder = []; + + // Create the new element + element = { + attributes : attributes, + attributesOrder : attributesOrder + }; + + // Padd empty elements prefix + if (prefix === '#') + element.paddEmpty = true; + + // Remove empty elements prefix + if (prefix === '-') + element.removeEmpty = true; + + // Copy attributes from global rule into current rule + if (globalAttributes) { + for (key in globalAttributes) + attributes[key] = globalAttributes[key]; + + attributesOrder.push.apply(attributesOrder, globalAttributesOrder); + } + + // Attributes defined + if (attrData) { + attrData = split(attrData, '|'); + for (ai = 0, al = attrData.length; ai < al; ai++) { + matches = attrRuleRegExp.exec(attrData[ai]); + if (matches) { + attr = {}; + attrType = matches[1]; + attrName = matches[2].replace(/::/g, ':'); + prefix = matches[3]; + value = matches[4]; + + // Required + if (attrType === '!') { + element.attributesRequired = element.attributesRequired || []; + element.attributesRequired.push(attrName); + attr.required = true; + } + + // Denied from global + if (attrType === '-') { + delete attributes[attrName]; + attributesOrder.splice(tinymce.inArray(attributesOrder, attrName), 1); + continue; + } + + // Default value + if (prefix) { + // Default value + if (prefix === '=') { + element.attributesDefault = element.attributesDefault || []; + element.attributesDefault.push({name: attrName, value: value}); + attr.defaultValue = value; + } + + // Forced value + if (prefix === ':') { + element.attributesForced = element.attributesForced || []; + element.attributesForced.push({name: attrName, value: value}); + attr.forcedValue = value; + } + + // Required values + if (prefix === '<') + attr.validValues = makeMap(value, '?'); + } + + // Check for attribute patterns + if (hasPatternsRegExp.test(attrName)) { + element.attributePatterns = element.attributePatterns || []; + attr.pattern = patternToRegExp(attrName); + element.attributePatterns.push(attr); + } else { + // Add attribute to order list if it doesn't already exist + if (!attributes[attrName]) + attributesOrder.push(attrName); + + attributes[attrName] = attr; + } + } + } + } + + // Global rule, store away these for later usage + if (!globalAttributes && elementName == '@') { + globalAttributes = attributes; + globalAttributesOrder = attributesOrder; + } + + // Handle substitute elements such as b/strong + if (outputName) { + element.outputName = elementName; + elements[outputName] = element; + } + + // Add pattern or exact element + if (hasPatternsRegExp.test(elementName)) { + element.pattern = patternToRegExp(elementName); + patternElements.push(element); + } else + elements[elementName] = element; + } + } + } + }; + + function setValidElements(valid_elements) { + elements = {}; + patternElements = []; + + addValidElements(valid_elements); + + each(schemaItems, function(element, name) { + children[name] = element.children; + }); + }; + + // Adds custom non HTML elements to the schema + function addCustomElements(custom_elements) { + var customElementRegExp = /^(~)?(.+)$/; + + if (custom_elements) { + each(split(custom_elements), function(rule) { + var matches = customElementRegExp.exec(rule), + inline = matches[1] === '~', + cloneName = inline ? 'span' : 'div', + name = matches[2]; + + children[name] = children[cloneName]; + customElementsMap[name] = cloneName; + + // If it's not marked as inline then add it to valid block elements + if (!inline) { + blockElementsMap[name.toUpperCase()] = {}; + blockElementsMap[name] = {}; + } + + // Add elements clone if needed + if (!elements[name]) { + elements[name] = elements[cloneName]; + } + + // Add custom elements at span/div positions + each(children, function(element, child) { + if (element[cloneName]) + element[name] = element[cloneName]; + }); + }); + } + }; + + // Adds valid children to the schema object + function addValidChildren(valid_children) { + var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; + + if (valid_children) { + each(split(valid_children), function(rule) { + var matches = childRuleRegExp.exec(rule), parent, prefix; + + if (matches) { + prefix = matches[1]; + + // Add/remove items from default + if (prefix) + parent = children[matches[2]]; + else + parent = children[matches[2]] = {'#comment' : {}}; + + parent = children[matches[2]]; + + each(split(matches[3], '|'), function(child) { + if (prefix === '-') + delete parent[child]; + else + parent[child] = {}; + }); + } + }); + } + }; + + function getElementRule(name) { + var element = elements[name], i; + + // Exact match found + if (element) + return element; + + // No exact match then try the patterns + i = patternElements.length; + while (i--) { + element = patternElements[i]; + + if (element.pattern.test(name)) + return element; + } + }; + + if (!settings.valid_elements) { + // No valid elements defined then clone the elements from the schema spec + each(schemaItems, function(element, name) { + elements[name] = { + attributes : element.attributes, + attributesOrder : element.attributesOrder + }; + + children[name] = element.children; + }); + + // Switch these on HTML4 + if (settings.schema != "html5") { + each(split('strong/b,em/i'), function(item) { + item = split(item, '/'); + elements[item[1]].outputName = item[0]; + }); + } + + // Add default alt attribute for images + elements.img.attributesDefault = [{name: 'alt', value: ''}]; + + // Remove these if they are empty by default + each(split('ol,ul,sub,sup,blockquote,span,font,a,table,tbody,tr,strong,em,b,i'), function(name) { + if (elements[name]) { + elements[name].removeEmpty = true; + } + }); + + // Padd these by default + each(split('p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption'), function(name) { + elements[name].paddEmpty = true; + }); + } else + setValidElements(settings.valid_elements); + + addCustomElements(settings.custom_elements); + addValidChildren(settings.valid_children); + addValidElements(settings.extended_valid_elements); + + // Todo: Remove this when we fix list handling to be valid + addValidChildren('+ol[ul|ol],+ul[ul|ol]'); + + // Delete invalid elements + if (settings.invalid_elements) { + tinymce.each(tinymce.explode(settings.invalid_elements), function(item) { + if (elements[item]) + delete elements[item]; + }); + } + + // If the user didn't allow span only allow internal spans + if (!getElementRule('span')) + addValidElements('span[!data-mce-type|*]'); + + /** + * Name/value map object with valid parents and children to those parents. + * + * @example + * children = { + * div:{p:{}, h1:{}} + * }; + * @field children + * @type {Object} + */ + self.children = children; + + /** + * Name/value map object with valid styles for each element. + * + * @field styles + * @type {Object} + */ + self.styles = validStyles; + + /** + * Returns a map with boolean attributes. + * + * @method getBoolAttrs + * @return {Object} Name/value lookup map for boolean attributes. + */ + self.getBoolAttrs = function() { + return boolAttrMap; + }; + + /** + * Returns a map with block elements. + * + * @method getBlockElements + * @return {Object} Name/value lookup map for block elements. + */ + self.getBlockElements = function() { + return blockElementsMap; + }; + + /** + * Returns a map with text block elements. Such as: p,h1-h6,div,address + * + * @method getTextBlockElements + * @return {Object} Name/value lookup map for block elements. + */ + self.getTextBlockElements = function() { + return textBlockElementsMap; + }; + + /** + * Returns a map with short ended elements such as BR or IMG. + * + * @method getShortEndedElements + * @return {Object} Name/value lookup map for short ended elements. + */ + self.getShortEndedElements = function() { + return shortEndedElementsMap; + }; + + /** + * Returns a map with self closing tags such as
  • . + * + * @method getSelfClosingElements + * @return {Object} Name/value lookup map for self closing tags elements. + */ + self.getSelfClosingElements = function() { + return selfClosingElementsMap; + }; + + /** + * Returns a map with elements that should be treated as contents regardless if it has text + * content in them or not such as TD, VIDEO or IMG. + * + * @method getNonEmptyElements + * @return {Object} Name/value lookup map for non empty elements. + */ + self.getNonEmptyElements = function() { + return nonEmptyElementsMap; + }; + + /** + * Returns a map with elements where white space is to be preserved like PRE or SCRIPT. + * + * @method getWhiteSpaceElements + * @return {Object} Name/value lookup map for white space elements. + */ + self.getWhiteSpaceElements = function() { + return whiteSpaceElementsMap; + }; + + /** + * Returns true/false if the specified element and it's child is valid or not + * according to the schema. + * + * @method isValidChild + * @param {String} name Element name to check for. + * @param {String} child Element child to verify. + * @return {Boolean} True/false if the element is a valid child of the specified parent. + */ + self.isValidChild = function(name, child) { + var parent = children[name]; + + return !!(parent && parent[child]); + }; + + /** + * Returns true/false if the specified element name and optional attribute is + * valid according to the schema. + * + * @method isValid + * @param {String} name Name of element to check. + * @param {String} attr Optional attribute name to check for. + * @return {Boolean} True/false if the element and attribute is valid. + */ + self.isValid = function(name, attr) { + var attrPatterns, i, rule = getElementRule(name); + + // Check if it's a valid element + if (rule) { + if (attr) { + // Check if attribute name exists + if (rule.attributes[attr]) { + return true; + } + + // Check if attribute matches a regexp pattern + attrPatterns = rule.attributePatterns; + if (attrPatterns) { + i = attrPatterns.length; + while (i--) { + if (attrPatterns[i].pattern.test(name)) { + return true; + } + } + } + } else { + return true; + } + } + + // No match + return false; + }; + + /** + * Returns true/false if the specified element is valid or not + * according to the schema. + * + * @method getElementRule + * @param {String} name Element name to check for. + * @return {Object} Element object or undefined if the element isn't valid. + */ + self.getElementRule = getElementRule; + + /** + * Returns an map object of all custom elements. + * + * @method getCustomElements + * @return {Object} Name/value map object of all custom elements. + */ + self.getCustomElements = function() { + return customElementsMap; + }; + + /** + * Parses a valid elements string and adds it to the schema. The valid elements format is for example "element[attr=default|otherattr]". + * Existing rules will be replaced with the ones specified, so this extends the schema. + * + * @method addValidElements + * @param {String} valid_elements String in the valid elements format to be parsed. + */ + self.addValidElements = addValidElements; + + /** + * Parses a valid elements string and sets it to the schema. The valid elements format is for example "element[attr=default|otherattr]". + * Existing rules will be replaced with the ones specified, so this extends the schema. + * + * @method setValidElements + * @param {String} valid_elements String in the valid elements format to be parsed. + */ + self.setValidElements = setValidElements; + + /** + * Adds custom non HTML elements to the schema. + * + * @method addCustomElements + * @param {String} custom_elements Comma separated list of custom elements to add. + */ + self.addCustomElements = addCustomElements; + + /** + * Parses a valid children string and adds them to the schema structure. The valid children format is for example: "element[child1|child2]". + * + * @method addValidChildren + * @param {String} valid_children Valid children elements string to parse + */ + self.addValidChildren = addValidChildren; + + self.elements = elements; + }; +})(tinymce); diff --git a/wp-includes/js/tinymce/wp-tinymce.js.gz b/wp-includes/js/tinymce/wp-tinymce.js.gz index b8ed7249f3534e25d275a094be803c9813e16c68..55d01ff113e87f3426fef82254ab6340ae6b76b6 100644 GIT binary patch literal 115683 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

    Cl3YiR=2nDL2R-xn07d;uhKmxWa2OqOmM9Yc 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/uwQg3N{^U0mmiZ(P$=7_DHY?0E_nw!tdn2C>;-%b{Yfn^)Dybr z6ZXy<3#|XSRI7cU?xrS-saL6i_(w@s^^9An;UZnfp$EPmJyLh!@7*ucy3HJ6SNtyB zw`9q=H)0B&IIKRai@+~EeO!M5cYFB=e&8j~PlB6Xo(U{-?|C_H&U(vceoo<(?4U{> zhOBPCf91(5t!a6_Ff1!eEl!kE7WS*LoS}aUbjor>jUX{r=~ukHMW^e_z1;hJf*1lX zA3QF5Qbtq(%(17Gz$=44-?_$?SI0oVk!*U)4qV>0uivq)WhLk2+h6VMdKvB7d%X(< z!j9PE_vrOSwo?l4{U$`sL^A3?ra_b#7qm!XG1J){(&V$2YJwhR9+uC}w;BT6t?#cf z0cpi%bp7QPC~a7+1uN^Ah7p#exKMX)L{Nv5>v|uw?W%%lgsEv8V`@3Uklzpn9~W;L_Wu#-f%U z1)weCF^yt4P%E^00M8ZgoXmj#S+Y^*K-@z-YL~y4gw(09LF9)wO-@ESP`LiyB0qip z?dt!^Qqs597<*s2X2oLCKd@+4?XMP;4!=cEx>ZbSw9GU3J|lD7rUUbBB1eVTlzil$ zO~UCd+(=RtlWk}{{6}dvGGN|Du%Xx{N0o7{jQxTpc8ay@7-Xwt@~nKxJ=4DAh|q_0 zsoKhVv^m)A1eaL9W|>j1#VyYUgFQC7MyjTmPVVrws4WsA*^OxjRWw1>(gw5eyV}z2 zFrBbTECIKR7$9lX^ZTelWl^BV-o3SGwHYJ!xbsRX9RG9Sm{+_J4i-` z!M|m!V5Hf!#40dm2;if(d&&e.reduce===d)return r&&(t=T.bind(t,r)),i?e.reduce(t,n):e.reduce(t);N(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.reduceRight=T.foldr=function(e,t,n,r){var i=arguments.length>2;if(v&&e.reduceRight===v)return r&&(t=T.bind(t,r)),arguments.length>2?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=T.keys(e);s=o.length}N(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.find=T.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},T.filter=T.select=function(e,t,n){var r=[];return m&&e.filter===m?e.filter(t,n):(N(e,function(e,i,s){t.call(n,e,i,s)&&(r[r.length]=e)}),r)},T.reject=function(e,t,n){var r=[];return N(e,function(e,i,s){t.call(n,e,i,s)||(r[r.length]=e)}),r},T.every=T.all=function(e,t,r){t||(t=T.identity);var i=!0;return g&&e.every===g?e.every(t,r):(N(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=T.some=T.any=function(e,t,r){t||(t=T.identity);var i=!1;return y&&e.some===y?e.some(t,r):(N(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};T.contains=T.include=function(e,t){var n=!1;return b&&e.indexOf===b?e.indexOf(t)!=-1:(n=C(e,function(e){return e===t}),n)},T.invoke=function(e,t){var n=u.call(arguments,2);return T.map(e,function(e){return(T.isFunction(t)?t:e[t]).apply(e,n)})},T.pluck=function(e,t){return T.map(e,function(e){return e[t]})},T.where=function(e,t){return T.isEmpty(t)?[]:T.filter(e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},T.max=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&T.isEmpty(e))return-Infinity;var r={computed:-Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},T.min=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&T.isEmpty(e))return Infinity;var r={computed:Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;or||n===void 0)return 1;if(n>>1;n.call(r,e[u])=0})})},T.difference=function(e){var t=a.apply(r,u.call(arguments,1));return T.filter(e,function(e){return!T.contains(t,e)})},T.zip=function(){var e=u.call(arguments),t=T.max(T.pluck(e,"length")),n=new Array(t);for(var r=0;r=0;n--)t=[e[n].apply(this,t)];return t[0]}},T.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},T.keys=S||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)T.has(e,n)&&(t[t.length]=n);return t},T.values=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push(e[n]);return t},T.pairs=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push([n,e[n]]);return t},T.invert=function(e){var t={};for(var n in e)T.has(e,n)&&(t[e[n]]=n);return t},T.functions=T.methods=function(e){var t=[];for(var n in e)T.isFunction(e[n])&&t.push(n);return t.sort()},T.extend=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]=t[n]}),e},T.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return N(n,function(n){n in e&&(t[n]=e[n])}),t},T.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)T.contains(n,i)||(t[i]=e[i]);return t},T.defaults=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]==null&&(e[n]=t[n])}),e},T.clone=function(e){return T.isObject(e)?T.isArray(e)?e.slice():T.extend({},e):e},T.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof T&&(e=e._wrapped),t instanceof T&&(t=t._wrapped);var i=l.call(e);if(i!=l.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,f=t.constructor;if(a!==f&&!(T.isFunction(a)&&a instanceof a&&T.isFunction(f)&&f instanceof f))return!1;for(var c in e)if(T.has(e,c)){o++;if(!(u=T.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(T.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};T.isEqual=function(e,t){return M(e,t,[],[])},T.isEmpty=function(e){if(e==null)return!0;if(T.isArray(e)||T.isString(e))return e.length===0;for(var t in e)if(T.has(e,t))return!1;return!0},T.isElement=function(e){return!!e&&e.nodeType===1},T.isArray=E||function(e){return l.call(e)=="[object Array]"},T.isObject=function(e){return e===Object(e)},N(["Arguments","Function","String","Number","Date","RegExp"],function(e){T["is"+e]=function(t){return l.call(t)=="[object "+e+"]"}}),T.isArguments(arguments)||(T.isArguments=function(e){return!!e&&!!T.has(e,"callee")}),typeof /./!="function"&&(T.isFunction=function(e){return typeof e=="function"}),T.isFinite=function(e){return T.isNumber(e)&&isFinite(e)},T.isNaN=function(e){return T.isNumber(e)&&e!=+e},T.isBoolean=function(e){return e===!0||e===!1||l.call(e)=="[object Boolean]"},T.isNull=function(e){return e===null},T.isUndefined=function(e){return e===void 0},T.has=function(e,t){return c.call(e,t)},T.noConflict=function(){return e._=t,this},T.identity=function(e){return e},T.times=function(e,t,n){for(var r=0;r":">",'"':""","'":"'","/":"/"}};_.unescape=T.invert(_.escape);var D={escape:new RegExp("["+T.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+T.keys(_.unescape).join("|")+")","g")};T.each(["escape","unescape"],function(e){T[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),T.result=function(e,t){if(e==null)return null;var n=e[t];return T.isFunction(n)?n.call(e):n},T.mixin=function(e){N(T.functions(e),function(t){var n=T[t]=e[t];T.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(T,e))}})};var P=0;T.uniqueId=function(e){var t=P++;return e?e+t:t},T.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;T.template=function(e,t,n){n=T.defaults({},n,T.templateSettings);var r=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),i=0,s="__p+='";e.replace(r,function(t,n,r,o,u){s+=e.slice(i,u).replace(j,function(e){return"\\"+B[e]}),s+=n?"'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?"'+\n((__t=("+r+"))==null?'':__t)+\n'":o?"';\n"+o+"\n__p+='":"",i=u+t.length}),s+="';\n",n.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{var o=new Function(n.variable||"obj","_",s)}catch(u){throw u.source=s,u}if(t)return o(t,T);var a=function(e){return o.call(this,e,T)};return a.source="function("+(n.variable||"obj")+"){\n"+s+"}",a},T.chain=function(e){return T(e).chain()};var F=function(e){return this._chain?T(e).chain():e};T.mixin(T),N(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];T.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),N(["concat","join","slice"],function(e){var t=r[e];T.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),T.extend(T.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); \ No newline at end of file diff --git a/wp-admin/js/utils.dev.js b/wp-includes/js/utils.js similarity index 100% rename from wp-admin/js/utils.dev.js rename to wp-includes/js/utils.js diff --git a/wp-admin/js/utils.js b/wp-includes/js/utils.min.js similarity index 100% rename from wp-admin/js/utils.js rename to wp-includes/js/utils.min.js diff --git a/wp-includes/js/wp-ajax-response.dev.js b/wp-includes/js/wp-ajax-response.dev.js deleted file mode 100644 index d5b003cf..00000000 --- a/wp-includes/js/wp-ajax-response.dev.js +++ /dev/null @@ -1,64 +0,0 @@ -var wpAjax = jQuery.extend( { - unserialize: function( s ) { - var r = {}, q, pp, i, p; - if ( !s ) { return r; } - q = s.split('?'); if ( q[1] ) { s = q[1]; } - pp = s.split('&'); - for ( i in pp ) { - if ( jQuery.isFunction(pp.hasOwnProperty) && !pp.hasOwnProperty(i) ) { continue; } - p = pp[i].split('='); - r[p[0]] = p[1]; - } - return r; - }, - parseAjaxResponse: function( x, r, e ) { // 1 = good, 0 = strange (bad data?), -1 = you lack permission - var parsed = {}, re = jQuery('#' + r).html(''), err = ''; - - if ( x && typeof x == 'object' && x.getElementsByTagName('wp_ajax') ) { - parsed.responses = []; - parsed.errors = false; - jQuery('response', x).each( function() { - var th = jQuery(this), child = jQuery(this.firstChild), response; - response = { action: th.attr('action'), what: child.get(0).nodeName, id: child.attr('id'), oldId: child.attr('old_id'), position: child.attr('position') }; - response.data = jQuery( 'response_data', child ).text(); - response.supplemental = {}; - if ( !jQuery( 'supplemental', child ).children().each( function() { - response.supplemental[this.nodeName] = jQuery(this).text(); - } ).size() ) { response.supplemental = false } - response.errors = []; - if ( !jQuery('wp_error', child).each( function() { - var code = jQuery(this).attr('code'), anError, errorData, formField; - anError = { code: code, message: this.firstChild.nodeValue, data: false }; - errorData = jQuery('wp_error_data[code="' + code + '"]', x); - if ( errorData ) { anError.data = errorData.get(); } - formField = jQuery( 'form-field', errorData ).text(); - if ( formField ) { code = formField; } - if ( e ) { wpAjax.invalidateForm( jQuery('#' + e + ' :input[name="' + code + '"]' ).parents('.form-field:first') ); } - err += '

    ' + anError.message + '

    '; - response.errors.push( anError ); - parsed.errors = true; - } ).size() ) { response.errors = false; } - parsed.responses.push( response ); - } ); - if ( err.length ) { re.html( '
    ' + err + '
    ' ); } - return parsed; - } - if ( isNaN(x) ) { return !re.html('

    ' + x + '

    '); } - x = parseInt(x,10); - if ( -1 == x ) { return !re.html('

    ' + wpAjax.noPerm + '

    '); } - else if ( 0 === x ) { return !re.html('

    ' + wpAjax.broken + '

    '); } - return true; - }, - invalidateForm: function ( selector ) { - return jQuery( selector ).addClass( 'form-invalid' ).find('input:visible').change( function() { jQuery(this).closest('.form-invalid').removeClass( 'form-invalid' ); } ); - }, - validateForm: function( selector ) { - selector = jQuery( selector ); - return !wpAjax.invalidateForm( selector.find('.form-required').filter( function() { return jQuery('input:visible', this).val() == ''; } ) ).size(); - } -}, wpAjax || { noPerm: 'You do not have permission to do that.', broken: 'An unidentified error has occurred.' } ); - -// Basic form validation -jQuery(document).ready( function($){ - $('form.validate').submit( function() { return wpAjax.validateForm( $(this) ); } ); -}); diff --git a/wp-includes/js/wp-ajax-response.js b/wp-includes/js/wp-ajax-response.js index bdfa53ab..d5b003cf 100644 --- a/wp-includes/js/wp-ajax-response.js +++ b/wp-includes/js/wp-ajax-response.js @@ -1 +1,64 @@ -var wpAjax=jQuery.extend({unserialize:function(c){var d={},e,a,b,f;if(!c){return d}e=c.split("?");if(e[1]){c=e[1]}a=c.split("&");for(b in a){if(jQuery.isFunction(a.hasOwnProperty)&&!a.hasOwnProperty(b)){continue}f=a[b].split("=");d[f[0]]=f[1]}return d},parseAjaxResponse:function(a,f,g){var b={},c=jQuery("#"+f).html(""),d="";if(a&&typeof a=="object"&&a.getElementsByTagName("wp_ajax")){b.responses=[];b.errors=false;jQuery("response",a).each(function(){var h=jQuery(this),i=jQuery(this.firstChild),e;e={action:h.attr("action"),what:i.get(0).nodeName,id:i.attr("id"),oldId:i.attr("old_id"),position:i.attr("position")};e.data=jQuery("response_data",i).text();e.supplemental={};if(!jQuery("supplemental",i).children().each(function(){e.supplemental[this.nodeName]=jQuery(this).text()}).size()){e.supplemental=false}e.errors=[];if(!jQuery("wp_error",i).each(function(){var j=jQuery(this).attr("code"),m,l,k;m={code:j,message:this.firstChild.nodeValue,data:false};l=jQuery('wp_error_data[code="'+j+'"]',a);if(l){m.data=l.get()}k=jQuery("form-field",l).text();if(k){j=k}if(g){wpAjax.invalidateForm(jQuery("#"+g+' :input[name="'+j+'"]').parents(".form-field:first"))}d+="

    "+m.message+"

    ";e.errors.push(m);b.errors=true}).size()){e.errors=false}b.responses.push(e)});if(d.length){c.html('
    '+d+"
    ")}return b}if(isNaN(a)){return !c.html('

    '+a+"

    ")}a=parseInt(a,10);if(-1==a){return !c.html('

    '+wpAjax.noPerm+"

    ")}else{if(0===a){return !c.html('

    '+wpAjax.broken+"

    ")}}return true},invalidateForm:function(a){return jQuery(a).addClass("form-invalid").find("input:visible").change(function(){jQuery(this).closest(".form-invalid").removeClass("form-invalid")})},validateForm:function(a){a=jQuery(a);return !wpAjax.invalidateForm(a.find(".form-required").filter(function(){return jQuery("input:visible",this).val()==""})).size()}},wpAjax||{noPerm:"You do not have permission to do that.",broken:"An unidentified error has occurred."});jQuery(document).ready(function(a){a("form.validate").submit(function(){return wpAjax.validateForm(a(this))})}); \ No newline at end of file +var wpAjax = jQuery.extend( { + unserialize: function( s ) { + var r = {}, q, pp, i, p; + if ( !s ) { return r; } + q = s.split('?'); if ( q[1] ) { s = q[1]; } + pp = s.split('&'); + for ( i in pp ) { + if ( jQuery.isFunction(pp.hasOwnProperty) && !pp.hasOwnProperty(i) ) { continue; } + p = pp[i].split('='); + r[p[0]] = p[1]; + } + return r; + }, + parseAjaxResponse: function( x, r, e ) { // 1 = good, 0 = strange (bad data?), -1 = you lack permission + var parsed = {}, re = jQuery('#' + r).html(''), err = ''; + + if ( x && typeof x == 'object' && x.getElementsByTagName('wp_ajax') ) { + parsed.responses = []; + parsed.errors = false; + jQuery('response', x).each( function() { + var th = jQuery(this), child = jQuery(this.firstChild), response; + response = { action: th.attr('action'), what: child.get(0).nodeName, id: child.attr('id'), oldId: child.attr('old_id'), position: child.attr('position') }; + response.data = jQuery( 'response_data', child ).text(); + response.supplemental = {}; + if ( !jQuery( 'supplemental', child ).children().each( function() { + response.supplemental[this.nodeName] = jQuery(this).text(); + } ).size() ) { response.supplemental = false } + response.errors = []; + if ( !jQuery('wp_error', child).each( function() { + var code = jQuery(this).attr('code'), anError, errorData, formField; + anError = { code: code, message: this.firstChild.nodeValue, data: false }; + errorData = jQuery('wp_error_data[code="' + code + '"]', x); + if ( errorData ) { anError.data = errorData.get(); } + formField = jQuery( 'form-field', errorData ).text(); + if ( formField ) { code = formField; } + if ( e ) { wpAjax.invalidateForm( jQuery('#' + e + ' :input[name="' + code + '"]' ).parents('.form-field:first') ); } + err += '

    ' + anError.message + '

    '; + response.errors.push( anError ); + parsed.errors = true; + } ).size() ) { response.errors = false; } + parsed.responses.push( response ); + } ); + if ( err.length ) { re.html( '
    ' + err + '
    ' ); } + return parsed; + } + if ( isNaN(x) ) { return !re.html('

    ' + x + '

    '); } + x = parseInt(x,10); + if ( -1 == x ) { return !re.html('

    ' + wpAjax.noPerm + '

    '); } + else if ( 0 === x ) { return !re.html('

    ' + wpAjax.broken + '

    '); } + return true; + }, + invalidateForm: function ( selector ) { + return jQuery( selector ).addClass( 'form-invalid' ).find('input:visible').change( function() { jQuery(this).closest('.form-invalid').removeClass( 'form-invalid' ); } ); + }, + validateForm: function( selector ) { + selector = jQuery( selector ); + return !wpAjax.invalidateForm( selector.find('.form-required').filter( function() { return jQuery('input:visible', this).val() == ''; } ) ).size(); + } +}, wpAjax || { noPerm: 'You do not have permission to do that.', broken: 'An unidentified error has occurred.' } ); + +// Basic form validation +jQuery(document).ready( function($){ + $('form.validate').submit( function() { return wpAjax.validateForm( $(this) ); } ); +}); diff --git a/wp-includes/js/wp-ajax-response.min.js b/wp-includes/js/wp-ajax-response.min.js new file mode 100644 index 00000000..bdfa53ab --- /dev/null +++ b/wp-includes/js/wp-ajax-response.min.js @@ -0,0 +1 @@ +var wpAjax=jQuery.extend({unserialize:function(c){var d={},e,a,b,f;if(!c){return d}e=c.split("?");if(e[1]){c=e[1]}a=c.split("&");for(b in a){if(jQuery.isFunction(a.hasOwnProperty)&&!a.hasOwnProperty(b)){continue}f=a[b].split("=");d[f[0]]=f[1]}return d},parseAjaxResponse:function(a,f,g){var b={},c=jQuery("#"+f).html(""),d="";if(a&&typeof a=="object"&&a.getElementsByTagName("wp_ajax")){b.responses=[];b.errors=false;jQuery("response",a).each(function(){var h=jQuery(this),i=jQuery(this.firstChild),e;e={action:h.attr("action"),what:i.get(0).nodeName,id:i.attr("id"),oldId:i.attr("old_id"),position:i.attr("position")};e.data=jQuery("response_data",i).text();e.supplemental={};if(!jQuery("supplemental",i).children().each(function(){e.supplemental[this.nodeName]=jQuery(this).text()}).size()){e.supplemental=false}e.errors=[];if(!jQuery("wp_error",i).each(function(){var j=jQuery(this).attr("code"),m,l,k;m={code:j,message:this.firstChild.nodeValue,data:false};l=jQuery('wp_error_data[code="'+j+'"]',a);if(l){m.data=l.get()}k=jQuery("form-field",l).text();if(k){j=k}if(g){wpAjax.invalidateForm(jQuery("#"+g+' :input[name="'+j+'"]').parents(".form-field:first"))}d+="

    "+m.message+"

    ";e.errors.push(m);b.errors=true}).size()){e.errors=false}b.responses.push(e)});if(d.length){c.html('
    '+d+"
    ")}return b}if(isNaN(a)){return !c.html('

    '+a+"

    ")}a=parseInt(a,10);if(-1==a){return !c.html('

    '+wpAjax.noPerm+"

    ")}else{if(0===a){return !c.html('

    '+wpAjax.broken+"

    ")}}return true},invalidateForm:function(a){return jQuery(a).addClass("form-invalid").find("input:visible").change(function(){jQuery(this).closest(".form-invalid").removeClass("form-invalid")})},validateForm:function(a){a=jQuery(a);return !wpAjax.invalidateForm(a.find(".form-required").filter(function(){return jQuery("input:visible",this).val()==""})).size()}},wpAjax||{noPerm:"You do not have permission to do that.",broken:"An unidentified error has occurred."});jQuery(document).ready(function(a){a("form.validate").submit(function(){return wpAjax.validateForm(a(this))})}); \ No newline at end of file diff --git a/wp-includes/js/wp-list-revisions.dev.js b/wp-includes/js/wp-list-revisions.dev.js deleted file mode 100644 index 9c702c65..00000000 --- a/wp-includes/js/wp-list-revisions.dev.js +++ /dev/null @@ -1,24 +0,0 @@ -(function(w) { - var init = function() { - var pr = document.getElementById('post-revisions'), - inputs = pr ? pr.getElementsByTagName('input') : []; - pr.onclick = function() { - var i, checkCount = 0, side; - for ( i = 0; i < inputs.length; i++ ) { - checkCount += inputs[i].checked ? 1 : 0; - side = inputs[i].getAttribute('name'); - if ( ! inputs[i].checked && - ( 'left' == side && 1 > checkCount || 'right' == side && 1 < checkCount && ( ! inputs[i-1] || ! inputs[i-1].checked ) ) && - ! ( inputs[i+1] && inputs[i+1].checked && 'right' == inputs[i+1].getAttribute('name') ) ) - inputs[i].style.visibility = 'hidden'; - else if ( 'left' == side || 'right' == side ) - inputs[i].style.visibility = 'visible'; - } - } - pr.onclick(); - } - if ( w && w.addEventListener ) - w.addEventListener('load', init, false); - else if ( w && w.attachEvent ) - w.attachEvent('onload', init); -})(window); diff --git a/wp-includes/js/wp-list-revisions.js b/wp-includes/js/wp-list-revisions.js index 417572db..9c702c65 100644 --- a/wp-includes/js/wp-list-revisions.js +++ b/wp-includes/js/wp-list-revisions.js @@ -1 +1,24 @@ -(function(a){var b=function(){var d=document.getElementById("post-revisions"),c=d?d.getElementsByTagName("input"):[];d.onclick=function(){var g,f=0,e;for(g=0;gf||"right"==e&&1 checkCount || 'right' == side && 1 < checkCount && ( ! inputs[i-1] || ! inputs[i-1].checked ) ) && + ! ( inputs[i+1] && inputs[i+1].checked && 'right' == inputs[i+1].getAttribute('name') ) ) + inputs[i].style.visibility = 'hidden'; + else if ( 'left' == side || 'right' == side ) + inputs[i].style.visibility = 'visible'; + } + } + pr.onclick(); + } + if ( w && w.addEventListener ) + w.addEventListener('load', init, false); + else if ( w && w.attachEvent ) + w.attachEvent('onload', init); +})(window); diff --git a/wp-includes/js/wp-list-revisions.min.js b/wp-includes/js/wp-list-revisions.min.js new file mode 100644 index 00000000..417572db --- /dev/null +++ b/wp-includes/js/wp-list-revisions.min.js @@ -0,0 +1 @@ +(function(a){var b=function(){var d=document.getElementById("post-revisions"),c=d?d.getElementsByTagName("input"):[];d.onclick=function(){var g,f=0,e;for(g=0;gf||"right"==e&&1
    '); - - return button.bind( 'click.pointer', function(e) { - e.preventDefault(); - t.element.pointer('close'); - }); - }, - position: 'top', - show: function( event, t ) { - t.pointer.show(); - t.opened(); - }, - hide: function( event, t ) { - t.pointer.hide(); - t.closed(); - }, - document: document - }, - - _create: function() { - var positioning, - family; - - this.content = $('
    '); - this.arrow = $('
    '); - - family = this.element.parents().add( this.element ); - positioning = 'absolute'; - - if ( family.filter(function(){ return 'fixed' === $(this).css('position'); }).length ) - positioning = 'fixed'; - - this.pointer = $('
    ') - .append( this.content ) - .append( this.arrow ) - .attr('id', 'wp-pointer-' + identifier++) - .addClass( this.options.pointerClass ) - .css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'}) - .appendTo( this.options.document.body ); - }, - - _setOption: function( key, value ) { - var o = this.options, - tip = this.pointer; - - // Handle document transfer - if ( key === "document" && value !== o.document ) { - tip.detach().appendTo( value.body ); - - // Handle class change - } else if ( key === "pointerClass" ) { - tip.removeClass( o.pointerClass ).addClass( value ); - } - - // Call super method. - $.Widget.prototype._setOption.apply( this, arguments ); - - // Reposition automatically - if ( key === "position" ) { - this.reposition(); - - // Update content automatically if pointer is open - } else if ( key === "content" && this.active ) { - this.update(); - } - }, - - destroy: function() { - this.pointer.remove(); - $.Widget.prototype.destroy.call( this ); - }, - - widget: function() { - return this.pointer; - }, - - update: function( event ) { - var self = this, - o = this.options, - dfd = $.Deferred(), - content; - - if ( o.disabled ) - return; - - dfd.done( function( content ) { - self._update( event, content ); - }) - - // Either o.content is a string... - if ( typeof o.content === 'string' ) { - content = o.content; - - // ...or o.content is a callback. - } else { - content = o.content.call( this.element[0], dfd.resolve, event, this._handoff() ); - } - - // If content is set, then complete the update. - if ( content ) - dfd.resolve( content ); - - return dfd.promise(); - }, - - /** - * Update is separated into two functions to allow events to defer - * updating the pointer (e.g. fetch content with ajax, etc). - */ - _update: function( event, content ) { - var buttons, - o = this.options; - - if ( ! content ) - return; - - this.pointer.stop(); // Kill any animations on the pointer. - this.content.html( content ); - - buttons = o.buttons.call( this.element[0], event, this._handoff() ); - if ( buttons ) { - buttons.wrap('
    ').parent().appendTo( this.content ); - } - - this.reposition(); - }, - - reposition: function() { - var position; - - if ( this.options.disabled ) - return; - - position = this._processPosition( this.options.position ); - - // Reposition pointer. - this.pointer.css({ - top: 0, - left: 0, - zIndex: zindex++ // Increment the z-index so that it shows above other opened pointers. - }).show().position($.extend({ - of: this.element, - collision: 'fit none' - }, position )); // the object comes before this.options.position so the user can override position.of. - - this.repoint(); - }, - - repoint: function() { - var o = this.options, - edge; - - if ( o.disabled ) - return; - - edge = ( typeof o.position == 'string' ) ? o.position : o.position.edge; - - // Remove arrow classes. - this.pointer[0].className = this.pointer[0].className.replace( /wp-pointer-[^\s'"]*/, '' ); - - // Add arrow class. - this.pointer.addClass( 'wp-pointer-' + edge ); - }, - - _processPosition: function( position ) { - var opposite = { - top: 'bottom', - bottom: 'top', - left: 'right', - right: 'left' - }, - result; - - // If the position object is a string, it is shorthand for position.edge. - if ( typeof position == 'string' ) { - result = { - edge: position + '' - }; - } else { - result = $.extend( {}, position ); - } - - if ( ! result.edge ) - return result; - - if ( result.edge == 'top' || result.edge == 'bottom' ) { - result.align = result.align || 'left'; - - result.at = result.at || result.align + ' ' + opposite[ result.edge ]; - result.my = result.my || result.align + ' ' + result.edge; - } else { - result.align = result.align || 'top'; - - result.at = result.at || opposite[ result.edge ] + ' ' + result.align; - result.my = result.my || result.edge + ' ' + result.align; - } - - return result; - }, - - open: function( event ) { - var self = this, - o = this.options; - - if ( this.active || o.disabled || this.element.is(':hidden') ) - return; - - this.update().done( function() { - self._open( event ); - }); - }, - - _open: function( event ) { - var self = this, - o = this.options; - - if ( this.active || o.disabled || this.element.is(':hidden') ) - return; - - this.active = true; - - this._trigger( "open", event, this._handoff() ); - - this._trigger( "show", event, this._handoff({ - opened: function() { - self._trigger( "opened", event, self._handoff() ); - } - })); - }, - - close: function( event ) { - if ( !this.active || this.options.disabled ) - return; - - var self = this; - this.active = false; - - this._trigger( "close", event, this._handoff() ); - this._trigger( "hide", event, this._handoff({ - closed: function() { - self._trigger( "closed", event, self._handoff() ); - } - })); - }, - - sendToTop: function( event ) { - if ( this.active ) - this.pointer.css( 'z-index', zindex++ ); - }, - - toggle: function( event ) { - if ( this.pointer.is(':hidden') ) - this.open( event ); - else - this.close( event ); - }, - - _handoff: function( extend ) { - return $.extend({ - pointer: this.pointer, - element: this.element - }, extend); - } - }); -})(jQuery); diff --git a/wp-includes/js/wp-pointer.js b/wp-includes/js/wp-pointer.js index 65531c84..23b0e43d 100644 --- a/wp-includes/js/wp-pointer.js +++ b/wp-includes/js/wp-pointer.js @@ -1 +1,281 @@ -(function(c){var a=0,b=9999;c.widget("wp.pointer",{options:{pointerClass:"wp-pointer",pointerWidth:320,content:function(f,e,d){return c(this).text()},buttons:function(f,e){var g=(wpPointerL10n)?wpPointerL10n.dismiss:"Dismiss",d=c(''+g+"");return d.bind("click.pointer",function(h){h.preventDefault();e.element.pointer("close")})},position:"top",show:function(e,d){d.pointer.show();d.opened()},hide:function(e,d){d.pointer.hide();d.closed()},document:document},_create:function(){var e,d;this.content=c('
    ');this.arrow=c('
    ');d=this.element.parents().add(this.element);e="absolute";if(d.filter(function(){return"fixed"===c(this).css("position")}).length){e="fixed"}this.pointer=c("
    ").append(this.content).append(this.arrow).attr("id","wp-pointer-"+a++).addClass(this.options.pointerClass).css({position:e,width:this.options.pointerWidth+"px",display:"none"}).appendTo(this.options.document.body)},_setOption:function(d,f){var g=this.options,e=this.pointer;if(d==="document"&&f!==g.document){e.detach().appendTo(f.body)}else{if(d==="pointerClass"){e.removeClass(g.pointerClass).addClass(f)}}c.Widget.prototype._setOption.apply(this,arguments);if(d==="position"){this.reposition()}else{if(d==="content"&&this.active){this.update()}}},destroy:function(){this.pointer.remove();c.Widget.prototype.destroy.call(this)},widget:function(){return this.pointer},update:function(g){var e=this,h=this.options,d=c.Deferred(),f;if(h.disabled){return}d.done(function(i){e._update(g,i)});if(typeof h.content==="string"){f=h.content}else{f=h.content.call(this.element[0],d.resolve,g,this._handoff())}if(f){d.resolve(f)}return d.promise()},_update:function(f,e){var d,g=this.options;if(!e){return}this.pointer.stop();this.content.html(e);d=g.buttons.call(this.element[0],f,this._handoff());if(d){d.wrap('
    ').parent().appendTo(this.content)}this.reposition()},reposition:function(){var d;if(this.options.disabled){return}d=this._processPosition(this.options.position);this.pointer.css({top:0,left:0,zIndex:b++}).show().position(c.extend({of:this.element,collision:"fit none"},d));this.repoint()},repoint:function(){var e=this.options,d;if(e.disabled){return}d=(typeof e.position=="string")?e.position:e.position.edge;this.pointer[0].className=this.pointer[0].className.replace(/wp-pointer-[^\s'"]*/,"");this.pointer.addClass("wp-pointer-"+d)},_processPosition:function(e){var f={top:"bottom",bottom:"top",left:"right",right:"left"},d;if(typeof e=="string"){d={edge:e+""}}else{d=c.extend({},e)}if(!d.edge){return d}if(d.edge=="top"||d.edge=="bottom"){d.align=d.align||"left";d.at=d.at||d.align+" "+f[d.edge];d.my=d.my||d.align+" "+d.edge}else{d.align=d.align||"top";d.at=d.at||f[d.edge]+" "+d.align;d.my=d.my||d.edge+" "+d.align}return d},open:function(e){var d=this,f=this.options;if(this.active||f.disabled||this.element.is(":hidden")){return}this.update().done(function(){d._open(e)})},_open:function(e){var d=this,f=this.options;if(this.active||f.disabled||this.element.is(":hidden")){return}this.active=true;this._trigger("open",e,this._handoff());this._trigger("show",e,this._handoff({opened:function(){d._trigger("opened",e,d._handoff())}}))},close:function(e){if(!this.active||this.options.disabled){return}var d=this;this.active=false;this._trigger("close",e,this._handoff());this._trigger("hide",e,this._handoff({closed:function(){d._trigger("closed",e,d._handoff())}}))},sendToTop:function(d){if(this.active){this.pointer.css("z-index",b++)}},toggle:function(d){if(this.pointer.is(":hidden")){this.open(d)}else{this.close(d)}},_handoff:function(d){return c.extend({pointer:this.pointer,element:this.element},d)}})})(jQuery); \ No newline at end of file +/** + * Pointer jQuery widget. + */ +(function($){ + var identifier = 0, + zindex = 9999; + + $.widget("wp.pointer", { + options: { + pointerClass: 'wp-pointer', + pointerWidth: 320, + content: function( respond, event, t ) { + return $(this).text(); + }, + buttons: function( event, t ) { + var close = ( wpPointerL10n ) ? wpPointerL10n.dismiss : 'Dismiss', + button = $('' + close + ''); + + return button.bind( 'click.pointer', function(e) { + e.preventDefault(); + t.element.pointer('close'); + }); + }, + position: 'top', + show: function( event, t ) { + t.pointer.show(); + t.opened(); + }, + hide: function( event, t ) { + t.pointer.hide(); + t.closed(); + }, + document: document + }, + + _create: function() { + var positioning, + family; + + this.content = $('
    '); + this.arrow = $('
    '); + + family = this.element.parents().add( this.element ); + positioning = 'absolute'; + + if ( family.filter(function(){ return 'fixed' === $(this).css('position'); }).length ) + positioning = 'fixed'; + + this.pointer = $('
    ') + .append( this.content ) + .append( this.arrow ) + .attr('id', 'wp-pointer-' + identifier++) + .addClass( this.options.pointerClass ) + .css({'position': positioning, 'width': this.options.pointerWidth+'px', 'display': 'none'}) + .appendTo( this.options.document.body ); + }, + + _setOption: function( key, value ) { + var o = this.options, + tip = this.pointer; + + // Handle document transfer + if ( key === "document" && value !== o.document ) { + tip.detach().appendTo( value.body ); + + // Handle class change + } else if ( key === "pointerClass" ) { + tip.removeClass( o.pointerClass ).addClass( value ); + } + + // Call super method. + $.Widget.prototype._setOption.apply( this, arguments ); + + // Reposition automatically + if ( key === "position" ) { + this.reposition(); + + // Update content automatically if pointer is open + } else if ( key === "content" && this.active ) { + this.update(); + } + }, + + destroy: function() { + this.pointer.remove(); + $.Widget.prototype.destroy.call( this ); + }, + + widget: function() { + return this.pointer; + }, + + update: function( event ) { + var self = this, + o = this.options, + dfd = $.Deferred(), + content; + + if ( o.disabled ) + return; + + dfd.done( function( content ) { + self._update( event, content ); + }) + + // Either o.content is a string... + if ( typeof o.content === 'string' ) { + content = o.content; + + // ...or o.content is a callback. + } else { + content = o.content.call( this.element[0], dfd.resolve, event, this._handoff() ); + } + + // If content is set, then complete the update. + if ( content ) + dfd.resolve( content ); + + return dfd.promise(); + }, + + /** + * Update is separated into two functions to allow events to defer + * updating the pointer (e.g. fetch content with ajax, etc). + */ + _update: function( event, content ) { + var buttons, + o = this.options; + + if ( ! content ) + return; + + this.pointer.stop(); // Kill any animations on the pointer. + this.content.html( content ); + + buttons = o.buttons.call( this.element[0], event, this._handoff() ); + if ( buttons ) { + buttons.wrap('
    ').parent().appendTo( this.content ); + } + + this.reposition(); + }, + + reposition: function() { + var position; + + if ( this.options.disabled ) + return; + + position = this._processPosition( this.options.position ); + + // Reposition pointer. + this.pointer.css({ + top: 0, + left: 0, + zIndex: zindex++ // Increment the z-index so that it shows above other opened pointers. + }).show().position($.extend({ + of: this.element, + collision: 'fit none' + }, position )); // the object comes before this.options.position so the user can override position.of. + + this.repoint(); + }, + + repoint: function() { + var o = this.options, + edge; + + if ( o.disabled ) + return; + + edge = ( typeof o.position == 'string' ) ? o.position : o.position.edge; + + // Remove arrow classes. + this.pointer[0].className = this.pointer[0].className.replace( /wp-pointer-[^\s'"]*/, '' ); + + // Add arrow class. + this.pointer.addClass( 'wp-pointer-' + edge ); + }, + + _processPosition: function( position ) { + var opposite = { + top: 'bottom', + bottom: 'top', + left: 'right', + right: 'left' + }, + result; + + // If the position object is a string, it is shorthand for position.edge. + if ( typeof position == 'string' ) { + result = { + edge: position + '' + }; + } else { + result = $.extend( {}, position ); + } + + if ( ! result.edge ) + return result; + + if ( result.edge == 'top' || result.edge == 'bottom' ) { + result.align = result.align || 'left'; + + result.at = result.at || result.align + ' ' + opposite[ result.edge ]; + result.my = result.my || result.align + ' ' + result.edge; + } else { + result.align = result.align || 'top'; + + result.at = result.at || opposite[ result.edge ] + ' ' + result.align; + result.my = result.my || result.edge + ' ' + result.align; + } + + return result; + }, + + open: function( event ) { + var self = this, + o = this.options; + + if ( this.active || o.disabled || this.element.is(':hidden') ) + return; + + this.update().done( function() { + self._open( event ); + }); + }, + + _open: function( event ) { + var self = this, + o = this.options; + + if ( this.active || o.disabled || this.element.is(':hidden') ) + return; + + this.active = true; + + this._trigger( "open", event, this._handoff() ); + + this._trigger( "show", event, this._handoff({ + opened: function() { + self._trigger( "opened", event, self._handoff() ); + } + })); + }, + + close: function( event ) { + if ( !this.active || this.options.disabled ) + return; + + var self = this; + this.active = false; + + this._trigger( "close", event, this._handoff() ); + this._trigger( "hide", event, this._handoff({ + closed: function() { + self._trigger( "closed", event, self._handoff() ); + } + })); + }, + + sendToTop: function( event ) { + if ( this.active ) + this.pointer.css( 'z-index', zindex++ ); + }, + + toggle: function( event ) { + if ( this.pointer.is(':hidden') ) + this.open( event ); + else + this.close( event ); + }, + + _handoff: function( extend ) { + return $.extend({ + pointer: this.pointer, + element: this.element + }, extend); + } + }); +})(jQuery); diff --git a/wp-includes/js/wp-pointer.min.js b/wp-includes/js/wp-pointer.min.js new file mode 100644 index 00000000..65531c84 --- /dev/null +++ b/wp-includes/js/wp-pointer.min.js @@ -0,0 +1 @@ +(function(c){var a=0,b=9999;c.widget("wp.pointer",{options:{pointerClass:"wp-pointer",pointerWidth:320,content:function(f,e,d){return c(this).text()},buttons:function(f,e){var g=(wpPointerL10n)?wpPointerL10n.dismiss:"Dismiss",d=c(''+g+"");return d.bind("click.pointer",function(h){h.preventDefault();e.element.pointer("close")})},position:"top",show:function(e,d){d.pointer.show();d.opened()},hide:function(e,d){d.pointer.hide();d.closed()},document:document},_create:function(){var e,d;this.content=c('
    ');this.arrow=c('
    ');d=this.element.parents().add(this.element);e="absolute";if(d.filter(function(){return"fixed"===c(this).css("position")}).length){e="fixed"}this.pointer=c("
    ").append(this.content).append(this.arrow).attr("id","wp-pointer-"+a++).addClass(this.options.pointerClass).css({position:e,width:this.options.pointerWidth+"px",display:"none"}).appendTo(this.options.document.body)},_setOption:function(d,f){var g=this.options,e=this.pointer;if(d==="document"&&f!==g.document){e.detach().appendTo(f.body)}else{if(d==="pointerClass"){e.removeClass(g.pointerClass).addClass(f)}}c.Widget.prototype._setOption.apply(this,arguments);if(d==="position"){this.reposition()}else{if(d==="content"&&this.active){this.update()}}},destroy:function(){this.pointer.remove();c.Widget.prototype.destroy.call(this)},widget:function(){return this.pointer},update:function(g){var e=this,h=this.options,d=c.Deferred(),f;if(h.disabled){return}d.done(function(i){e._update(g,i)});if(typeof h.content==="string"){f=h.content}else{f=h.content.call(this.element[0],d.resolve,g,this._handoff())}if(f){d.resolve(f)}return d.promise()},_update:function(f,e){var d,g=this.options;if(!e){return}this.pointer.stop();this.content.html(e);d=g.buttons.call(this.element[0],f,this._handoff());if(d){d.wrap('
    ').parent().appendTo(this.content)}this.reposition()},reposition:function(){var d;if(this.options.disabled){return}d=this._processPosition(this.options.position);this.pointer.css({top:0,left:0,zIndex:b++}).show().position(c.extend({of:this.element,collision:"fit none"},d));this.repoint()},repoint:function(){var e=this.options,d;if(e.disabled){return}d=(typeof e.position=="string")?e.position:e.position.edge;this.pointer[0].className=this.pointer[0].className.replace(/wp-pointer-[^\s'"]*/,"");this.pointer.addClass("wp-pointer-"+d)},_processPosition:function(e){var f={top:"bottom",bottom:"top",left:"right",right:"left"},d;if(typeof e=="string"){d={edge:e+""}}else{d=c.extend({},e)}if(!d.edge){return d}if(d.edge=="top"||d.edge=="bottom"){d.align=d.align||"left";d.at=d.at||d.align+" "+f[d.edge];d.my=d.my||d.align+" "+d.edge}else{d.align=d.align||"top";d.at=d.at||f[d.edge]+" "+d.align;d.my=d.my||d.edge+" "+d.align}return d},open:function(e){var d=this,f=this.options;if(this.active||f.disabled||this.element.is(":hidden")){return}this.update().done(function(){d._open(e)})},_open:function(e){var d=this,f=this.options;if(this.active||f.disabled||this.element.is(":hidden")){return}this.active=true;this._trigger("open",e,this._handoff());this._trigger("show",e,this._handoff({opened:function(){d._trigger("opened",e,d._handoff())}}))},close:function(e){if(!this.active||this.options.disabled){return}var d=this;this.active=false;this._trigger("close",e,this._handoff());this._trigger("hide",e,this._handoff({closed:function(){d._trigger("closed",e,d._handoff())}}))},sendToTop:function(d){if(this.active){this.pointer.css("z-index",b++)}},toggle:function(d){if(this.pointer.is(":hidden")){this.open(d)}else{this.close(d)}},_handoff:function(d){return c.extend({pointer:this.pointer,element:this.element},d)}})})(jQuery); \ No newline at end of file diff --git a/wp-includes/js/wplink.dev.js b/wp-includes/js/wplink.dev.js deleted file mode 100644 index d0c4b9a0..00000000 --- a/wp-includes/js/wplink.dev.js +++ /dev/null @@ -1,593 +0,0 @@ -var wpLink; - -(function($){ - var inputs = {}, rivers = {}, ed, River, Query; - - wpLink = { - timeToTriggerRiver: 150, - minRiverAJAXDuration: 200, - riverBottomThreshold: 5, - keySensitivity: 100, - lastSearch: '', - textarea: '', - - init : function() { - inputs.dialog = $('#wp-link'); - inputs.submit = $('#wp-link-submit'); - // URL - inputs.url = $('#url-field'); - inputs.nonce = $('#_ajax_linking_nonce'); - // Secondary options - inputs.title = $('#link-title-field'); - // Advanced Options - inputs.openInNewTab = $('#link-target-checkbox'); - inputs.search = $('#search-field'); - // Build Rivers - rivers.search = new River( $('#search-results') ); - rivers.recent = new River( $('#most-recent-results') ); - rivers.elements = $('.query-results', inputs.dialog); - - // Bind event handlers - inputs.dialog.keydown( wpLink.keydown ); - inputs.dialog.keyup( wpLink.keyup ); - inputs.submit.click( function(e){ - e.preventDefault(); - wpLink.update(); - }); - $('#wp-link-cancel').click( function(e){ - e.preventDefault(); - wpLink.close(); - }); - $('#internal-toggle').click( wpLink.toggleInternalLinking ); - - rivers.elements.bind('river-select', wpLink.updateFields ); - - inputs.search.keyup( wpLink.searchInternalLinks ); - - inputs.dialog.bind('wpdialogrefresh', wpLink.refresh); - inputs.dialog.bind('wpdialogbeforeopen', wpLink.beforeOpen); - inputs.dialog.bind('wpdialogclose', wpLink.onClose); - }, - - beforeOpen : function() { - wpLink.range = null; - - if ( ! wpLink.isMCE() && document.selection ) { - wpLink.textarea.focus(); - wpLink.range = document.selection.createRange(); - } - }, - - open : function() { - if ( !wpActiveEditor ) - return; - - this.textarea = $('#'+wpActiveEditor).get(0); - - // Initialize the dialog if necessary (html mode). - if ( ! inputs.dialog.data('wpdialog') ) { - inputs.dialog.wpdialog({ - title: wpLinkL10n.title, - width: 480, - height: 'auto', - modal: true, - dialogClass: 'wp-dialog', - zIndex: 300000 - }); - } - - inputs.dialog.wpdialog('open'); - }, - - isMCE : function() { - return tinyMCEPopup && ( ed = tinyMCEPopup.editor ) && ! ed.isHidden(); - }, - - refresh : function() { - // Refresh rivers (clear links, check visibility) - rivers.search.refresh(); - rivers.recent.refresh(); - - if ( wpLink.isMCE() ) - wpLink.mceRefresh(); - else - wpLink.setDefaultValues(); - - // Focus the URL field and highlight its contents. - // If this is moved above the selection changes, - // IE will show a flashing cursor over the dialog. - inputs.url.focus()[0].select(); - // Load the most recent results if this is the first time opening the panel. - if ( ! rivers.recent.ul.children().length ) - rivers.recent.ajax(); - }, - - mceRefresh : function() { - var e; - ed = tinyMCEPopup.editor; - - tinyMCEPopup.restoreSelection(); - - // If link exists, select proper values. - if ( e = ed.dom.getParent(ed.selection.getNode(), 'A') ) { - // Set URL and description. - inputs.url.val( ed.dom.getAttrib(e, 'href') ); - inputs.title.val( ed.dom.getAttrib(e, 'title') ); - // Set open in new tab. - if ( "_blank" == ed.dom.getAttrib(e, 'target') ) - inputs.openInNewTab.prop('checked', true); - // Update save prompt. - inputs.submit.val( wpLinkL10n.update ); - - // If there's no link, set the default values. - } else { - wpLink.setDefaultValues(); - } - - tinyMCEPopup.storeSelection(); - }, - - close : function() { - if ( wpLink.isMCE() ) - tinyMCEPopup.close(); - else - inputs.dialog.wpdialog('close'); - }, - - onClose: function() { - if ( ! wpLink.isMCE() ) { - wpLink.textarea.focus(); - if ( wpLink.range ) { - wpLink.range.moveToBookmark( wpLink.range.getBookmark() ); - wpLink.range.select(); - } - } - }, - - getAttrs : function() { - return { - href : inputs.url.val(), - title : inputs.title.val(), - target : inputs.openInNewTab.prop('checked') ? '_blank' : '' - }; - }, - - update : function() { - if ( wpLink.isMCE() ) - wpLink.mceUpdate(); - else - wpLink.htmlUpdate(); - }, - - htmlUpdate : function() { - var attrs, html, begin, end, cursor, - textarea = wpLink.textarea; - - if ( ! textarea ) - return; - - attrs = wpLink.getAttrs(); - - // If there's no href, return. - if ( ! attrs.href || attrs.href == 'http://' ) - return; - - // Build HTML - html = ''; - wpLink.range.moveToBookmark( wpLink.range.getBookmark() ); - wpLink.range.select(); - - wpLink.range = null; - } else if ( typeof textarea.selectionStart !== 'undefined' ) { - // W3C - begin = textarea.selectionStart; - end = textarea.selectionEnd; - selection = textarea.value.substring( begin, end ); - html = html + selection + ''; - cursor = begin + html.length; - - // If no next is selected, place the cursor inside the closing tag. - if ( begin == end ) - cursor -= ''.length; - - textarea.value = textarea.value.substring( 0, begin ) - + html - + textarea.value.substring( end, textarea.value.length ); - - // Update cursor position - textarea.selectionStart = textarea.selectionEnd = cursor; - } - - wpLink.close(); - textarea.focus(); - }, - - mceUpdate : function() { - var ed = tinyMCEPopup.editor, - attrs = wpLink.getAttrs(), - e, b; - - tinyMCEPopup.restoreSelection(); - e = ed.dom.getParent(ed.selection.getNode(), 'A'); - - // If the values are empty, unlink and return - if ( ! attrs.href || attrs.href == 'http://' ) { - if ( e ) { - tinyMCEPopup.execCommand("mceBeginUndoLevel"); - b = ed.selection.getBookmark(); - ed.dom.remove(e, 1); - ed.selection.moveToBookmark(b); - tinyMCEPopup.execCommand("mceEndUndoLevel"); - wpLink.close(); - } - return; - } - - tinyMCEPopup.execCommand("mceBeginUndoLevel"); - - if (e == null) { - ed.getDoc().execCommand("unlink", false, null); - tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1}); - - tinymce.each(ed.dom.select("a"), function(n) { - if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { - e = n; - ed.dom.setAttribs(e, attrs); - } - }); - - // Sometimes WebKit lets a user create a link where - // they shouldn't be able to. In this case, CreateLink - // injects "#mce_temp_url#" into their content. Fix it. - if ( $(e).text() == '#mce_temp_url#' ) { - ed.dom.remove(e); - e = null; - } - } else { - ed.dom.setAttribs(e, attrs); - } - - // Don't move caret if selection was image - if ( e && (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') ) { - ed.focus(); - ed.selection.select(e); - ed.selection.collapse(0); - tinyMCEPopup.storeSelection(); - } - - tinyMCEPopup.execCommand("mceEndUndoLevel"); - wpLink.close(); - }, - - updateFields : function( e, li, originalEvent ) { - inputs.url.val( li.children('.item-permalink').val() ); - inputs.title.val( li.hasClass('no-title') ? '' : li.children('.item-title').text() ); - if ( originalEvent && originalEvent.type == "click" ) - inputs.url.focus(); - }, - setDefaultValues : function() { - // Set URL and description to defaults. - // Leave the new tab setting as-is. - inputs.url.val('http://'); - inputs.title.val(''); - - // Update save prompt. - inputs.submit.val( wpLinkL10n.save ); - }, - - searchInternalLinks : function() { - var t = $(this), waiting, - search = t.val(); - - if ( search.length > 2 ) { - rivers.recent.hide(); - rivers.search.show(); - - // Don't search if the keypress didn't change the title. - if ( wpLink.lastSearch == search ) - return; - - wpLink.lastSearch = search; - waiting = t.siblings('img.waiting').show(); - - rivers.search.change( search ); - rivers.search.ajax( function(){ waiting.hide(); }); - } else { - rivers.search.hide(); - rivers.recent.show(); - } - }, - - next : function() { - rivers.search.next(); - rivers.recent.next(); - }, - prev : function() { - rivers.search.prev(); - rivers.recent.prev(); - }, - - keydown : function( event ) { - var fn, key = $.ui.keyCode; - - switch( event.which ) { - case key.UP: - fn = 'prev'; - case key.DOWN: - fn = fn || 'next'; - clearInterval( wpLink.keyInterval ); - wpLink[ fn ](); - wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity ); - break; - default: - return; - } - event.preventDefault(); - }, - keyup: function( event ) { - var key = $.ui.keyCode; - - switch( event.which ) { - case key.ESCAPE: - event.stopImmediatePropagation(); - if ( ! $(document).triggerHandler( 'wp_CloseOnEscape', [{ event: event, what: 'wplink', cb: wpLink.close }] ) ) - wpLink.close(); - - return false; - break; - case key.UP: - case key.DOWN: - clearInterval( wpLink.keyInterval ); - break; - default: - return; - } - event.preventDefault(); - }, - - delayedCallback : function( func, delay ) { - var timeoutTriggered, funcTriggered, funcArgs, funcContext; - - if ( ! delay ) - return func; - - setTimeout( function() { - if ( funcTriggered ) - return func.apply( funcContext, funcArgs ); - // Otherwise, wait. - timeoutTriggered = true; - }, delay); - - return function() { - if ( timeoutTriggered ) - return func.apply( this, arguments ); - // Otherwise, wait. - funcArgs = arguments; - funcContext = this; - funcTriggered = true; - }; - }, - - toggleInternalLinking : function( event ) { - var panel = $('#search-panel'), - widget = inputs.dialog.wpdialog('widget'), - // We're about to toggle visibility; it's currently the opposite - visible = !panel.is(':visible'), - win = $(window); - - $(this).toggleClass('toggle-arrow-active', visible); - - inputs.dialog.height('auto'); - panel.slideToggle( 300, function() { - setUserSetting('wplink', visible ? '1' : '0'); - inputs[ visible ? 'search' : 'url' ].focus(); - - // Move the box if the box is now expanded, was opened in a collapsed state, - // and if it needs to be moved. (Judged by bottom not being positive or - // bottom being smaller than top.) - var scroll = win.scrollTop(), - top = widget.offset().top, - bottom = top + widget.outerHeight(), - diff = bottom - win.height(); - - if ( diff > scroll ) { - widget.animate({'top': diff < top ? top - diff : scroll }, 200); - } - }); - event.preventDefault(); - } - } - - River = function( element, search ) { - var self = this; - this.element = element; - this.ul = element.children('ul'); - this.waiting = element.find('.river-waiting'); - - this.change( search ); - this.refresh(); - - element.scroll( function(){ self.maybeLoad(); }); - element.delegate('li', 'click', function(e){ self.select( $(this), e ); }); - }; - - $.extend( River.prototype, { - refresh: function() { - this.deselect(); - this.visible = this.element.is(':visible'); - }, - show: function() { - if ( ! this.visible ) { - this.deselect(); - this.element.show(); - this.visible = true; - } - }, - hide: function() { - this.element.hide(); - this.visible = false; - }, - // Selects a list item and triggers the river-select event. - select: function( li, event ) { - var liHeight, elHeight, liTop, elTop; - - if ( li.hasClass('unselectable') || li == this.selected ) - return; - - this.deselect(); - this.selected = li.addClass('selected'); - // Make sure the element is visible - liHeight = li.outerHeight(); - elHeight = this.element.height(); - liTop = li.position().top; - elTop = this.element.scrollTop(); - - if ( liTop < 0 ) // Make first visible element - this.element.scrollTop( elTop + liTop ); - else if ( liTop + liHeight > elHeight ) // Make last visible element - this.element.scrollTop( elTop + liTop - elHeight + liHeight ); - - // Trigger the river-select event - this.element.trigger('river-select', [ li, event, this ]); - }, - deselect: function() { - if ( this.selected ) - this.selected.removeClass('selected'); - this.selected = false; - }, - prev: function() { - if ( ! this.visible ) - return; - - var to; - if ( this.selected ) { - to = this.selected.prev('li'); - if ( to.length ) - this.select( to ); - } - }, - next: function() { - if ( ! this.visible ) - return; - - var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element); - if ( to.length ) - this.select( to ); - }, - ajax: function( callback ) { - var self = this, - delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration, - response = wpLink.delayedCallback( function( results, params ) { - self.process( results, params ); - if ( callback ) - callback( results, params ); - }, delay ); - - this.query.ajax( response ); - }, - change: function( search ) { - if ( this.query && this._search == search ) - return; - - this._search = search; - this.query = new Query( search ); - this.element.scrollTop(0); - }, - process: function( results, params ) { - var list = '', alt = true, classes = '', - firstPage = params.page == 1; - - if ( !results ) { - if ( firstPage ) { - list += '
  • ' - + wpLinkL10n.noMatchesFound - + '
  • '; - } - } else { - $.each( results, function() { - classes = alt ? 'alternate' : ''; - classes += this['title'] ? '' : ' no-title'; - list += classes ? '
  • ' : '
  • '; - list += ''; - list += ''; - list += this['title'] ? this['title'] : wpLinkL10n.noTitle; - list += '' + this['info'] + '
  • '; - alt = ! alt; - }); - } - - this.ul[ firstPage ? 'html' : 'append' ]( list ); - }, - maybeLoad: function() { - var self = this, - el = this.element, - bottom = el.scrollTop() + el.height(); - - if ( ! this.query.ready() || bottom < this.ul.height() - wpLink.riverBottomThreshold ) - return; - - setTimeout(function() { - var newTop = el.scrollTop(), - newBottom = newTop + el.height(); - - if ( ! self.query.ready() || newBottom < self.ul.height() - wpLink.riverBottomThreshold ) - return; - - self.waiting.show(); - el.scrollTop( newTop + self.waiting.outerHeight() ); - - self.ajax( function() { self.waiting.hide(); }); - }, wpLink.timeToTriggerRiver ); - } - }); - - Query = function( search ) { - this.page = 1; - this.allLoaded = false; - this.querying = false; - this.search = search; - }; - - $.extend( Query.prototype, { - ready: function() { - return !( this.querying || this.allLoaded ); - }, - ajax: function( callback ) { - var self = this, - query = { - action : 'wp-link-ajax', - page : this.page, - '_ajax_linking_nonce' : inputs.nonce.val() - }; - - if ( this.search ) - query.search = this.search; - - this.querying = true; - - $.post( ajaxurl, query, function(r) { - self.page++; - self.querying = false; - self.allLoaded = !r; - callback( r, query ); - }, "json" ); - } - }); - - $(document).ready( wpLink.init ); -})(jQuery); diff --git a/wp-includes/js/wplink.js b/wp-includes/js/wplink.js index 4ce2f6eb..c52d2a19 100644 --- a/wp-includes/js/wplink.js +++ b/wp-includes/js/wplink.js @@ -1 +1,593 @@ -var wpLink;(function(f){var b={},e={},d,a,c;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",textarea:"",init:function(){b.dialog=f("#wp-link");b.submit=f("#wp-link-submit");b.url=f("#url-field");b.nonce=f("#_ajax_linking_nonce");b.title=f("#link-title-field");b.openInNewTab=f("#link-target-checkbox");b.search=f("#search-field");e.search=new a(f("#search-results"));e.recent=new a(f("#most-recent-results"));e.elements=f(".query-results",b.dialog);b.dialog.keydown(wpLink.keydown);b.dialog.keyup(wpLink.keyup);b.submit.click(function(g){g.preventDefault();wpLink.update()});f("#wp-link-cancel").click(function(g){g.preventDefault();wpLink.close()});f("#internal-toggle").click(wpLink.toggleInternalLinking);e.elements.bind("river-select",wpLink.updateFields);b.search.keyup(wpLink.searchInternalLinks);b.dialog.bind("wpdialogrefresh",wpLink.refresh);b.dialog.bind("wpdialogbeforeopen",wpLink.beforeOpen);b.dialog.bind("wpdialogclose",wpLink.onClose)},beforeOpen:function(){wpLink.range=null;if(!wpLink.isMCE()&&document.selection){wpLink.textarea.focus();wpLink.range=document.selection.createRange()}},open:function(){if(!wpActiveEditor){return}this.textarea=f("#"+wpActiveEditor).get(0);if(!b.dialog.data("wpdialog")){b.dialog.wpdialog({title:wpLinkL10n.title,width:480,height:"auto",modal:true,dialogClass:"wp-dialog",zIndex:300000})}b.dialog.wpdialog("open")},isMCE:function(){return tinyMCEPopup&&(d=tinyMCEPopup.editor)&&!d.isHidden()},refresh:function(){e.search.refresh();e.recent.refresh();if(wpLink.isMCE()){wpLink.mceRefresh()}else{wpLink.setDefaultValues()}b.url.focus()[0].select();if(!e.recent.ul.children().length){e.recent.ajax()}},mceRefresh:function(){var g;d=tinyMCEPopup.editor;tinyMCEPopup.restoreSelection();if(g=d.dom.getParent(d.selection.getNode(),"A")){b.url.val(d.dom.getAttrib(g,"href"));b.title.val(d.dom.getAttrib(g,"title"));if("_blank"==d.dom.getAttrib(g,"target")){b.openInNewTab.prop("checked",true)}b.submit.val(wpLinkL10n.update)}else{wpLink.setDefaultValues()}tinyMCEPopup.storeSelection()},close:function(){if(wpLink.isMCE()){tinyMCEPopup.close()}else{b.dialog.wpdialog("close")}},onClose:function(){if(!wpLink.isMCE()){wpLink.textarea.focus();if(wpLink.range){wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select()}}},getAttrs:function(){return{href:b.url.val(),title:b.title.val(),target:b.openInNewTab.prop("checked")?"_blank":""}},update:function(){if(wpLink.isMCE()){wpLink.mceUpdate()}else{wpLink.htmlUpdate()}},htmlUpdate:function(){var i,j,k,h,l,g=wpLink.textarea;if(!g){return}i=wpLink.getAttrs();if(!i.href||i.href=="http://"){return}j='";wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select();wpLink.range=null}else{if(typeof g.selectionStart!=="undefined"){k=g.selectionStart;h=g.selectionEnd;selection=g.value.substring(k,h);j=j+selection+"";l=k+j.length;if(k==h){l-="".length}g.value=g.value.substring(0,k)+j+g.value.substring(h,g.value.length);g.selectionStart=g.selectionEnd=l}}wpLink.close();g.focus()},mceUpdate:function(){var h=tinyMCEPopup.editor,i=wpLink.getAttrs(),j,g;tinyMCEPopup.restoreSelection();j=h.dom.getParent(h.selection.getNode(),"A");if(!i.href||i.href=="http://"){if(j){tinyMCEPopup.execCommand("mceBeginUndoLevel");g=h.selection.getBookmark();h.dom.remove(j,1);h.selection.moveToBookmark(g);tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()}return}tinyMCEPopup.execCommand("mceBeginUndoLevel");if(j==null){h.getDoc().execCommand("unlink",false,null);tinyMCEPopup.execCommand("mceInsertLink",false,"#mce_temp_url#",{skip_undo:1});tinymce.each(h.dom.select("a"),function(k){if(h.dom.getAttrib(k,"href")=="#mce_temp_url#"){j=k;h.dom.setAttribs(j,i)}});if(f(j).text()=="#mce_temp_url#"){h.dom.remove(j);j=null}}else{h.dom.setAttribs(j,i)}if(j&&(j.childNodes.length!=1||j.firstChild.nodeName!="IMG")){h.focus();h.selection.select(j);h.selection.collapse(0);tinyMCEPopup.storeSelection()}tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()},updateFields:function(i,h,g){b.url.val(h.children(".item-permalink").val());b.title.val(h.hasClass("no-title")?"":h.children(".item-title").text());if(g&&g.type=="click"){b.url.focus()}},setDefaultValues:function(){b.url.val("http://");b.title.val("");b.submit.val(wpLinkL10n.save)},searchInternalLinks:function(){var h=f(this),i,g=h.val();if(g.length>2){e.recent.hide();e.search.show();if(wpLink.lastSearch==g){return}wpLink.lastSearch=g;i=h.siblings("img.waiting").show();e.search.change(g);e.search.ajax(function(){i.hide()})}else{e.search.hide();e.recent.show()}},next:function(){e.search.next();e.recent.next()},prev:function(){e.search.prev();e.recent.prev()},keydown:function(i){var h,g=f.ui.keyCode;switch(i.which){case g.UP:h="prev";case g.DOWN:h=h||"next";clearInterval(wpLink.keyInterval);wpLink[h]();wpLink.keyInterval=setInterval(wpLink[h],wpLink.keySensitivity);break;default:return}i.preventDefault()},keyup:function(h){var g=f.ui.keyCode;switch(h.which){case g.ESCAPE:h.stopImmediatePropagation();if(!f(document).triggerHandler("wp_CloseOnEscape",[{event:h,what:"wplink",cb:wpLink.close}])){wpLink.close()}return false;break;case g.UP:case g.DOWN:clearInterval(wpLink.keyInterval);break;default:return}h.preventDefault()},delayedCallback:function(i,g){var l,k,j,h;if(!g){return i}setTimeout(function(){if(k){return i.apply(h,j)}l=true},g);return function(){if(l){return i.apply(this,arguments)}j=arguments;h=this;k=true}},toggleInternalLinking:function(h){var g=f("#search-panel"),i=b.dialog.wpdialog("widget"),k=!g.is(":visible"),j=f(window);f(this).toggleClass("toggle-arrow-active",k);b.dialog.height("auto");g.slideToggle(300,function(){setUserSetting("wplink",k?"1":"0");b[k?"search":"url"].focus();var l=j.scrollTop(),o=i.offset().top,m=o+i.outerHeight(),n=m-j.height();if(n>l){i.animate({top:ni){this.element.scrollTop(g+l-i+j)}}this.element.trigger("river-select",[h,k,this])},deselect:function(){if(this.selected){this.selected.removeClass("selected")}this.selected=false},prev:function(){if(!this.visible){return}var g;if(this.selected){g=this.selected.prev("li");if(g.length){this.select(g)}}},next:function(){if(!this.visible){return}var g=this.selected?this.selected.next("li"):f("li:not(.unselectable):first",this.element);if(g.length){this.select(g)}},ajax:function(j){var h=this,i=this.query.page==1?0:wpLink.minRiverAJAXDuration,g=wpLink.delayedCallback(function(k,l){h.process(k,l);if(j){j(k,l)}},i);this.query.ajax(g)},change:function(g){if(this.query&&this._search==g){return}this._search=g;this.query=new c(g);this.element.scrollTop(0)},process:function(h,l){var i="",j=true,g="",k=l.page==1;if(!h){if(k){i+='
  • '+wpLinkL10n.noMatchesFound+"
  • "}}else{f.each(h,function(){g=j?"alternate":"";g+=this["title"]?"":" no-title";i+=g?'
  • ':"
  • ";i+='';i+='';i+=this["title"]?this["title"]:wpLinkL10n.noTitle;i+=''+this["info"]+"
  • ";j=!j})}this.ul[k?"html":"append"](i)},maybeLoad:function(){var h=this,i=this.element,g=i.scrollTop()+i.height();if(!this.query.ready()||g'; + wpLink.range.moveToBookmark( wpLink.range.getBookmark() ); + wpLink.range.select(); + + wpLink.range = null; + } else if ( typeof textarea.selectionStart !== 'undefined' ) { + // W3C + begin = textarea.selectionStart; + end = textarea.selectionEnd; + selection = textarea.value.substring( begin, end ); + html = html + selection + ''; + cursor = begin + html.length; + + // If no next is selected, place the cursor inside the closing tag. + if ( begin == end ) + cursor -= ''.length; + + textarea.value = textarea.value.substring( 0, begin ) + + html + + textarea.value.substring( end, textarea.value.length ); + + // Update cursor position + textarea.selectionStart = textarea.selectionEnd = cursor; + } + + wpLink.close(); + textarea.focus(); + }, + + mceUpdate : function() { + var ed = tinyMCEPopup.editor, + attrs = wpLink.getAttrs(), + e, b; + + tinyMCEPopup.restoreSelection(); + e = ed.dom.getParent(ed.selection.getNode(), 'A'); + + // If the values are empty, unlink and return + if ( ! attrs.href || attrs.href == 'http://' ) { + if ( e ) { + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + b = ed.selection.getBookmark(); + ed.dom.remove(e, 1); + ed.selection.moveToBookmark(b); + tinyMCEPopup.execCommand("mceEndUndoLevel"); + wpLink.close(); + } + return; + } + + tinyMCEPopup.execCommand("mceBeginUndoLevel"); + + if (e == null) { + ed.getDoc().execCommand("unlink", false, null); + tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1}); + + tinymce.each(ed.dom.select("a"), function(n) { + if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') { + e = n; + ed.dom.setAttribs(e, attrs); + } + }); + + // Sometimes WebKit lets a user create a link where + // they shouldn't be able to. In this case, CreateLink + // injects "#mce_temp_url#" into their content. Fix it. + if ( $(e).text() == '#mce_temp_url#' ) { + ed.dom.remove(e); + e = null; + } + } else { + ed.dom.setAttribs(e, attrs); + } + + // Don't move caret if selection was image + if ( e && (e.childNodes.length != 1 || e.firstChild.nodeName != 'IMG') ) { + ed.focus(); + ed.selection.select(e); + ed.selection.collapse(0); + tinyMCEPopup.storeSelection(); + } + + tinyMCEPopup.execCommand("mceEndUndoLevel"); + wpLink.close(); + }, + + updateFields : function( e, li, originalEvent ) { + inputs.url.val( li.children('.item-permalink').val() ); + inputs.title.val( li.hasClass('no-title') ? '' : li.children('.item-title').text() ); + if ( originalEvent && originalEvent.type == "click" ) + inputs.url.focus(); + }, + setDefaultValues : function() { + // Set URL and description to defaults. + // Leave the new tab setting as-is. + inputs.url.val('http://'); + inputs.title.val(''); + + // Update save prompt. + inputs.submit.val( wpLinkL10n.save ); + }, + + searchInternalLinks : function() { + var t = $(this), waiting, + search = t.val(); + + if ( search.length > 2 ) { + rivers.recent.hide(); + rivers.search.show(); + + // Don't search if the keypress didn't change the title. + if ( wpLink.lastSearch == search ) + return; + + wpLink.lastSearch = search; + waiting = t.parent().find('.spinner').show(); + + rivers.search.change( search ); + rivers.search.ajax( function(){ waiting.hide(); }); + } else { + rivers.search.hide(); + rivers.recent.show(); + } + }, + + next : function() { + rivers.search.next(); + rivers.recent.next(); + }, + prev : function() { + rivers.search.prev(); + rivers.recent.prev(); + }, + + keydown : function( event ) { + var fn, key = $.ui.keyCode; + + switch( event.which ) { + case key.UP: + fn = 'prev'; + case key.DOWN: + fn = fn || 'next'; + clearInterval( wpLink.keyInterval ); + wpLink[ fn ](); + wpLink.keyInterval = setInterval( wpLink[ fn ], wpLink.keySensitivity ); + break; + default: + return; + } + event.preventDefault(); + }, + keyup: function( event ) { + var key = $.ui.keyCode; + + switch( event.which ) { + case key.ESCAPE: + event.stopImmediatePropagation(); + if ( ! $(document).triggerHandler( 'wp_CloseOnEscape', [{ event: event, what: 'wplink', cb: wpLink.close }] ) ) + wpLink.close(); + + return false; + break; + case key.UP: + case key.DOWN: + clearInterval( wpLink.keyInterval ); + break; + default: + return; + } + event.preventDefault(); + }, + + delayedCallback : function( func, delay ) { + var timeoutTriggered, funcTriggered, funcArgs, funcContext; + + if ( ! delay ) + return func; + + setTimeout( function() { + if ( funcTriggered ) + return func.apply( funcContext, funcArgs ); + // Otherwise, wait. + timeoutTriggered = true; + }, delay); + + return function() { + if ( timeoutTriggered ) + return func.apply( this, arguments ); + // Otherwise, wait. + funcArgs = arguments; + funcContext = this; + funcTriggered = true; + }; + }, + + toggleInternalLinking : function( event ) { + var panel = $('#search-panel'), + widget = inputs.dialog.wpdialog('widget'), + // We're about to toggle visibility; it's currently the opposite + visible = !panel.is(':visible'), + win = $(window); + + $(this).toggleClass('toggle-arrow-active', visible); + + inputs.dialog.height('auto'); + panel.slideToggle( 300, function() { + setUserSetting('wplink', visible ? '1' : '0'); + inputs[ visible ? 'search' : 'url' ].focus(); + + // Move the box if the box is now expanded, was opened in a collapsed state, + // and if it needs to be moved. (Judged by bottom not being positive or + // bottom being smaller than top.) + var scroll = win.scrollTop(), + top = widget.offset().top, + bottom = top + widget.outerHeight(), + diff = bottom - win.height(); + + if ( diff > scroll ) { + widget.animate({'top': diff < top ? top - diff : scroll }, 200); + } + }); + event.preventDefault(); + } + } + + River = function( element, search ) { + var self = this; + this.element = element; + this.ul = element.children('ul'); + this.waiting = element.find('.river-waiting'); + + this.change( search ); + this.refresh(); + + element.scroll( function(){ self.maybeLoad(); }); + element.delegate('li', 'click', function(e){ self.select( $(this), e ); }); + }; + + $.extend( River.prototype, { + refresh: function() { + this.deselect(); + this.visible = this.element.is(':visible'); + }, + show: function() { + if ( ! this.visible ) { + this.deselect(); + this.element.show(); + this.visible = true; + } + }, + hide: function() { + this.element.hide(); + this.visible = false; + }, + // Selects a list item and triggers the river-select event. + select: function( li, event ) { + var liHeight, elHeight, liTop, elTop; + + if ( li.hasClass('unselectable') || li == this.selected ) + return; + + this.deselect(); + this.selected = li.addClass('selected'); + // Make sure the element is visible + liHeight = li.outerHeight(); + elHeight = this.element.height(); + liTop = li.position().top; + elTop = this.element.scrollTop(); + + if ( liTop < 0 ) // Make first visible element + this.element.scrollTop( elTop + liTop ); + else if ( liTop + liHeight > elHeight ) // Make last visible element + this.element.scrollTop( elTop + liTop - elHeight + liHeight ); + + // Trigger the river-select event + this.element.trigger('river-select', [ li, event, this ]); + }, + deselect: function() { + if ( this.selected ) + this.selected.removeClass('selected'); + this.selected = false; + }, + prev: function() { + if ( ! this.visible ) + return; + + var to; + if ( this.selected ) { + to = this.selected.prev('li'); + if ( to.length ) + this.select( to ); + } + }, + next: function() { + if ( ! this.visible ) + return; + + var to = this.selected ? this.selected.next('li') : $('li:not(.unselectable):first', this.element); + if ( to.length ) + this.select( to ); + }, + ajax: function( callback ) { + var self = this, + delay = this.query.page == 1 ? 0 : wpLink.minRiverAJAXDuration, + response = wpLink.delayedCallback( function( results, params ) { + self.process( results, params ); + if ( callback ) + callback( results, params ); + }, delay ); + + this.query.ajax( response ); + }, + change: function( search ) { + if ( this.query && this._search == search ) + return; + + this._search = search; + this.query = new Query( search ); + this.element.scrollTop(0); + }, + process: function( results, params ) { + var list = '', alt = true, classes = '', + firstPage = params.page == 1; + + if ( !results ) { + if ( firstPage ) { + list += '
  • ' + + wpLinkL10n.noMatchesFound + + '
  • '; + } + } else { + $.each( results, function() { + classes = alt ? 'alternate' : ''; + classes += this['title'] ? '' : ' no-title'; + list += classes ? '
  • ' : '
  • '; + list += ''; + list += ''; + list += this['title'] ? this['title'] : wpLinkL10n.noTitle; + list += '' + this['info'] + '
  • '; + alt = ! alt; + }); + } + + this.ul[ firstPage ? 'html' : 'append' ]( list ); + }, + maybeLoad: function() { + var self = this, + el = this.element, + bottom = el.scrollTop() + el.height(); + + if ( ! this.query.ready() || bottom < this.ul.height() - wpLink.riverBottomThreshold ) + return; + + setTimeout(function() { + var newTop = el.scrollTop(), + newBottom = newTop + el.height(); + + if ( ! self.query.ready() || newBottom < self.ul.height() - wpLink.riverBottomThreshold ) + return; + + self.waiting.show(); + el.scrollTop( newTop + self.waiting.outerHeight() ); + + self.ajax( function() { self.waiting.hide(); }); + }, wpLink.timeToTriggerRiver ); + } + }); + + Query = function( search ) { + this.page = 1; + this.allLoaded = false; + this.querying = false; + this.search = search; + }; + + $.extend( Query.prototype, { + ready: function() { + return !( this.querying || this.allLoaded ); + }, + ajax: function( callback ) { + var self = this, + query = { + action : 'wp-link-ajax', + page : this.page, + '_ajax_linking_nonce' : inputs.nonce.val() + }; + + if ( this.search ) + query.search = this.search; + + this.querying = true; + + $.post( ajaxurl, query, function(r) { + self.page++; + self.querying = false; + self.allLoaded = !r; + callback( r, query ); + }, "json" ); + } + }); + + $(document).ready( wpLink.init ); +})(jQuery); diff --git a/wp-includes/js/wplink.min.js b/wp-includes/js/wplink.min.js new file mode 100644 index 00000000..9d6a5606 --- /dev/null +++ b/wp-includes/js/wplink.min.js @@ -0,0 +1 @@ +var wpLink;(function(f){var b={},e={},d,a,c;wpLink={timeToTriggerRiver:150,minRiverAJAXDuration:200,riverBottomThreshold:5,keySensitivity:100,lastSearch:"",textarea:"",init:function(){b.dialog=f("#wp-link");b.submit=f("#wp-link-submit");b.url=f("#url-field");b.nonce=f("#_ajax_linking_nonce");b.title=f("#link-title-field");b.openInNewTab=f("#link-target-checkbox");b.search=f("#search-field");e.search=new a(f("#search-results"));e.recent=new a(f("#most-recent-results"));e.elements=f(".query-results",b.dialog);b.dialog.keydown(wpLink.keydown);b.dialog.keyup(wpLink.keyup);b.submit.click(function(g){g.preventDefault();wpLink.update()});f("#wp-link-cancel").click(function(g){g.preventDefault();wpLink.close()});f("#internal-toggle").click(wpLink.toggleInternalLinking);e.elements.bind("river-select",wpLink.updateFields);b.search.keyup(wpLink.searchInternalLinks);b.dialog.bind("wpdialogrefresh",wpLink.refresh);b.dialog.bind("wpdialogbeforeopen",wpLink.beforeOpen);b.dialog.bind("wpdialogclose",wpLink.onClose)},beforeOpen:function(){wpLink.range=null;if(!wpLink.isMCE()&&document.selection){wpLink.textarea.focus();wpLink.range=document.selection.createRange()}},open:function(){if(!wpActiveEditor){return}this.textarea=f("#"+wpActiveEditor).get(0);if(!b.dialog.data("wpdialog")){b.dialog.wpdialog({title:wpLinkL10n.title,width:480,height:"auto",modal:true,dialogClass:"wp-dialog",zIndex:300000})}b.dialog.wpdialog("open")},isMCE:function(){return tinyMCEPopup&&(d=tinyMCEPopup.editor)&&!d.isHidden()},refresh:function(){e.search.refresh();e.recent.refresh();if(wpLink.isMCE()){wpLink.mceRefresh()}else{wpLink.setDefaultValues()}b.url.focus()[0].select();if(!e.recent.ul.children().length){e.recent.ajax()}},mceRefresh:function(){var g;d=tinyMCEPopup.editor;tinyMCEPopup.restoreSelection();if(g=d.dom.getParent(d.selection.getNode(),"A")){b.url.val(d.dom.getAttrib(g,"href"));b.title.val(d.dom.getAttrib(g,"title"));if("_blank"==d.dom.getAttrib(g,"target")){b.openInNewTab.prop("checked",true)}b.submit.val(wpLinkL10n.update)}else{wpLink.setDefaultValues()}tinyMCEPopup.storeSelection()},close:function(){if(wpLink.isMCE()){tinyMCEPopup.close()}else{b.dialog.wpdialog("close")}},onClose:function(){if(!wpLink.isMCE()){wpLink.textarea.focus();if(wpLink.range){wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select()}}},getAttrs:function(){return{href:b.url.val(),title:b.title.val(),target:b.openInNewTab.prop("checked")?"_blank":""}},update:function(){if(wpLink.isMCE()){wpLink.mceUpdate()}else{wpLink.htmlUpdate()}},htmlUpdate:function(){var i,j,k,h,l,g=wpLink.textarea;if(!g){return}i=wpLink.getAttrs();if(!i.href||i.href=="http://"){return}j='";wpLink.range.moveToBookmark(wpLink.range.getBookmark());wpLink.range.select();wpLink.range=null}else{if(typeof g.selectionStart!=="undefined"){k=g.selectionStart;h=g.selectionEnd;selection=g.value.substring(k,h);j=j+selection+"";l=k+j.length;if(k==h){l-="".length}g.value=g.value.substring(0,k)+j+g.value.substring(h,g.value.length);g.selectionStart=g.selectionEnd=l}}wpLink.close();g.focus()},mceUpdate:function(){var h=tinyMCEPopup.editor,i=wpLink.getAttrs(),j,g;tinyMCEPopup.restoreSelection();j=h.dom.getParent(h.selection.getNode(),"A");if(!i.href||i.href=="http://"){if(j){tinyMCEPopup.execCommand("mceBeginUndoLevel");g=h.selection.getBookmark();h.dom.remove(j,1);h.selection.moveToBookmark(g);tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()}return}tinyMCEPopup.execCommand("mceBeginUndoLevel");if(j==null){h.getDoc().execCommand("unlink",false,null);tinyMCEPopup.execCommand("mceInsertLink",false,"#mce_temp_url#",{skip_undo:1});tinymce.each(h.dom.select("a"),function(k){if(h.dom.getAttrib(k,"href")=="#mce_temp_url#"){j=k;h.dom.setAttribs(j,i)}});if(f(j).text()=="#mce_temp_url#"){h.dom.remove(j);j=null}}else{h.dom.setAttribs(j,i)}if(j&&(j.childNodes.length!=1||j.firstChild.nodeName!="IMG")){h.focus();h.selection.select(j);h.selection.collapse(0);tinyMCEPopup.storeSelection()}tinyMCEPopup.execCommand("mceEndUndoLevel");wpLink.close()},updateFields:function(i,h,g){b.url.val(h.children(".item-permalink").val());b.title.val(h.hasClass("no-title")?"":h.children(".item-title").text());if(g&&g.type=="click"){b.url.focus()}},setDefaultValues:function(){b.url.val("http://");b.title.val("");b.submit.val(wpLinkL10n.save)},searchInternalLinks:function(){var h=f(this),i,g=h.val();if(g.length>2){e.recent.hide();e.search.show();if(wpLink.lastSearch==g){return}wpLink.lastSearch=g;i=h.parent().find(".spinner").show();e.search.change(g);e.search.ajax(function(){i.hide()})}else{e.search.hide();e.recent.show()}},next:function(){e.search.next();e.recent.next()},prev:function(){e.search.prev();e.recent.prev()},keydown:function(i){var h,g=f.ui.keyCode;switch(i.which){case g.UP:h="prev";case g.DOWN:h=h||"next";clearInterval(wpLink.keyInterval);wpLink[h]();wpLink.keyInterval=setInterval(wpLink[h],wpLink.keySensitivity);break;default:return}i.preventDefault()},keyup:function(h){var g=f.ui.keyCode;switch(h.which){case g.ESCAPE:h.stopImmediatePropagation();if(!f(document).triggerHandler("wp_CloseOnEscape",[{event:h,what:"wplink",cb:wpLink.close}])){wpLink.close()}return false;break;case g.UP:case g.DOWN:clearInterval(wpLink.keyInterval);break;default:return}h.preventDefault()},delayedCallback:function(i,g){var l,k,j,h;if(!g){return i}setTimeout(function(){if(k){return i.apply(h,j)}l=true},g);return function(){if(l){return i.apply(this,arguments)}j=arguments;h=this;k=true}},toggleInternalLinking:function(h){var g=f("#search-panel"),i=b.dialog.wpdialog("widget"),k=!g.is(":visible"),j=f(window);f(this).toggleClass("toggle-arrow-active",k);b.dialog.height("auto");g.slideToggle(300,function(){setUserSetting("wplink",k?"1":"0");b[k?"search":"url"].focus();var l=j.scrollTop(),o=i.offset().top,m=o+i.outerHeight(),n=m-j.height();if(n>l){i.animate({top:ni){this.element.scrollTop(g+l-i+j)}}this.element.trigger("river-select",[h,k,this])},deselect:function(){if(this.selected){this.selected.removeClass("selected")}this.selected=false},prev:function(){if(!this.visible){return}var g;if(this.selected){g=this.selected.prev("li");if(g.length){this.select(g)}}},next:function(){if(!this.visible){return}var g=this.selected?this.selected.next("li"):f("li:not(.unselectable):first",this.element);if(g.length){this.select(g)}},ajax:function(j){var h=this,i=this.query.page==1?0:wpLink.minRiverAJAXDuration,g=wpLink.delayedCallback(function(k,l){h.process(k,l);if(j){j(k,l)}},i);this.query.ajax(g)},change:function(g){if(this.query&&this._search==g){return}this._search=g;this.query=new c(g);this.element.scrollTop(0)},process:function(h,l){var i="",j=true,g="",k=l.page==1;if(!h){if(k){i+='
  • '+wpLinkL10n.noMatchesFound+"
  • "}}else{f.each(h,function(){g=j?"alternate":"";g+=this["title"]?"":" no-title";i+=g?'
  • ':"
  • ";i+='';i+='';i+=this["title"]?this["title"]:wpLinkL10n.noTitle;i+=''+this["info"]+"
  • ";j=!j})}this.ul[k?"html":"append"](i)},maybeLoad:function(){var h=this,i=this.element,g=i.scrollTop()+i.height();if(!this.query.ready()||g array(), 'a' => array( - 'class' => true, 'href' => true, - 'id' => true, - 'title' => true, 'rel' => true, 'rev' => true, 'name' => true, 'target' => true, ), - 'abbr' => array( - 'class' => true, - 'title' => true, - ), - 'acronym' => array( - 'title' => true, + 'abbr' => array(), + 'acronym' => array(), + 'area' => array( + 'alt' => true, + 'coords' => true, + 'href' => true, + 'nohref' => true, + 'shape' => true, + 'target' => true, ), 'article' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'aside' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'b' => array(), 'big' => array(), 'blockquote' => array( - 'id' => true, 'cite' => true, - 'class' => true, 'lang' => true, 'xml:lang' => true, ), - 'br' => array ( - 'class' => true, - ), + 'br' => array(), 'button' => array( 'disabled' => true, 'name' => true, @@ -103,24 +100,18 @@ if ( ! CUSTOM_TAGS ) { ), 'caption' => array( 'align' => true, - 'class' => true, ), - 'cite' => array ( - 'class' => true, + 'cite' => array( 'dir' => true, 'lang' => true, - 'title' => true, - ), - 'code' => array ( - 'style' => true, ), + 'code' => array(), 'col' => array( 'align' => true, 'char' => true, 'charoff' => true, 'span' => true, 'dir' => true, - 'style' => true, 'valign' => true, 'width' => true, ), @@ -130,19 +121,15 @@ if ( ! CUSTOM_TAGS ) { 'dd' => array(), 'details' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, 'open' => true, - 'style' => true, 'xml:lang' => true, ), 'div' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'dl' => array(), @@ -151,18 +138,14 @@ if ( ! CUSTOM_TAGS ) { 'fieldset' => array(), 'figure' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'figcaption' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'font' => array( @@ -172,10 +155,8 @@ if ( ! CUSTOM_TAGS ) { ), 'footer' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'form' => array( @@ -189,59 +170,36 @@ if ( ! CUSTOM_TAGS ) { ), 'h1' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), - 'h2' => array ( + 'h2' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), - 'h3' => array ( + 'h3' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), - 'h4' => array ( + 'h4' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), - 'h5' => array ( + 'h5' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), - 'h6' => array ( + 'h6' => array( 'align' => true, - 'class' => true, - 'id' => true, - 'style' => true, ), 'header' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'hgroup' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), - 'hr' => array ( + 'hr' => array( 'align' => true, - 'class' => true, 'noshade' => true, 'size' => true, 'width' => true, @@ -251,13 +209,12 @@ if ( ! CUSTOM_TAGS ) { 'alt' => true, 'align' => true, 'border' => true, - 'class' => true, 'height' => true, 'hspace' => true, 'longdesc' => true, 'vspace' => true, 'src' => true, - 'style' => true, + 'usemap' => true, 'width' => true, ), 'ins' => array( @@ -271,65 +228,54 @@ if ( ! CUSTOM_TAGS ) { 'legend' => array( 'align' => true, ), - 'li' => array ( + 'li' => array( 'align' => true, - 'class' => true, ), - 'menu' => array ( - 'class' => true, - 'style' => true, + 'map' => array( + 'name' => true, + ), + 'menu' => array( 'type' => true, ), 'nav' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'p' => array( - 'class' => true, 'align' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'pre' => array( - 'style' => true, 'width' => true, ), 'q' => array( 'cite' => true, ), 's' => array(), - 'span' => array ( - 'class' => true, + 'span' => array( 'dir' => true, 'align' => true, 'lang' => true, - 'style' => true, - 'title' => true, 'xml:lang' => true, ), 'section' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), + 'small' => array(), 'strike' => array(), 'strong' => array(), 'sub' => array(), 'summary' => array( 'align' => true, - 'class' => true, 'dir' => true, 'lang' => true, - 'style' => true, 'xml:lang' => true, ), 'sup' => array(), @@ -339,11 +285,8 @@ if ( ! CUSTOM_TAGS ) { 'border' => true, 'cellpadding' => true, 'cellspacing' => true, - 'class' => true, 'dir' => true, - 'id' => true, 'rules' => true, - 'style' => true, 'summary' => true, 'width' => true, ), @@ -360,7 +303,6 @@ if ( ! CUSTOM_TAGS ) { 'bgcolor' => true, 'char' => true, 'charoff' => true, - 'class' => true, 'colspan' => true, 'dir' => true, 'headers' => true, @@ -368,7 +310,6 @@ if ( ! CUSTOM_TAGS ) { 'nowrap' => true, 'rowspan' => true, 'scope' => true, - 'style' => true, 'valign' => true, 'width' => true, ), @@ -382,7 +323,6 @@ if ( ! CUSTOM_TAGS ) { 'tfoot' => array( 'align' => true, 'char' => true, - 'class' => true, 'charoff' => true, 'valign' => true, ), @@ -393,7 +333,6 @@ if ( ! CUSTOM_TAGS ) { 'bgcolor' => true, 'char' => true, 'charoff' => true, - 'class' => true, 'colspan' => true, 'headers' => true, 'height' => true, @@ -407,7 +346,6 @@ if ( ! CUSTOM_TAGS ) { 'align' => true, 'char' => true, 'charoff' => true, - 'class' => true, 'valign' => true, ), 'title' => array(), @@ -416,21 +354,15 @@ if ( ! CUSTOM_TAGS ) { 'bgcolor' => true, 'char' => true, 'charoff' => true, - 'class' => true, - 'style' => true, 'valign' => true, ), 'tt' => array(), 'u' => array(), - 'ul' => array ( - 'class' => true, - 'style' => true, + 'ul' => array( 'type' => true, ), - 'ol' => array ( - 'class' => true, + 'ol' => array( 'start' => true, - 'style' => true, 'type' => true, ), 'var' => array(), @@ -457,29 +389,18 @@ if ( ! CUSTOM_TAGS ) { 'blockquote' => array( 'cite' => true, ), - // 'br' => array(), 'cite' => array(), 'code' => array(), 'del' => array( 'datetime' => true, ), - // 'dd' => array(), - // 'dl' => array(), - // 'dt' => array(), - 'em' => array (), 'i' => array (), - // 'ins' => array('datetime' => array(), 'cite' => array()), - // 'li' => array(), - // 'ol' => array(), - // 'p' => array(), + 'em' => array(), + 'i' => array(), 'q' => array( 'cite' => true, ), 'strike' => array(), 'strong' => array(), - // 'sub' => array(), - // 'sup' => array(), - // 'u' => array(), - // 'ul' => array(), ); $allowedentitynames = array( @@ -525,6 +446,11 @@ if ( ! CUSTOM_TAGS ) { 'sdot', 'lceil', 'rceil', 'lfloor', 'rfloor', 'lang', 'rang', 'loz', 'spades', 'clubs', 'hearts', 'diams', ); + + $allowedposttags = array_map( '_wp_add_global_attributes', $allowedposttags ); +} else { + $allowedtags = wp_kses_array_lc( $allowedtags ); + $allowedposttags = wp_kses_array_lc( $allowedposttags ); } /** @@ -547,15 +473,51 @@ if ( ! CUSTOM_TAGS ) { * @param array $allowed_protocols Optional. Allowed protocol in links. * @return string Filtered content with only allowed HTML elements */ -function wp_kses($string, $allowed_html, $allowed_protocols = array ()) { +function wp_kses( $string, $allowed_html, $allowed_protocols = array() ) { if ( empty( $allowed_protocols ) ) $allowed_protocols = wp_allowed_protocols(); $string = wp_kses_no_null($string); $string = wp_kses_js_entities($string); $string = wp_kses_normalize_entities($string); - $allowed_html_fixed = wp_kses_array_lc($allowed_html); - $string = wp_kses_hook($string, $allowed_html_fixed, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook - return wp_kses_split($string, $allowed_html_fixed, $allowed_protocols); + $string = wp_kses_hook($string, $allowed_html, $allowed_protocols); // WP changed the order of these funcs and added args to wp_kses_hook + return wp_kses_split($string, $allowed_html, $allowed_protocols); +} + +/** + * Return a list of allowed tags and attributes for a given context. + * + * @since 3.5.0 + * + * @param string $context The context for which to retrieve tags. Allowed values are + * post | strip | data | entities or the name of a field filter such as pre_user_description. + * @return array List of allowed tags and their allowed attributes. + */ +function wp_kses_allowed_html( $context = '' ) { + global $allowedposttags, $allowedtags, $allowedentitynames; + + if ( is_array( $context ) ) + return apply_filters( 'wp_kses_allowed_html', $context, 'explicit' ); + + switch ( $context ) { + case 'post': + return apply_filters( 'wp_kses_allowed_html', $allowedposttags, $context ); + break; + case 'user_description': + case 'pre_user_description': + $tags = $allowedtags; + $tags['a']['rel'] = true; + return apply_filters( 'wp_kses_allowed_html', $tags, $context ); + break; + case 'strip': + return apply_filters( 'wp_kses_allowed_html', array(), $context ); + break; + case 'entities': + return apply_filters( 'wp_kses_allowed_html', $allowedentitynames, $context); + break; + case 'data': + default: + return apply_filters( 'wp_kses_allowed_html', $allowedtags, $context ); + } } /** @@ -571,7 +533,7 @@ function wp_kses($string, $allowed_html, $allowed_protocols = array ()) { * @param array $allowed_protocols Allowed protocol in links * @return string Filtered content through 'pre_kses' hook */ -function wp_kses_hook($string, $allowed_html, $allowed_protocols) { +function wp_kses_hook( $string, $allowed_html, $allowed_protocols ) { $string = apply_filters('pre_kses', $string, $allowed_html, $allowed_protocols); return $string; } @@ -599,7 +561,7 @@ function wp_kses_version() { * @param array $allowed_protocols Allowed protocols to keep * @return string Content with fixed HTML tags */ -function wp_kses_split($string, $allowed_html, $allowed_protocols) { +function wp_kses_split( $string, $allowed_html, $allowed_protocols ) { global $pass_allowed_html, $pass_allowed_protocols; $pass_allowed_html = $allowed_html; $pass_allowed_protocols = $allowed_protocols; @@ -667,6 +629,9 @@ function wp_kses_split2($string, $allowed_html, $allowed_protocols) { $elem = $matches[2]; $attrlist = $matches[3]; + if ( ! is_array( $allowed_html ) ) + $allowed_html = wp_kses_allowed_html( $allowed_html ); + if ( ! isset($allowed_html[strtolower($elem)]) ) return ''; # They are using a not allowed HTML element @@ -698,6 +663,9 @@ function wp_kses_split2($string, $allowed_html, $allowed_protocols) { function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { # Is there a closing XHTML slash at the end of the attributes? + if ( ! is_array( $allowed_html ) ) + $allowed_html = wp_kses_allowed_html( $allowed_html ); + $xhtml_slash = ''; if (preg_match('%\s*/\s*$%', $attr)) $xhtml_slash = ' /'; @@ -776,7 +744,7 @@ function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { * @return array List of attributes after parsing */ function wp_kses_hair($attr, $allowed_protocols) { - $attrarr = array (); + $attrarr = array(); $mode = 0; $attrname = ''; $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action'); @@ -1285,9 +1253,8 @@ function _wp_kses_decode_entities_chr_hexdec( $match ) { * @param string $data Content to filter, expected to be escaped with slashes * @return string Filtered content */ -function wp_filter_kses($data) { - global $allowedtags; - return addslashes( wp_kses(stripslashes( $data ), $allowedtags) ); +function wp_filter_kses( $data ) { + return addslashes( wp_kses( stripslashes( $data ), current_filter() ) ); } /** @@ -1299,9 +1266,8 @@ function wp_filter_kses($data) { * @param string $data Content to filter, expected to not be escaped * @return string Filtered content */ -function wp_kses_data($data) { - global $allowedtags; - return wp_kses( $data , $allowedtags ); +function wp_kses_data( $data ) { + return wp_kses( $data , current_filter() ); } /** @@ -1311,14 +1277,12 @@ function wp_kses_data($data) { * data from forms. * * @since 2.0.0 - * @uses $allowedposttags * * @param string $data Post content to filter, expected to be escaped with slashes * @return string Filtered post content with allowed HTML tags and attributes intact. */ function wp_filter_post_kses($data) { - global $allowedposttags; - return addslashes ( wp_kses(stripslashes( $data ), $allowedposttags) ); + return addslashes ( wp_kses( stripslashes( $data ), 'post' ) ); } /** @@ -1328,14 +1292,12 @@ function wp_filter_post_kses($data) { * data from forms. * * @since 2.9.0 - * @uses $allowedposttags * * @param string $data Post content to filter * @return string Filtered post content with allowed HTML tags and attributes intact. */ function wp_kses_post($data) { - global $allowedposttags; - return wp_kses( $data , $allowedposttags ); + return wp_kses( $data , 'post' ); } /** @@ -1346,8 +1308,8 @@ function wp_kses_post($data) { * @param string $data Content to strip all HTML from * @return string Filtered content without any HTML */ -function wp_filter_nohtml_kses($data) { - return addslashes ( wp_kses(stripslashes( $data ), array()) ); +function wp_filter_nohtml_kses( $data ) { + return addslashes ( wp_kses( stripslashes( $data ), 'strip' ) ); } /** @@ -1483,3 +1445,29 @@ function safecss_filter_attr( $css, $deprecated = '' ) { return $css; } + +/** + * Helper function to add global attributes to a tag in the allowed html list. + * + * @since 3.5.0 + * @access private + * + * @param array $value An array of attributes. + * @return array The array of attributes with global attributes added. + */ +function _wp_add_global_attributes( $value ) { + $global_attributes = array( + 'class' => true, + 'id' => true, + 'style' => true, + 'title' => true, + ); + + if ( true === $value ) + $value = array(); + + if ( is_array( $value ) ) + return array_merge( $value, $global_attributes ); + + return $value; +} diff --git a/wp-includes/l10n.php b/wp-includes/l10n.php index 7ec3c426..750e08de 100644 --- a/wp-includes/l10n.php +++ b/wp-includes/l10n.php @@ -65,7 +65,7 @@ function get_locale() { * @return string Translated text */ function translate( $text, $domain = 'default' ) { - $translations = &get_translations_for_domain( $domain ); + $translations = get_translations_for_domain( $domain ); return apply_filters( 'gettext', $translations->translate( $text ), $text, $domain ); } @@ -78,7 +78,7 @@ function before_last_bar( $string ) { } function translate_with_gettext_context( $text, $context, $domain = 'default' ) { - $translations = &get_translations_for_domain( $domain ); + $translations = get_translations_for_domain( $domain ); return apply_filters( 'gettext_with_context', $translations->translate( $text, $context ), $text, $context, $domain ); } @@ -236,7 +236,7 @@ function esc_html_x( $single, $context, $domain = 'default' ) { * @return string Either $single or $plural translated text */ function _n( $single, $plural, $number, $domain = 'default' ) { - $translations = &get_translations_for_domain( $domain ); + $translations = get_translations_for_domain( $domain ); $translation = $translations->translate_plural( $single, $plural, $number ); return apply_filters( 'ngettext', $translation, $single, $plural, $number, $domain ); } @@ -249,7 +249,7 @@ function _n( $single, $plural, $number, $domain = 'default' ) { * */ function _nx($single, $plural, $number, $context, $domain = 'default') { - $translations = &get_translations_for_domain( $domain ); + $translations = get_translations_for_domain( $domain ); $translation = $translations->translate_plural( $single, $plural, $number, $context ); return apply_filters( 'ngettext_with_context', $translation, $single, $plural, $number, $context, $domain ); } @@ -459,9 +459,16 @@ function load_muplugin_textdomain( $domain, $mu_plugin_rel_path = '' ) { function load_theme_textdomain( $domain, $path = false ) { $locale = apply_filters( 'theme_locale', get_locale(), $domain ); - $path = ( empty( $path ) ) ? get_template_directory() : $path; + if ( ! $path ) + $path = get_template_directory(); - $mofile = "$path/$locale.mo"; + // Load the textdomain from the Theme provided location, or theme directory first + $mofile = "{$path}/{$locale}.mo"; + if ( $loaded = load_textdomain($domain, $mofile) ) + return $loaded; + + // Else, load textdomain from the Language directory + $mofile = WP_LANG_DIR . "/themes/{$domain}-{$locale}.mo"; return load_textdomain($domain, $mofile); } @@ -478,12 +485,9 @@ function load_theme_textdomain( $domain, $path = false ) { * @param string $domain Unique identifier for retrieving translated strings */ function load_child_theme_textdomain( $domain, $path = false ) { - $locale = apply_filters( 'theme_locale', get_locale(), $domain ); - - $path = ( empty( $path ) ) ? get_stylesheet_directory() : $path; - - $mofile = "$path/$locale.mo"; - return load_textdomain($domain, $mofile); + if ( ! $path ) + $path = get_stylesheet_directory(); + return load_theme_textdomain( $domain, $path ); } /** @@ -493,7 +497,7 @@ function load_child_theme_textdomain( $domain, $path = false ) { * @param string $domain * @return object A Translation instance */ -function &get_translations_for_domain( $domain ) { +function get_translations_for_domain( $domain ) { global $l10n; if ( !isset( $l10n[$domain] ) ) { $l10n[$domain] = new NOOP_Translations; diff --git a/wp-includes/link-template.php b/wp-includes/link-template.php index ae8a9f13..de76f45a 100644 --- a/wp-includes/link-template.php +++ b/wp-includes/link-template.php @@ -54,11 +54,11 @@ function user_trailingslashit($string, $type_of_url = '') { * * @param string $mode Permalink mode can be either 'title', 'id', or default, which is 'id'. */ -function permalink_anchor($mode = 'id') { - global $post; - switch ( strtolower($mode) ) { +function permalink_anchor( $mode = 'id' ) { + $post = get_post(); + switch ( strtolower( $mode ) ) { case 'title': - $title = sanitize_title($post->post_title) . '-' . $post->ID; + $title = sanitize_title( $post->post_title ) . '-' . $post->ID; echo ''; break; case 'id': @@ -77,7 +77,7 @@ function permalink_anchor($mode = 'id') { * @param bool $leavename Optional, defaults to false. Whether to keep post name or page name. * @return string */ -function get_permalink($id = 0, $leavename = false) { +function get_permalink( $id = 0, $leavename = false ) { $rewritecode = array( '%year%', '%monthnum%', @@ -96,7 +96,7 @@ function get_permalink($id = 0, $leavename = false) { $post = $id; $sample = true; } else { - $post = &get_post($id); + $post = get_post($id); $sample = false; } @@ -106,7 +106,7 @@ function get_permalink($id = 0, $leavename = false) { if ( $post->post_type == 'page' ) return get_page_link($post->ID, $leavename, $sample); elseif ( $post->post_type == 'attachment' ) - return get_attachment_link($post->ID); + return get_attachment_link( $post->ID, $leavename ); elseif ( in_array($post->post_type, get_post_types( array('_builtin' => false) ) ) ) return get_post_permalink($post->ID, $leavename, $sample); @@ -122,8 +122,10 @@ function get_permalink($id = 0, $leavename = false) { $cats = get_the_category($post->ID); if ( $cats ) { usort($cats, '_usort_terms_by_ID'); // order by ID - $category = $cats[0]->slug; - if ( $parent = $cats[0]->parent ) + $category_object = apply_filters( 'post_link_category', $cats[0], $cats, $post ); + $category_object = get_term( $category_object, 'category' ); + $category = $category_object->slug; + if ( $parent = $category_object->parent ) $category = get_category_parents($parent, false, '/', true) . $category; } // show default category in permalinks, without @@ -176,7 +178,7 @@ function get_permalink($id = 0, $leavename = false) { function get_post_permalink( $id = 0, $leavename = false, $sample = false ) { global $wp_rewrite; - $post = &get_post($id); + $post = get_post($id); if ( is_wp_error( $post ) ) return $post; @@ -230,24 +232,20 @@ function post_permalink( $post_id = 0, $deprecated = '' ) { * * @since 1.5.0 * - * @param int $id Optional. Post ID. + * @param mixed $post Optional. Post ID or object. * @param bool $leavename Optional, defaults to false. Whether to keep page name. * @param bool $sample Optional, defaults to false. Is it a sample permalink. * @return string */ -function get_page_link( $id = false, $leavename = false, $sample = false ) { - global $post; - - $id = (int) $id; - if ( !$id ) - $id = (int) $post->ID; +function get_page_link( $post = false, $leavename = false, $sample = false ) { + $post = get_post( $post ); - if ( 'page' == get_option('show_on_front') && $id == get_option('page_on_front') ) + if ( 'page' == get_option( 'show_on_front' ) && $post->ID == get_option( 'page_on_front' ) ) $link = home_url('/'); else - $link = _get_page_link( $id , $leavename, $sample ); + $link = _get_page_link( $post, $leavename, $sample ); - return apply_filters('page_link', $link, $id, $sample); + return apply_filters( 'page_link', $link, $post->ID, $sample ); } /** @@ -258,18 +256,15 @@ function get_page_link( $id = false, $leavename = false, $sample = false ) { * @since 2.1.0 * @access private * - * @param int $id Optional. Post ID. + * @param mixed $post Optional. Post ID or object. * @param bool $leavename Optional. Leave name. * @param bool $sample Optional. Sample permalink. * @return string */ -function _get_page_link( $id = false, $leavename = false, $sample = false ) { - global $post, $wp_rewrite; +function _get_page_link( $post = false, $leavename = false, $sample = false ) { + global $wp_rewrite; - if ( !$id ) - $id = (int) $post->ID; - else - $post = &get_post($id); + $post = get_post( $post ); $draft_or_pending = in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ); @@ -277,16 +272,16 @@ function _get_page_link( $id = false, $leavename = false, $sample = false ) { if ( !empty($link) && ( ( isset($post->post_status) && !$draft_or_pending ) || $sample ) ) { if ( ! $leavename ) { - $link = str_replace('%pagename%', get_page_uri($id), $link); + $link = str_replace('%pagename%', get_page_uri( $post ), $link); } $link = home_url($link); $link = user_trailingslashit($link, 'page'); } else { - $link = home_url("?page_id=$id"); + $link = home_url( '?page_id=' . $post->ID ); } - return apply_filters( '_get_page_link', $link, $id ); + return apply_filters( '_get_page_link', $link, $post->ID ); } /** @@ -296,38 +291,40 @@ function _get_page_link( $id = false, $leavename = false, $sample = false ) { * * @since 2.0.0 * - * @param int $id Optional. Post ID. + * @param mixed $post Optional. Post ID or object. + * @param bool $leavename Optional. Leave name. * @return string */ -function get_attachment_link($id = false) { - global $post, $wp_rewrite; +function get_attachment_link( $post = null, $leavename = false ) { + global $wp_rewrite; $link = false; - if ( ! $id) - $id = (int) $post->ID; + $post = get_post( $post ); - $object = get_post($id); - if ( $wp_rewrite->using_permalinks() && ($object->post_parent > 0) && ($object->post_parent != $id) ) { - $parent = get_post($object->post_parent); + if ( $wp_rewrite->using_permalinks() && ( $post->post_parent > 0 ) && ( $post->post_parent != $post->ID ) ) { + $parent = get_post($post->post_parent); if ( 'page' == $parent->post_type ) - $parentlink = _get_page_link( $object->post_parent ); // Ignores page_on_front + $parentlink = _get_page_link( $post->post_parent ); // Ignores page_on_front else - $parentlink = get_permalink( $object->post_parent ); + $parentlink = get_permalink( $post->post_parent ); - if ( is_numeric($object->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') ) - $name = 'attachment/' . $object->post_name; // // is paged so we use the explicit attachment marker + if ( is_numeric($post->post_name) || false !== strpos(get_option('permalink_structure'), '%category%') ) + $name = 'attachment/' . $post->post_name; // // is paged so we use the explicit attachment marker else - $name = $object->post_name; + $name = $post->post_name; if ( strpos($parentlink, '?') === false ) - $link = user_trailingslashit( trailingslashit($parentlink) . $name ); + $link = user_trailingslashit( trailingslashit($parentlink) . '%postname%' ); + + if ( ! $leavename ) + $link = str_replace( '%postname%', $name, $link ); } if ( ! $link ) - $link = home_url( "/?attachment_id=$id" ); + $link = home_url( '/?attachment_id=' . $post->ID ); - return apply_filters('attachment_link', $link, $id); + return apply_filters( 'attachment_link', $link, $post->ID ); } /** @@ -487,9 +484,9 @@ function get_post_comments_feed_link($post_id = 0, $feed = '') { } else { $type = get_post_field('post_type', $post_id); if ( 'page' == $type ) - $url = home_url("?feed=$feed&page_id=$post_id"); + $url = add_query_arg( array( 'feed' => $feed, 'page_id' => $post_id ), home_url( '/' ) ); else - $url = home_url("?feed=$feed&p=$post_id"); + $url = add_query_arg( array( 'feed' => $feed, 'p' => $post_id ), home_url( '/' ) ); } return apply_filters('post_comments_feed_link', $url); @@ -512,7 +509,7 @@ function get_post_comments_feed_link($post_id = 0, $feed = '') { * @return string Link to the comment feed for the current post. */ function post_comments_feed_link( $link_text = '', $post_id = '', $feed = '' ) { - $url = get_post_comments_feed_link($post_id, $feed); + $url = esc_url( get_post_comments_feed_link( $post_id, $feed ) ); if ( empty($link_text) ) $link_text = __('Comments Feed'); @@ -624,7 +621,7 @@ function get_term_feed_link( $term_id, $taxonomy = 'category', $feed = '' ) { if ( 'category' == $taxonomy ) $link = apply_filters( 'category_feed_link', $link, $feed ); elseif ( 'post_tag' == $taxonomy ) - $link = apply_filters( 'category_feed_link', $link, $feed ); + $link = apply_filters( 'tag_feed_link', $link, $feed ); else $link = apply_filters( 'taxonomy_feed_link', $link, $feed, $taxonomy ); @@ -896,7 +893,7 @@ function get_post_type_archive_feed_link( $post_type, $feed = '' ) { * @return string */ function get_edit_post_link( $id = 0, $context = 'display' ) { - if ( !$post = &get_post( $id ) ) + if ( ! $post = get_post( $id ) ) return; if ( 'display' == $context ) @@ -925,7 +922,7 @@ function get_edit_post_link( $id = 0, $context = 'display' ) { * @param int $id Optional. Post ID. */ function edit_post_link( $link = null, $before = '', $after = '', $id = 0 ) { - if ( !$post = &get_post( $id ) ) + if ( !$post = get_post( $id ) ) return; if ( !$url = get_edit_post_link( $post->ID ) ) @@ -955,7 +952,7 @@ function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false if ( ! empty( $deprecated ) ) _deprecated_argument( __FUNCTION__, '3.0' ); - if ( !$post = &get_post( $id ) ) + if ( !$post = get_post( $id ) ) return; $post_type_object = get_post_type_object( $post->post_type ); @@ -969,7 +966,7 @@ function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false $delete_link = add_query_arg( 'action', $action, admin_url( sprintf( $post_type_object->_edit_link, $post->ID ) ) ); - return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-{$post->post_type}_{$post->ID}" ), $post->ID, $force_delete ); + return apply_filters( 'get_delete_post_link', wp_nonce_url( $delete_link, "$action-post_{$post->ID}" ), $post->ID, $force_delete ); } /** @@ -981,7 +978,7 @@ function get_delete_post_link( $id = 0, $deprecated = '', $force_delete = false * @return string */ function get_edit_comment_link( $comment_id = 0 ) { - $comment = &get_comment( $comment_id ); + $comment = get_comment( $comment_id ); if ( !current_user_can( 'edit_comment', $comment->comment_ID ) ) return; @@ -1054,6 +1051,34 @@ function edit_bookmark_link( $link = '', $before = '', $after = '', $bookmark = echo $before . apply_filters( 'edit_bookmark_link', $link, $bookmark->link_id ) . $after; } +/** + * Retrieve edit user link + * + * @since 3.5.0 + * + * @param int $user_id Optional. User ID. Defaults to the current user. + * @return string URL to edit user page or empty string. + */ +function get_edit_user_link( $user_id = null ) { + if ( ! $user_id ) + $user_id = get_current_user_id(); + + if ( empty( $user_id ) || ! current_user_can( 'edit_user', $user_id ) ) + return ''; + + $user = get_userdata( $user_id ); + + if ( ! $user ) + return ''; + + if ( get_current_user_id() == $user->ID ) + $link = get_edit_profile_url( $user->ID ); + else + $link = add_query_arg( 'user_id', $user->ID, self_admin_url( 'user-edit.php' ) ); + + return apply_filters( 'get_edit_user_link', $link, $user->ID ); +} + // Navigation links /** @@ -1095,9 +1120,9 @@ function get_next_post($in_same_cat = false, $excluded_categories = '') { * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists. */ function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $previous = true ) { - global $post, $wpdb; + global $wpdb; - if ( empty( $post ) ) + if ( ! $post = get_post() ) return null; $current_post_date = $post->post_date; @@ -1108,7 +1133,11 @@ function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $pr $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"; if ( $in_same_cat ) { + if ( ! is_object_in_taxonomy( $post->post_type, 'category' ) ) + return ''; $cat_array = wp_get_object_terms($post->ID, 'category', array('fields' => 'ids')); + if ( ! $cat_array || is_wp_error( $cat_array ) ) + return ''; $join .= " AND tt.taxonomy = 'category' AND tt.term_id IN (" . implode(',', $cat_array) . ")"; } @@ -1145,17 +1174,24 @@ function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $pr $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $posts_in_ex_cats_sql", $current_post_date, $post->post_type), $in_same_cat, $excluded_categories ); $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1" ); - $query = "SELECT p.* FROM $wpdb->posts AS p $join $where $sort"; + $query = "SELECT p.id FROM $wpdb->posts AS p $join $where $sort"; $query_key = 'adjacent_post_' . md5($query); $result = wp_cache_get($query_key, 'counts'); - if ( false !== $result ) + if ( false !== $result ) { + if ( $result ) + $result = get_post( $result ); return $result; + } - $result = $wpdb->get_row("SELECT p.* FROM $wpdb->posts AS p $join $where $sort"); + $result = $wpdb->get_var( $query ); if ( null === $result ) $result = ''; wp_cache_set($query_key, $result, 'counts'); + + if ( $result ) + $result = get_post( $result ); + return $result; } @@ -1173,20 +1209,22 @@ function get_adjacent_post( $in_same_cat = false, $excluded_categories = '', $pr * @return string */ function get_adjacent_post_rel_link($title = '%title', $in_same_cat = false, $excluded_categories = '', $previous = true) { - if ( $previous && is_attachment() && is_object( $GLOBALS['post'] ) ) - $post = & get_post($GLOBALS['post']->post_parent); + if ( $previous && is_attachment() && $post = get_post() ) + $post = get_post( $post->post_parent ); else - $post = get_adjacent_post($in_same_cat,$excluded_categories,$previous); + $post = get_adjacent_post( $in_same_cat, $excluded_categories, $previous ); if ( empty($post) ) return; if ( empty($post->post_title) ) - $post->post_title = $previous ? __('Previous Post') : __('Next Post'); + $post_title = $previous ? __('Previous Post') : __('Next Post'); + else + $post_title = $post->post_title; $date = mysql2date(get_option('date_format'), $post->post_date); - $title = str_replace('%title', $post->post_title, $title); + $title = str_replace('%title', $post_title, $title); $title = str_replace('%date', $date, $title); $title = apply_filters('the_title', $title, $post->ID); @@ -1265,9 +1303,8 @@ function prev_post_rel_link($title = '%title', $in_same_cat = false, $excluded_c * @return object */ function get_boundary_post( $in_same_cat = false, $excluded_categories = '', $start = true ) { - global $post; - - if ( empty($post) || ! is_single() || is_attachment() ) + $post = get_post(); + if ( ! $post || ! is_single() || is_attachment() ) return null; $cat_array = array(); @@ -1337,33 +1374,35 @@ function next_post_link($format='%link »', $link='%title', $in_same_cat = * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs. * @param bool $previous Optional, default is true. Whether to display link to previous or next post. */ -function adjacent_post_link($format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true) { +function adjacent_post_link( $format, $link, $in_same_cat = false, $excluded_categories = '', $previous = true ) { if ( $previous && is_attachment() ) - $post = & get_post($GLOBALS['post']->post_parent); + $post = get_post( get_post()->post_parent ); else - $post = get_adjacent_post($in_same_cat, $excluded_categories, $previous); - - if ( !$post ) - return; + $post = get_adjacent_post( $in_same_cat, $excluded_categories, $previous ); - $title = $post->post_title; + if ( ! $post ) { + $output = ''; + } else { + $title = $post->post_title; - if ( empty($post->post_title) ) - $title = $previous ? __('Previous Post') : __('Next Post'); + if ( empty( $post->post_title ) ) + $title = $previous ? __( 'Previous Post' ) : __( 'Next Post' ); - $title = apply_filters('the_title', $title, $post->ID); - $date = mysql2date(get_option('date_format'), $post->post_date); - $rel = $previous ? 'prev' : 'next'; + $title = apply_filters( 'the_title', $title, $post->ID ); + $date = mysql2date( get_option( 'date_format' ), $post->post_date ); + $rel = $previous ? 'prev' : 'next'; - $string = ''; - $link = str_replace('%title', $title, $link); - $link = str_replace('%date', $date, $link); - $link = $string . $link . ''; + $string = ''; + $inlink = str_replace( '%title', $title, $link ); + $inlink = str_replace( '%date', $date, $inlink ); + $inlink = $string . $inlink . ''; - $format = str_replace('%link', $link, $format); + $output = str_replace( '%link', $inlink, $format ); + } $adjacent = $previous ? 'previous' : 'next'; - echo apply_filters( "{$adjacent}_post_link", $format, $link ); + + echo apply_filters( "{$adjacent}_post_link", $output, $format, $link, $post ); } /** @@ -1385,9 +1424,9 @@ function get_pagenum_link($pagenum = 1, $escape = true ) { $home_root = parse_url(home_url()); $home_root = ( isset($home_root['path']) ) ? $home_root['path'] : ''; - $home_root = preg_quote( trailingslashit( $home_root ), '|' ); + $home_root = preg_quote( $home_root, '|' ); - $request = preg_replace('|^'. $home_root . '|', '', $request); + $request = preg_replace('|^'. $home_root . '|i', '', $request); $request = preg_replace('|^/+|', '', $request); if ( !$wp_rewrite->using_permalinks() || is_admin() ) { @@ -1410,7 +1449,7 @@ function get_pagenum_link($pagenum = 1, $escape = true ) { } $request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request); - $request = preg_replace( '|^index\.php|', '', $request); + $request = preg_replace( '|^index\.php|i', '', $request); $request = ltrim($request, '/'); $base = trailingslashit( get_bloginfo( 'url' ) ); @@ -1646,11 +1685,11 @@ function posts_nav_link( $sep = '', $prelabel = '', $nxtlabel = '' ) { * @return string */ function get_comments_pagenum_link( $pagenum = 1, $max_page = 0 ) { - global $post, $wp_rewrite; + global $wp_rewrite; $pagenum = (int) $pagenum; - $result = get_permalink( $post->ID ); + $result = get_permalink(); if ( 'newest' == get_option('default_comments_page') ) { if ( $pagenum != $max_page ) { @@ -1842,7 +1881,7 @@ function get_shortcut_link() { * @return string Home url link with optional path appended. */ function home_url( $path = '', $scheme = null ) { - return get_home_url(null, $path, $scheme); + return get_home_url( null, $path, $scheme ); } /** @@ -1863,20 +1902,24 @@ function home_url( $path = '', $scheme = null ) { function get_home_url( $blog_id = null, $path = '', $scheme = null ) { $orig_scheme = $scheme; - if ( !in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) - $scheme = is_ssl() && !is_admin() ? 'https' : 'http'; - - if ( empty( $blog_id ) || !is_multisite() ) + if ( empty( $blog_id ) || !is_multisite() ) { $url = get_option( 'home' ); - else - $url = get_blog_option( $blog_id, 'home' ); + } else { + switch_to_blog( $blog_id ); + $url = get_option( 'home' ); + restore_current_blog(); + } - if ( 'relative' == $scheme ) - $url = preg_replace( '#^.+://[^/]*#', '', $url ); - elseif ( 'http' != $scheme ) - $url = str_replace( 'http://', "$scheme://", $url ); + if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) { + if ( is_ssl() && ! is_admin() ) + $scheme = 'https'; + else + $scheme = parse_url( $url, PHP_URL_SCHEME ); + } - if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) + $url = set_url_scheme( $url, $scheme ); + + if ( ! empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= '/' . ltrim( $path, '/' ); return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id ); @@ -1895,11 +1938,11 @@ function get_home_url( $blog_id = null, $path = '', $scheme = null ) { * @uses get_site_url() * * @param string $path Optional. Path relative to the site url. - * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', 'admin', or 'relative'. + * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme(). * @return string Site url link with optional path appended. */ function site_url( $path = '', $scheme = null ) { - return get_site_url(null, $path, $scheme); + return get_site_url( null, $path, $scheme ); } /** @@ -1918,33 +1961,20 @@ function site_url( $path = '', $scheme = null ) { * @return string Site url link with optional path appended. */ function get_site_url( $blog_id = null, $path = '', $scheme = null ) { - // should the list of allowed schemes be maintained elsewhere? - $orig_scheme = $scheme; - if ( !in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) { - if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) ) - $scheme = 'https'; - elseif ( ( 'login' == $scheme ) && force_ssl_admin() ) - $scheme = 'https'; - elseif ( ( 'admin' == $scheme ) && force_ssl_admin() ) - $scheme = 'https'; - else - $scheme = ( is_ssl() ? 'https' : 'http' ); - } - - if ( empty( $blog_id ) || !is_multisite() ) + if ( empty( $blog_id ) || !is_multisite() ) { $url = get_option( 'siteurl' ); - else - $url = get_blog_option( $blog_id, 'siteurl' ); + } else { + switch_to_blog( $blog_id ); + $url = get_option( 'siteurl' ); + restore_current_blog(); + } - if ( 'relative' == $scheme ) - $url = preg_replace( '#^.+://[^/]*#', '', $url ); - elseif ( 'http' != $scheme ) - $url = str_replace( 'http://', "{$scheme}://", $url ); + $url = set_url_scheme( $url, $scheme ); - if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) + if ( ! empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= '/' . ltrim( $path, '/' ); - return apply_filters( 'site_url', $url, $path, $orig_scheme, $blog_id ); + return apply_filters( 'site_url', $url, $path, $scheme, $blog_id ); } /** @@ -1958,7 +1988,7 @@ function get_site_url( $blog_id = null, $path = '', $scheme = null ) { * @return string Admin url link with optional path appended. */ function admin_url( $path = '', $scheme = 'admin' ) { - return get_admin_url(null, $path, $scheme); + return get_admin_url( null, $path, $scheme ); } /** @@ -1975,10 +2005,10 @@ function admin_url( $path = '', $scheme = 'admin' ) { function get_admin_url( $blog_id = null, $path = '', $scheme = 'admin' ) { $url = get_site_url($blog_id, 'wp-admin/', $scheme); - if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) - $url .= ltrim($path, '/'); + if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) + $url .= ltrim( $path, '/' ); - return apply_filters('admin_url', $url, $path, $blog_id); + return apply_filters( 'admin_url', $url, $path, $blog_id ); } /** @@ -2009,9 +2039,7 @@ function includes_url($path = '') { * @return string Content url link with optional path appended. */ function content_url($path = '') { - $url = WP_CONTENT_URL; - if ( 0 === strpos($url, 'http') && is_ssl() ) - $url = str_replace( 'http://', 'https://', $url ); + $url = set_url_scheme( WP_CONTENT_URL ); if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) $url .= '/' . ltrim($path, '/'); @@ -2043,8 +2071,8 @@ function plugins_url($path = '', $plugin = '') { else $url = WP_PLUGIN_URL; - if ( 0 === strpos($url, 'http') && is_ssl() ) - $url = str_replace( 'http://', 'https://', $url ); + + $url = set_url_scheme( $url ); if ( !empty($plugin) && is_string($plugin) ) { $folder = dirname(plugin_basename($plugin)); @@ -2069,36 +2097,24 @@ function plugins_url($path = '', $plugin = '') { * @since 3.0.0 * * @param string $path Optional. Path relative to the site url. - * @param string $scheme Optional. Scheme to give the site url context. Currently 'http', 'https', 'login', 'login_post', 'admin', or 'relative'. + * @param string $scheme Optional. Scheme to give the site url context. See set_url_scheme(). * @return string Site url link with optional path appended. */ function network_site_url( $path = '', $scheme = null ) { global $current_site; - if ( !is_multisite() ) + if ( ! is_multisite() ) return site_url($path, $scheme); - $orig_scheme = $scheme; - if ( !in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) { - if ( ( 'login_post' == $scheme || 'rpc' == $scheme ) && ( force_ssl_login() || force_ssl_admin() ) ) - $scheme = 'https'; - elseif ( ('login' == $scheme) && ( force_ssl_admin() ) ) - $scheme = 'https'; - elseif ( ('admin' == $scheme) && force_ssl_admin() ) - $scheme = 'https'; - else - $scheme = ( is_ssl() ? 'https' : 'http' ); - } - if ( 'relative' == $scheme ) $url = $current_site->path; else - $url = $scheme . '://' . $current_site->domain . $current_site->path; + $url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme ); - if ( !empty($path) && is_string($path) && strpos($path, '..') === false ) - $url .= ltrim($path, '/'); + if ( ! empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) + $url .= ltrim( $path, '/' ); - return apply_filters('network_site_url', $url, $path, $orig_scheme); + return apply_filters( 'network_site_url', $url, $path, $scheme ); } /** @@ -2118,20 +2134,20 @@ function network_site_url( $path = '', $scheme = null ) { function network_home_url( $path = '', $scheme = null ) { global $current_site; - if ( !is_multisite() ) + if ( ! is_multisite() ) return home_url($path, $scheme); $orig_scheme = $scheme; - if ( !in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) - $scheme = is_ssl() && !is_admin() ? 'https' : 'http'; + if ( ! in_array( $scheme, array( 'http', 'https', 'relative' ) ) ) + $scheme = is_ssl() && ! is_admin() ? 'https' : 'http'; if ( 'relative' == $scheme ) $url = $current_site->path; else - $url = $scheme . '://' . $current_site->domain . $current_site->path; + $url = set_url_scheme( 'http://' . $current_site->domain . $current_site->path, $scheme ); - if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) + if ( ! empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false ) $url .= ltrim( $path, '/' ); return apply_filters( 'network_home_url', $url, $path, $orig_scheme); @@ -2302,6 +2318,10 @@ function rel_canonical() { return; $link = get_permalink( $id ); + + if ( $page = get_query_var('cpage') ) + $link = get_comments_pagenum_link( $page ); + echo "\n"; } @@ -2401,7 +2421,7 @@ function wp_shortlink_header() { * @param string $after Optional HTML to display after the link. */ function the_shortlink( $text = '', $title = '', $before = '', $after = '' ) { - global $post; + $post = get_post(); if ( empty( $text ) ) $text = __('This is the short link.'); diff --git a/wp-includes/load.php b/wp-includes/load.php index 7e026203..1742af40 100644 --- a/wp-includes/load.php +++ b/wp-includes/load.php @@ -356,7 +356,7 @@ function wp_set_wpdb_vars() { dead_db(); $wpdb->field_types = array( 'post_author' => '%d', 'post_parent' => '%d', 'menu_order' => '%d', 'term_id' => '%d', 'term_group' => '%d', 'term_taxonomy_id' => '%d', - 'parent' => '%d', 'count' => '%d','object_id' => '%d', 'term_order' => '%d', 'ID' => '%d', 'commment_ID' => '%d', 'comment_post_ID' => '%d', 'comment_parent' => '%d', + 'parent' => '%d', 'count' => '%d','object_id' => '%d', 'term_order' => '%d', 'ID' => '%d', 'comment_ID' => '%d', 'comment_post_ID' => '%d', 'comment_parent' => '%d', 'user_id' => '%d', 'link_id' => '%d', 'link_owner' => '%d', 'link_rating' => '%d', 'option_id' => '%d', 'blog_id' => '%d', 'meta_id' => '%d', 'post_id' => '%d', 'user_status' => '%d', 'umeta_id' => '%d', 'comment_karma' => '%d', 'comment_count' => '%d', // multisite: @@ -381,7 +381,7 @@ function wp_set_wpdb_vars() { * @since 3.0.0 */ function wp_start_object_cache() { - global $_wp_using_ext_object_cache; + global $_wp_using_ext_object_cache, $blog_id; $first_init = false; if ( ! function_exists( 'wp_cache_init' ) ) { @@ -403,13 +403,13 @@ function wp_start_object_cache() { // If cache supports reset, reset instead of init if already initialized. // Reset signals to the cache that global IDs have changed and it may need to update keys // and cleanup caches. - if ( !$first_init && function_exists('wp_cache_reset') ) - wp_cache_reset(); + if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) ) + wp_cache_switch_to_blog( $blog_id ); else wp_cache_init(); if ( function_exists( 'wp_cache_add_global_groups' ) ) { - wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) ); wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); } } @@ -583,8 +583,11 @@ function wp_clone( $object ) { * @return bool True if inside WordPress administration pages. */ function is_admin() { - if ( defined( 'WP_ADMIN' ) ) + if ( isset( $GLOBALS['current_screen'] ) ) + return $GLOBALS['current_screen']->in_admin(); + elseif ( defined( 'WP_ADMIN' ) ) return WP_ADMIN; + return false; } @@ -599,8 +602,11 @@ function is_admin() { * @return bool True if inside WordPress network administration pages. */ function is_blog_admin() { - if ( defined( 'WP_BLOG_ADMIN' ) ) + if ( isset( $GLOBALS['current_screen'] ) ) + return $GLOBALS['current_screen']->in_admin( 'site' ); + elseif ( defined( 'WP_BLOG_ADMIN' ) ) return WP_BLOG_ADMIN; + return false; } @@ -615,8 +621,11 @@ function is_blog_admin() { * @return bool True if inside WordPress network administration pages. */ function is_network_admin() { - if ( defined( 'WP_NETWORK_ADMIN' ) ) + if ( isset( $GLOBALS['current_screen'] ) ) + return $GLOBALS['current_screen']->in_admin( 'network' ); + elseif ( defined( 'WP_NETWORK_ADMIN' ) ) return WP_NETWORK_ADMIN; + return false; } @@ -631,8 +640,11 @@ function is_network_admin() { * @return bool True if inside WordPress user administration pages. */ function is_user_admin() { - if ( defined( 'WP_USER_ADMIN' ) ) + if ( isset( $GLOBALS['current_screen'] ) ) + return $GLOBALS['current_screen']->in_admin( 'user' ); + elseif ( defined( 'WP_USER_ADMIN' ) ) return WP_USER_ADMIN; + return false; } @@ -653,6 +665,18 @@ function is_multisite() { return false; } +/** + * Retrieve the current blog id + * + * @since 3.1.0 + * + * @return int Blog id + */ +function get_current_blog_id() { + global $blog_id; + return absint($blog_id); +} + /** * Attempts an early load of translations. * diff --git a/wp-includes/media-template.php b/wp-includes/media-template.php new file mode 100644 index 00000000..909ddfe5 --- /dev/null +++ b/wp-includes/media-template.php @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 && is_admin() ) // Only in admin. Assume that theme authors know what they're doing. + if ( intval($content_width) > 0 && 'edit' == $context ) // Only in admin. Assume that theme authors know what they're doing. $max_width = min( intval($content_width), $max_width ); } // $size == 'full' has no constraint @@ -73,7 +78,7 @@ function image_constrain_size_for_editor($width, $height, $size = 'medium') { $max_height = $height; } - list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size ); + list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context ); return wp_constrain_dimensions( $width, $height, $max_width, $max_height ); } @@ -225,44 +230,18 @@ function get_image_tag($id, $alt, $title, $align, $size='medium') { list( $img_src, $width, $height ) = image_downsize($id, $size); $hwstring = image_hwstring($width, $height); + $title = $title ? 'title="' . esc_attr( $title ) . '" ' : ''; + $class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id; $class = apply_filters('get_image_tag_class', $class, $id, $align, $size); - $html = '' . esc_attr($alt) . ''; + $html = '' . esc_attr($alt) . ''; $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); return $html; } -/** - * Load an image from a string, if PHP supports it. - * - * @since 2.1.0 - * - * @param string $file Filename of the image to load. - * @return resource The resulting image resource on success, Error string on failure. - */ -function wp_load_image( $file ) { - if ( is_numeric( $file ) ) - $file = get_attached_file( $file ); - - if ( ! file_exists( $file ) ) - return sprintf(__('File “%s” doesn’t exist?'), $file); - - if ( ! function_exists('imagecreatefromstring') ) - return __('The GD image library is not installed.'); - - // Set artificially high because GD uses uncompressed images in memory - @ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) ); - $image = imagecreatefromstring( file_get_contents( $file ) ); - - if ( !is_resource( $image ) ) - return sprintf(__('File “%s” is not an image.'), $file); - - return $image; -} - /** * Calculates the new dimensions for a downsampled image. * @@ -320,7 +299,7 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width=0, } /** - * Retrieve calculated resized dimensions for use in imagecopyresampled(). + * Retrieve calculated resized dimensions for use in WP_Image_Editor. * * Calculate dimensions and coordinates for a resized image that fits within a * specified width and height. If $crop is true, the largest matching central @@ -392,92 +371,6 @@ function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = fal } -/** - * Scale down an image to fit a particular size and save a new copy of the image. - * - * The PNG transparency will be preserved using the function, as well as the - * image type. If the file going in is PNG, then the resized image is going to - * be PNG. The only supported image types are PNG, GIF, and JPEG. - * - * Some functionality requires API to exist, so some PHP version may lose out - * support. This is not the fault of WordPress (where functionality is - * downgraded, not actual defects), but of your PHP version. - * - * @since 2.5.0 - * - * @param string $file Image file path. - * @param int $max_w Maximum width to resize to. - * @param int $max_h Maximum height to resize to. - * @param bool $crop Optional. Whether to crop image or resize. - * @param string $suffix Optional. File suffix. - * @param string $dest_path Optional. New image file path. - * @param int $jpeg_quality Optional, default is 90. Image quality percentage. - * @return mixed WP_Error on failure. String with new destination path. - */ -function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) { - - $image = wp_load_image( $file ); - if ( !is_resource( $image ) ) - return new WP_Error( 'error_loading_image', $image, $file ); - - $size = @getimagesize( $file ); - if ( !$size ) - return new WP_Error('invalid_image', __('Could not read image size'), $file); - list($orig_w, $orig_h, $orig_type) = $size; - - $dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop); - if ( !$dims ) - return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') ); - list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims; - - $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h ); - - imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); - - // convert from full colors to index colors, like original PNG. - if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) ) - imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) ); - - // we don't need the original in memory anymore - imagedestroy( $image ); - - // $suffix will be appended to the destination filename, just before the extension - if ( !$suffix ) - $suffix = "{$dst_w}x{$dst_h}"; - - $info = pathinfo($file); - $dir = $info['dirname']; - $ext = $info['extension']; - $name = wp_basename($file, ".$ext"); - - if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) ) - $dir = $_dest_path; - $destfilename = "{$dir}/{$name}-{$suffix}.{$ext}"; - - if ( IMAGETYPE_GIF == $orig_type ) { - if ( !imagegif( $newimage, $destfilename ) ) - return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); - } elseif ( IMAGETYPE_PNG == $orig_type ) { - if ( !imagepng( $newimage, $destfilename ) ) - return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); - } else { - // all other formats are converted to jpg - if ( 'jpg' != $ext && 'jpeg' != $ext ) - $destfilename = "{$dir}/{$name}-{$suffix}.jpg"; - if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) ) - return new WP_Error('resize_path_invalid', __( 'Resize path invalid' )); - } - - imagedestroy( $newimage ); - - // Set correct file permissions - $stat = stat( dirname( $destfilename )); - $perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits - @ chmod( $destfilename, $perms ); - - return $destfilename; -} - /** * Resize an image to make a thumbnail or intermediate size. * @@ -493,16 +386,18 @@ function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $de * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize. * @return bool|array False, if no image was created. Metadata array on success. */ -function image_make_intermediate_size($file, $width, $height, $crop=false) { +function image_make_intermediate_size( $file, $width, $height, $crop = false ) { if ( $width || $height ) { - $resized_file = image_resize($file, $width, $height, $crop); - if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) { - $resized_file = apply_filters('image_make_intermediate_size', $resized_file); - return array( - 'file' => wp_basename( $resized_file ), - 'width' => $info[0], - 'height' => $info[1], - ); + $editor = wp_get_image_editor( $file ); + + if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) + return false; + + $resized_file = $editor->save(); + + if ( ! is_wp_error( $resized_file ) && $resized_file ) { + unset( $resized_file['path'] ); + return $resized_file; } } return false; @@ -655,12 +550,11 @@ function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa $hwstring = image_hwstring($width, $height); if ( is_array($size) ) $size = join('x', $size); - $attachment =& get_post($attachment_id); + $attachment = get_post($attachment_id); $default_attr = array( 'src' => $src, 'class' => "attachment-$size", 'alt' => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first - 'title' => trim(strip_tags( $attachment->post_title )), ); if ( empty($default_attr['alt']) ) $default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption @@ -775,11 +669,18 @@ add_shortcode('gallery', 'gallery_shortcode'); * @return string HTML content to display gallery. */ function gallery_shortcode($attr) { - global $post; + $post = get_post(); static $instance = 0; $instance++; + if ( ! empty( $attr['ids'] ) ) { + // 'ids' is explicitly ordered, unless you specify otherwise. + if ( empty( $attr['orderby'] ) ) + $attr['orderby'] = 'post__in'; + $attr['include'] = $attr['ids']; + } + // Allow plugins/themes to override the default gallery template. $output = apply_filters('post_gallery', '', $attr); if ( $output != '' ) @@ -810,7 +711,6 @@ function gallery_shortcode($attr) { $orderby = 'none'; if ( !empty($include) ) { - $include = preg_replace( '/[^0-9,]+/', '', $include ); $_attachments = get_posts( array('include' => $include, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); $attachments = array(); @@ -818,7 +718,6 @@ function gallery_shortcode($attr) { $attachments[$val->ID] = $_attachments[$key]; } } elseif ( !empty($exclude) ) { - $exclude = preg_replace( '/[^0-9,]+/', '', $exclude ); $attachments = get_children( array('post_parent' => $id, 'exclude' => $exclude, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); } else { $attachments = get_children( array('post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $order, 'orderby' => $orderby) ); @@ -928,9 +827,8 @@ function next_image_link($size = 'thumbnail', $text = false) { * @param bool $prev Optional. Default is true to display previous link, false for next. */ function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) { - global $post; - $post = get_post($post); - $attachments = array_values(get_children( array('post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID') )); + $post = get_post(); + $attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID' ) ) ); foreach ( $attachments as $k => $attachment ) if ( $attachment->ID == $post->ID ) @@ -938,8 +836,14 @@ function adjacent_image_link($prev = true, $size = 'thumbnail', $text = false) { $k = $prev ? $k - 1 : $k + 1; - if ( isset($attachments[$k]) ) - echo wp_get_attachment_link($attachments[$k]->ID, $size, true, false, $text); + $output = $attachment_id = null; + if ( isset( $attachments[ $k ] ) ) { + $attachment_id = $attachments[ $k ]->ID; + $output = wp_get_attachment_link( $attachment_id, $size, true, false, $text ); + } + + $adjacent = $prev ? 'previous' : 'next'; + echo apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text ); } /** @@ -982,38 +886,37 @@ function get_attachment_taxonomies($attachment) { } /** - * Check if the installed version of GD supports particular image type + * Return all of the taxonomy names that are registered for attachments. * - * @since 2.9.0 + * Handles mime-type-specific taxonomies such as attachment:image and attachment:video. + * + * @since 3.5.0 + * @see get_attachment_taxonomies() + * @uses get_taxonomies() * - * @param string $mime_type - * @return bool + * @param string $output The type of output to return, either taxonomy 'names' or 'objects'. 'names' is the default. + * @return array The names of all taxonomy of $object_type. */ -function gd_edit_image_support($mime_type) { - if ( function_exists('imagetypes') ) { - switch( $mime_type ) { - case 'image/jpeg': - return (imagetypes() & IMG_JPG) != 0; - case 'image/png': - return (imagetypes() & IMG_PNG) != 0; - case 'image/gif': - return (imagetypes() & IMG_GIF) != 0; - } - } else { - switch( $mime_type ) { - case 'image/jpeg': - return function_exists('imagecreatefromjpeg'); - case 'image/png': - return function_exists('imagecreatefrompng'); - case 'image/gif': - return function_exists('imagecreatefromgif'); +function get_taxonomies_for_attachments( $output = 'names' ) { + $taxonomies = array(); + foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { + foreach ( $taxonomy->object_type as $object_type ) { + if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) { + if ( 'names' == $output ) + $taxonomies[] = $taxonomy->name; + else + $taxonomies[ $taxonomy->name ] = $taxonomy; + break; + } } } - return false; + + return $taxonomies; } /** * Create new GD image resource with transparency support + * @TODO: Deprecate if possible. * * @since 2.9.0 * @@ -1030,285 +933,6 @@ function wp_imagecreatetruecolor($width, $height) { return $img; } -/** - * API for easily embedding rich media such as videos and images into content. - * - * @package WordPress - * @subpackage Embed - * @since 2.9.0 - */ -class WP_Embed { - var $handlers = array(); - var $post_ID; - var $usecache = true; - var $linkifunknown = true; - - /** - * Constructor - */ - function __construct() { - // Hack to get the [embed] shortcode to run before wpautop() - add_filter( 'the_content', array(&$this, 'run_shortcode'), 8 ); - - // Shortcode placeholder for strip_shortcodes() - add_shortcode( 'embed', '__return_false' ); - - // Attempts to embed all URLs in a post - if ( get_option('embed_autourls') ) - add_filter( 'the_content', array(&$this, 'autoembed'), 8 ); - - // After a post is saved, invalidate the oEmbed cache - add_action( 'save_post', array(&$this, 'delete_oembed_caches') ); - - // After a post is saved, cache oEmbed items via AJAX - add_action( 'edit_form_advanced', array(&$this, 'maybe_run_ajax_cache') ); - } - - /** - * Process the [embed] shortcode. - * - * Since the [embed] shortcode needs to be run earlier than other shortcodes, - * this function removes all existing shortcodes, registers the [embed] shortcode, - * calls {@link do_shortcode()}, and then re-registers the old shortcodes. - * - * @uses $shortcode_tags - * @uses remove_all_shortcodes() - * @uses add_shortcode() - * @uses do_shortcode() - * - * @param string $content Content to parse - * @return string Content with shortcode parsed - */ - function run_shortcode( $content ) { - global $shortcode_tags; - - // Back up current registered shortcodes and clear them all out - $orig_shortcode_tags = $shortcode_tags; - remove_all_shortcodes(); - - add_shortcode( 'embed', array(&$this, 'shortcode') ); - - // Do the shortcode (only the [embed] one is registered) - $content = do_shortcode( $content ); - - // Put the original shortcodes back - $shortcode_tags = $orig_shortcode_tags; - - return $content; - } - - /** - * If a post/page was saved, then output JavaScript to make - * an AJAX request that will call WP_Embed::cache_oembed(). - */ - function maybe_run_ajax_cache() { - global $post_ID; - - if ( empty($post_ID) || empty($_GET['message']) || 1 != $_GET['message'] ) - return; - -?> - -handlers[$priority][$id] = array( - 'regex' => $regex, - 'callback' => $callback, - ); - } - - /** - * Unregister a previously registered embed handler. Do not use this function directly, use {@link wp_embed_unregister_handler()} instead. - * - * @param string $id The handler ID that should be removed. - * @param int $priority Optional. The priority of the handler to be removed (default: 10). - */ - function unregister_handler( $id, $priority = 10 ) { - if ( isset($this->handlers[$priority][$id]) ) - unset($this->handlers[$priority][$id]); - } - - /** - * The {@link do_shortcode()} callback function. - * - * Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of the registered embed handlers. - * If none of the regex matches and it's enabled, then the URL will be given to the {@link WP_oEmbed} class. - * - * @uses wp_oembed_get() - * @uses wp_parse_args() - * @uses wp_embed_defaults() - * @uses WP_Embed::maybe_make_link() - * @uses get_option() - * @uses current_user_can() - * @uses wp_cache_get() - * @uses wp_cache_set() - * @uses get_post_meta() - * @uses update_post_meta() - * - * @param array $attr Shortcode attributes. - * @param string $url The URL attempting to be embedded. - * @return string The embed HTML on success, otherwise the original URL. - */ - function shortcode( $attr, $url = '' ) { - global $post; - - if ( empty($url) ) - return ''; - - $rawattr = $attr; - $attr = wp_parse_args( $attr, wp_embed_defaults() ); - - // kses converts & into & and we need to undo this - // See http://core.trac.wordpress.org/ticket/11311 - $url = str_replace( '&', '&', $url ); - - // Look for known internal handlers - ksort( $this->handlers ); - foreach ( $this->handlers as $priority => $handlers ) { - foreach ( $handlers as $id => $handler ) { - if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) { - if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) ) - return apply_filters( 'embed_handler_html', $return, $url, $attr ); - } - } - } - - $post_ID = ( !empty($post->ID) ) ? $post->ID : null; - if ( !empty($this->post_ID) ) // Potentially set by WP_Embed::cache_oembed() - $post_ID = $this->post_ID; - - // Unknown URL format. Let oEmbed have a go. - if ( $post_ID ) { - - // Check for a cached result (stored in the post meta) - $cachekey = '_oembed_' . md5( $url . serialize( $attr ) ); - if ( $this->usecache ) { - $cache = get_post_meta( $post_ID, $cachekey, true ); - - // Failures are cached - if ( '{{unknown}}' === $cache ) - return $this->maybe_make_link( $url ); - - if ( !empty($cache) ) - return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID ); - } - - // Use oEmbed to get the HTML - $attr['discover'] = ( apply_filters('embed_oembed_discover', false) && author_can( $post_ID, 'unfiltered_html' ) ); - $html = wp_oembed_get( $url, $attr ); - - // Cache the result - $cache = ( $html ) ? $html : '{{unknown}}'; - update_post_meta( $post_ID, $cachekey, $cache ); - - // If there was a result, return it - if ( $html ) - return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID ); - } - - // Still unknown - return $this->maybe_make_link( $url ); - } - - /** - * Delete all oEmbed caches. - * - * @param int $post_ID Post ID to delete the caches for. - */ - function delete_oembed_caches( $post_ID ) { - $post_metas = get_post_custom_keys( $post_ID ); - if ( empty($post_metas) ) - return; - - foreach( $post_metas as $post_meta_key ) { - if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) ) - delete_post_meta( $post_ID, $post_meta_key ); - } - } - - /** - * Triggers a caching of all oEmbed results. - * - * @param int $post_ID Post ID to do the caching for. - */ - function cache_oembed( $post_ID ) { - $post = get_post( $post_ID ); - - if ( empty($post->ID) || !in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', array( 'post', 'page' ) ) ) ) - return; - - // Trigger a caching - if ( !empty($post->post_content) ) { - $this->post_ID = $post->ID; - $this->usecache = false; - - $content = $this->run_shortcode( $post->post_content ); - if ( get_option('embed_autourls') ) - $this->autoembed( $content ); - - $this->usecache = true; - } - } - - /** - * Passes any unlinked URLs that are on their own line to {@link WP_Embed::shortcode()} for potential embedding. - * - * @uses WP_Embed::autoembed_callback() - * - * @param string $content The content to be searched. - * @return string Potentially modified $content. - */ - function autoembed( $content ) { - return preg_replace_callback( '|^\s*(https?://[^\s"]+)\s*$|im', array(&$this, 'autoembed_callback'), $content ); - } - - /** - * Callback function for {@link WP_Embed::autoembed()}. - * - * @uses WP_Embed::shortcode() - * - * @param array $match A regex match array. - * @return string The embed HTML on success, otherwise the original URL. - */ - function autoembed_callback( $match ) { - $oldval = $this->linkifunknown; - $this->linkifunknown = false; - $return = $this->shortcode( array(), $match[1] ); - $this->linkifunknown = $oldval; - - return "\n$return\n"; - } - - /** - * Conditionally makes a hyperlink based on an internal class variable. - * - * @param string $url URL to potentially be linked. - * @return string Linked URL or the original URL. - */ - function maybe_make_link( $url ) { - $output = ( $this->linkifunknown ) ? '' . esc_html($url) . '' : $url; - return apply_filters( 'embed_maybe_make_link', $output, $url ); - } -} -$GLOBALS['wp_embed'] = new WP_Embed(); - /** * Register an embed handler. This function should probably only be used for sites that do not support oEmbed. * @@ -1334,31 +958,27 @@ function wp_embed_unregister_handler( $id, $priority = 10 ) { /** * Create default array of embed parameters. * + * The width defaults to the content width as specified by the theme. If the + * theme does not specify a content width, then 500px is used. + * + * The default height is 1.5 times the width, or 1000px, whichever is smaller. + * + * The 'embed_defaults' filter can be used to adjust either of these values. + * * @since 2.9.0 * * @return array Default embed parameters. */ function wp_embed_defaults() { - if ( !empty($GLOBALS['content_width']) ) - $theme_width = (int) $GLOBALS['content_width']; - - $width = get_option('embed_size_w'); + if ( ! empty( $GLOBALS['content_width'] ) ) + $width = (int) $GLOBALS['content_width']; - if ( empty($width) && !empty($theme_width) ) - $width = $theme_width; - - if ( empty($width) ) + if ( empty( $width ) ) $width = 500; - $height = get_option('embed_size_h'); - - if ( empty($height) ) - $height = 700; + $height = min( ceil( $width * 1.5 ), 1000 ); - return apply_filters( 'embed_defaults', array( - 'width' => $width, - 'height' => $height, - ) ); + return apply_filters( 'embed_defaults', compact( 'width', 'height' ) ); } /** @@ -1419,6 +1039,29 @@ function wp_oembed_add_provider( $format, $provider, $regex = false ) { $oembed->providers[$format] = array( $provider, $regex ); } +/** + * Removes an oEmbed provider. + * + * @since 3.5 + * @see WP_oEmbed + * + * @uses _wp_oembed_get_object() + * + * @param string $format The URL format for the oEmbed provider to remove. + */ +function wp_oembed_remove_provider( $format ) { + require_once( ABSPATH . WPINC . '/class-oembed.php' ); + + $oembed = _wp_oembed_get_object(); + + if ( isset( $oembed->providers[ $format ] ) ) { + unset( $oembed->providers[ $format ] ); + return true; + } + + return false; +} + /** * Determines if default embed handlers should be loaded. * @@ -1457,6 +1100,145 @@ function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) { return apply_filters( 'embed_googlevideo', '', $matches, $attr, $url, $rawattr ); } +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $size + * @return unknown + */ +function wp_convert_hr_to_bytes( $size ) { + $size = strtolower( $size ); + $bytes = (int) $size; + if ( strpos( $size, 'k' ) !== false ) + $bytes = intval( $size ) * 1024; + elseif ( strpos( $size, 'm' ) !== false ) + $bytes = intval($size) * 1024 * 1024; + elseif ( strpos( $size, 'g' ) !== false ) + $bytes = intval( $size ) * 1024 * 1024 * 1024; + return $bytes; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.3.0 + * + * @param unknown_type $bytes + * @return unknown + */ +function wp_convert_bytes_to_hr( $bytes ) { + $units = array( 0 => 'B', 1 => 'kB', 2 => 'MB', 3 => 'GB' ); + $log = log( $bytes, 1024 ); + $power = (int) $log; + $size = pow( 1024, $log - $power ); + return $size . $units[$power]; +} + +/** + * {@internal Missing Short Description}} + * + * @since 2.5.0 + * + * @return unknown + */ +function wp_max_upload_size() { + $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); + $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); + $bytes = apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); + return $bytes; +} + +/** + * Returns a WP_Image_Editor instance and loads file into it. + * + * @since 3.5.0 + * @access public + * + * @param string $path Path to file to load + * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } + * @return WP_Image_Editor|WP_Error + */ +function wp_get_image_editor( $path, $args = array() ) { + $args['path'] = $path; + + if ( ! isset( $args['mime_type'] ) ) { + $file_info = wp_check_filetype( $args['path'] ); + + // If $file_info['type'] is false, then we let the editor attempt to + // figure out the file type, rather than forcing a failure based on extension. + if ( isset( $file_info ) && $file_info['type'] ) + $args['mime_type'] = $file_info['type']; + } + + $implementation = _wp_image_editor_choose( $args ); + + if ( $implementation ) { + $editor = new $implementation( $path ); + $loaded = $editor->load(); + + if ( is_wp_error( $loaded ) ) + return $loaded; + + return $editor; + } + + return new WP_Error( 'image_no_editor', __('No editor could be selected.') ); +} + +/** + * Tests whether there is an editor that supports a given mime type or methods. + * + * @since 3.5.0 + * @access public + * + * @param string|array $args Array of requirements. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } + * @return boolean true if an eligible editor is found; false otherwise + */ +function wp_image_editor_supports( $args = array() ) { + return (bool) _wp_image_editor_choose( $args ); +} + +/** + * Tests which editors are capable of supporting the request. + * + * @since 3.5.0 + * @access private + * + * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } + * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request. + */ +function _wp_image_editor_choose( $args = array() ) { + require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; + require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; + require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; + + $implementations = apply_filters( 'wp_image_editors', + array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); + + foreach ( $implementations as $implementation ) { + if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) + continue; + + if ( isset( $args['mime_type'] ) && + ! call_user_func( + array( $implementation, 'supports_mime_type' ), + $args['mime_type'] ) ) { + continue; + } + + if ( isset( $args['methods'] ) && + array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { + continue; + } + + return $implementation; + } + + return false; +} + /** * Prints default plupload arguments. * @@ -1465,6 +1247,10 @@ function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) { function wp_plupload_default_settings() { global $wp_scripts; + $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); + if ( $data && false !== strpos( $data, '_wpPluploadSettings' ) ) + return; + $max_upload_size = wp_max_upload_size(); $defaults = array( @@ -1472,7 +1258,7 @@ function wp_plupload_default_settings() { 'file_data_name' => 'async-upload', // key passed to $_FILE. 'multiple_queues' => true, 'max_file_size' => $max_upload_size . 'b', - 'url' => admin_url( 'admin-ajax.php', 'relative' ), + 'url' => admin_url( 'async-upload.php', 'relative' ), 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), 'filters' => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ), @@ -1480,6 +1266,11 @@ function wp_plupload_default_settings() { 'urlstream_upload' => true, ); + // Multi-file uploading doesn't currently work in iOS Safari, + // single-file allows the built-in camera to be used as source for images + if ( wp_is_mobile() ) + $defaults['multi_selection'] = false; + $defaults = apply_filters( 'plupload_default_settings', $defaults ); $params = array( @@ -1496,14 +1287,258 @@ function wp_plupload_default_settings() { 'mobile' => wp_is_mobile(), 'supported' => _device_can_upload(), ), + 'limitExceeded' => is_multisite() && ! is_upload_space_available() ); $script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';'; - $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); if ( $data ) $script = "$data\n$script"; $wp_scripts->add_data( 'wp-plupload', 'data', $script ); } add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' ); + +/** + * Prepares an attachment post object for JS, where it is expected + * to be JSON-encoded and fit into an Attachment model. + * + * @since 3.5.0 + * + * @param mixed $attachment Attachment ID or object. + * @return array Array of attachment details. + */ +function wp_prepare_attachment_for_js( $attachment ) { + if ( ! $attachment = get_post( $attachment ) ) + return; + + if ( 'attachment' != $attachment->post_type ) + return; + + $meta = wp_get_attachment_metadata( $attachment->ID ); + if ( false !== strpos( $attachment->post_mime_type, '/' ) ) + list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); + else + list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); + + $attachment_url = wp_get_attachment_url( $attachment->ID ); + + $response = array( + 'id' => $attachment->ID, + 'title' => $attachment->post_title, + 'filename' => basename( $attachment->guid ), + 'url' => $attachment_url, + 'link' => get_attachment_link( $attachment->ID ), + 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), + 'author' => $attachment->post_author, + 'description' => $attachment->post_content, + 'caption' => $attachment->post_excerpt, + 'name' => $attachment->post_name, + 'status' => $attachment->post_status, + 'uploadedTo' => $attachment->post_parent, + 'date' => strtotime( $attachment->post_date_gmt ) * 1000, + 'modified' => strtotime( $attachment->post_modified_gmt ) * 1000, + 'menuOrder' => $attachment->menu_order, + 'mime' => $attachment->post_mime_type, + 'type' => $type, + 'subtype' => $subtype, + 'icon' => wp_mime_type_icon( $attachment->ID ), + 'dateFormatted' => mysql2date( get_option('date_format'), $attachment->post_date ), + 'nonces' => array( + 'update' => false, + 'delete' => false, + ), + 'editLink' => false, + ); + + if ( current_user_can( 'edit_post', $attachment->ID ) ) { + $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); + $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); + } + + if ( current_user_can( 'delete_post', $attachment->ID ) ) + $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID ); + + if ( $meta && 'image' === $type ) { + $sizes = array(); + $possible_sizes = apply_filters( 'image_size_names_choose', array( + 'thumbnail' => __('Thumbnail'), + 'medium' => __('Medium'), + 'large' => __('Large'), + 'full' => __('Full Size'), + ) ); + unset( $possible_sizes['full'] ); + + // Loop through all potential sizes that may be chosen. Try to do this with some efficiency. + // First: run the image_downsize filter. If it returns something, we can use its data. + // If the filter does not return something, then image_downsize() is just an expensive + // way to check the image metadata, which we do second. + foreach ( $possible_sizes as $size => $label ) { + if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) { + if ( ! $downsize[3] ) + continue; + $sizes[ $size ] = array( + 'height' => $downsize[2], + 'width' => $downsize[1], + 'url' => $downsize[0], + 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', + ); + } elseif ( isset( $meta['sizes'][ $size ] ) ) { + if ( ! isset( $base_url ) ) + $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); + + // Nothing from the filter, so consult image metadata if we have it. + $size_meta = $meta['sizes'][ $size ]; + + // We have the actual image size, but might need to further constrain it if content_width is narrower. + // This is not necessary for thumbnails and medium size. + if ( 'thumbnail' == $size || 'medium' == $size ) { + $width = $size_meta['width']; + $height = $size_meta['height']; + } else { + list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' ); + } + + $sizes[ $size ] = array( + 'height' => $height, + 'width' => $width, + 'url' => $base_url . $size_meta['file'], + 'orientation' => $height > $width ? 'portrait' : 'landscape', + ); + } + } + + $sizes['full'] = array( + 'height' => $meta['height'], + 'width' => $meta['width'], + 'url' => $attachment_url, + 'orientation' => $meta['height'] > $meta['width'] ? 'portrait' : 'landscape', + ); + + $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] ); + } + + if ( function_exists('get_compat_media_markup') ) + $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) ); + + return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); +} + +/** + * Enqueues all scripts, styles, settings, and templates necessary to use + * all media JS APIs. + * + * @since 3.5.0 + */ +function wp_enqueue_media( $args = array() ) { + $defaults = array( + 'post' => null, + ); + $args = wp_parse_args( $args, $defaults ); + + // We're going to pass the old thickbox media tabs to `media_upload_tabs` + // to ensure plugins will work. We will then unset those tabs. + $tabs = array( + // handler action suffix => tab label + 'type' => '', + 'type_url' => '', + 'gallery' => '', + 'library' => '', + ); + + $tabs = apply_filters( 'media_upload_tabs', $tabs ); + unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] ); + + $settings = array( + 'tabs' => $tabs, + 'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ), + 'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ), + 'captions' => ! apply_filters( 'disable_captions', '' ), + 'nonce' => array( + 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ), + ), + 'post' => array( + 'id' => 0, + ), + ); + + $post = null; + if ( isset( $args['post'] ) ) { + $post = get_post( $args['post'] ); + $settings['post'] = array( + 'id' => $post->ID, + 'nonce' => wp_create_nonce( 'update-post_' . $post->ID ), + ); + + if ( current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ) ) { + $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true ); + $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1; + } + } + + $hier = $post && is_post_type_hierarchical( $post->post_type ); + + $strings = array( + // Generic + 'url' => __( 'URL' ), + 'addMedia' => __( 'Add Media' ), + 'search' => __( 'Search' ), + 'select' => __( 'Select' ), + 'cancel' => __( 'Cancel' ), + /* translators: This is a would-be plural string used in the media manager. + If there is not a word you can use in your language to avoid issues with the + lack of plural support here, turn it into "selected: %d" then translate it. + */ + 'selected' => __( '%d selected' ), + 'dragInfo' => __( 'Drag and drop to reorder images.' ), + + // Upload + 'uploadFilesTitle' => __( 'Upload Files' ), + 'uploadImagesTitle' => __( 'Upload Images' ), + + // Library + 'mediaLibraryTitle' => __( 'Media Library' ), + 'insertMediaTitle' => __( 'Insert Media' ), + 'createNewGallery' => __( 'Create a new gallery' ), + 'returnToLibrary' => __( '← Return to library' ), + 'allMediaItems' => __( 'All media items' ), + 'noItemsFound' => __( 'No items found.' ), + 'insertIntoPost' => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), + 'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), + 'warnDelete' => __( "You are about to permanently delete this item.\n 'Cancel' to stop, 'OK' to delete." ), + + // From URL + 'insertFromUrlTitle' => __( 'Insert from URL' ), + + // Featured Images + 'setFeaturedImageTitle' => __( 'Set Featured Image' ), + 'setFeaturedImage' => __( 'Set featured image' ), + + // Gallery + 'createGalleryTitle' => __( 'Create Gallery' ), + 'editGalleryTitle' => __( 'Edit Gallery' ), + 'cancelGalleryTitle' => __( '← Cancel Gallery' ), + 'insertGallery' => __( 'Insert gallery' ), + 'updateGallery' => __( 'Update gallery' ), + 'addToGallery' => __( 'Add to gallery' ), + 'addToGalleryTitle' => __( 'Add to Gallery' ), + 'reverseOrder' => __( 'Reverse order' ), + ); + + $settings = apply_filters( 'media_view_settings', $settings, $post ); + $strings = apply_filters( 'media_view_strings', $strings, $post ); + + $strings['settings'] = $settings; + + wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings ); + + wp_enqueue_script( 'media-editor' ); + wp_enqueue_style( 'media-views' ); + wp_plupload_default_settings(); + + require_once ABSPATH . WPINC . '/media-template.php'; + add_action( 'admin_footer', 'wp_print_media_templates' ); + add_action( 'wp_footer', 'wp_print_media_templates' ); + + do_action( 'wp_enqueue_media' ); +} diff --git a/wp-includes/meta.php b/wp-includes/meta.php index d6984f62..9db1de30 100644 --- a/wp-includes/meta.php +++ b/wp-includes/meta.php @@ -123,9 +123,6 @@ function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_v if ( null !== $check ) return (bool) $check; - if ( ! $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ) ) - return add_metadata($meta_type, $object_id, $meta_key, $passed_value); - // Compare existing value to new value if no prev value given and the key exists only once. if ( empty($prev_value) ) { $old_value = get_metadata($meta_type, $object_id, $meta_key); @@ -135,6 +132,9 @@ function update_metadata($meta_type, $object_id, $meta_key, $meta_value, $prev_v } } + if ( ! $meta_id = $wpdb->get_var( $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s AND $column = %d", $meta_key, $object_id ) ) ) + return add_metadata($meta_type, $object_id, $meta_key, $passed_value); + $_meta_value = $meta_value; $meta_value = maybe_serialize( $meta_value ); @@ -711,7 +711,30 @@ class WP_Meta_Query { $join = array(); $where = array(); - foreach ( $this->queries as $k => $q ) { + $key_only_queries = array(); + $queries = array(); + + // Split out the meta_key only queries (we can only do this for OR) + if ( 'OR' == $this->relation ) { + foreach ( $this->queries as $k => $q ) { + if ( ! isset( $q['value'] ) && ! empty( $q['key'] ) ) + $key_only_queries[$k] = $q; + else + $queries[$k] = $q; + } + } else { + $queries = $this->queries; + } + + // Specify all the meta_key only queries in one go + if ( $key_only_queries ) { + $join[] = "INNER JOIN $meta_table ON $primary_table.$primary_id_column = $meta_table.$meta_id_column"; + + foreach ( $key_only_queries as $key => $q ) + $where["key-only-$key"] = $wpdb->prepare( "$meta_table.meta_key = %s", trim( $q['key'] ) ); + } + + foreach ( $queries as $k => $q ) { $meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : ''; $meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR'; @@ -720,10 +743,35 @@ class WP_Meta_Query { elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) ) $meta_type = 'CHAR'; + $meta_value = isset( $q['value'] ) ? $q['value'] : null; + + if ( isset( $q['compare'] ) ) + $meta_compare = strtoupper( $q['compare'] ); + else + $meta_compare = is_array( $meta_value ) ? 'IN' : '='; + + if ( ! in_array( $meta_compare, array( + '=', '!=', '>', '>=', '<', '<=', + 'LIKE', 'NOT LIKE', + 'IN', 'NOT IN', + 'BETWEEN', 'NOT BETWEEN', + 'NOT EXISTS' + ) ) ) + $meta_compare = '='; + $i = count( $join ); $alias = $i ? 'mt' . $i : $meta_table; - // Set JOIN + if ( 'NOT EXISTS' == $meta_compare ) { + $join[$i] = "LEFT JOIN $meta_table"; + $join[$i] .= $i ? " AS $alias" : ''; + $join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column AND $alias.meta_key = '$meta_key')"; + + $where[$k] = ' ' . $alias . '.' . $meta_id_column . ' IS NULL'; + + continue; + } + $join[$i] = "INNER JOIN $meta_table"; $join[$i] .= $i ? " AS $alias" : ''; $join[$i] .= " ON ($primary_table.$primary_id_column = $alias.$meta_id_column)"; @@ -732,21 +780,12 @@ class WP_Meta_Query { if ( !empty( $meta_key ) ) $where[$k] = $wpdb->prepare( "$alias.meta_key = %s", $meta_key ); - if ( !isset( $q['value'] ) ) { + if ( is_null( $meta_value ) ) { if ( empty( $where[$k] ) ) unset( $join[$i] ); continue; } - $meta_value = $q['value']; - - $meta_compare = is_array( $meta_value ) ? 'IN' : '='; - if ( isset( $q['compare'] ) ) - $meta_compare = strtoupper( $q['compare'] ); - - if ( ! in_array( $meta_compare, array( '=', '!=', '>', '>=', '<', '<=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) - $meta_compare = '='; - if ( in_array( $meta_compare, array( 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN' ) ) ) { if ( ! is_array( $meta_value ) ) $meta_value = preg_split( '/[,\s]+/', $meta_value ); diff --git a/wp-includes/ms-blogs.php b/wp-includes/ms-blogs.php index 8f66aadd..a1f70a40 100644 --- a/wp-includes/ms-blogs.php +++ b/wp-includes/ms-blogs.php @@ -84,28 +84,32 @@ function get_blogaddress_by_domain( $domain, $path ) { } /** - * Given a blog's (subdomain or directory) name, retrieve it's id. + * Given a blog's (subdomain or directory) slug, retrieve it's id. * * @since MU * - * @param string $name + * @param string $slug * @return int A blog id */ -function get_id_from_blogname( $name ) { +function get_id_from_blogname( $slug ) { global $wpdb, $current_site; - $blog_id = wp_cache_get( 'get_id_from_blogname_' . $name, 'blog-details' ); + + $slug = trim( $slug, '/' ); + + $blog_id = wp_cache_get( 'get_id_from_blogname_' . $slug, 'blog-details' ); if ( $blog_id ) return $blog_id; if ( is_subdomain_install() ) { - $domain = $name . '.' . $current_site->domain; + $domain = $slug . '.' . $current_site->domain; $path = $current_site->path; } else { $domain = $current_site->domain; - $path = $current_site->path . $name . '/'; + $path = $current_site->path . $slug . '/'; } + $blog_id = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domain, $path) ); - wp_cache_set( 'get_id_from_blogname_' . $name, $blog_id, 'blog-details' ); + wp_cache_set( 'get_id_from_blogname_' . $slug, $blog_id, 'blog-details' ); return $blog_id; } @@ -114,11 +118,11 @@ function get_id_from_blogname( $name ) { * * @since MU * - * @param int|string|array $fields A blog ID, a blog name, or an array of fields to query against. + * @param int|string|array $fields A blog ID, a blog slug, or an array of fields to query against. Optional. If not specified the current blog ID is used. * @param bool $get_all Whether to retrieve all details or only the details in the blogs table. Default is true. * @return object Blog details. */ -function get_blog_details( $fields, $get_all = true ) { +function get_blog_details( $fields = null, $get_all = true ) { global $wpdb; if ( is_array($fields ) ) { @@ -162,7 +166,9 @@ function get_blog_details( $fields, $get_all = true ) { return false; } } else { - if ( !is_numeric( $fields ) ) + if ( ! $fields ) + $blog_id = get_current_blog_id(); + elseif ( ! is_numeric( $fields ) ) $blog_id = get_id_from_blogname( $fields ); else $blog_id = $fields; @@ -222,9 +228,11 @@ function get_blog_details( $fields, $get_all = true ) { return $details; } - $details->blogname = get_blog_option( $blog_id, 'blogname' ); - $details->siteurl = get_blog_option( $blog_id, 'siteurl' ); - $details->post_count = get_blog_option( $blog_id, 'post_count' ); + switch_to_blog( $blog_id ); + $details->blogname = get_option( 'blogname' ); + $details->siteurl = get_option( 'siteurl' ); + $details->post_count = get_option( 'post_count' ); + restore_current_blog(); $details = apply_filters( 'blog_details', $details ); @@ -247,11 +255,7 @@ function refresh_blog_details( $blog_id ) { $blog_id = (int) $blog_id; $details = get_blog_details( $blog_id, false ); - wp_cache_delete( $blog_id , 'blog-details' ); - wp_cache_delete( $blog_id . 'short' , 'blog-details' ); - wp_cache_delete( md5( $details->domain . $details->path ) , 'blog-lookup' ); - wp_cache_delete( 'current_blog_' . $details->domain, 'site-options' ); - wp_cache_delete( 'current_blog_' . $details->domain . $details->path, 'site-options' ); + clean_blog_cache( $details ); do_action( 'refresh_blog_details', $blog_id ); } @@ -288,18 +292,48 @@ function update_blog_details( $blog_id, $details = array() ) { foreach ( array_intersect( array_keys( $details ), $fields ) as $field ) $update_details[$field] = $details[$field]; - $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) ); + $result = $wpdb->update( $wpdb->blogs, $update_details, array('blog_id' => $blog_id) ); + + if ( false === $result ) + return false; // If spam status changed, issue actions. if ( $details[ 'spam' ] != $current_details[ 'spam' ] ) { if ( $details[ 'spam' ] == 1 ) - do_action( "make_spam_blog", $blog_id ); + do_action( 'make_spam_blog', $blog_id ); else - do_action( "make_ham_blog", $blog_id ); + do_action( 'make_ham_blog', $blog_id ); } - if ( isset($details[ 'public' ]) ) - update_blog_option( $blog_id, 'blog_public', $details[ 'public' ] ); + // If mature status changed, issue actions. + if ( $details[ 'mature' ] != $current_details[ 'mature' ] ) { + if ( $details[ 'mature' ] == 1 ) + do_action( 'mature_blog', $blog_id ); + else + do_action( 'unmature_blog', $blog_id ); + } + + // If archived status changed, issue actions. + if ( $details[ 'archived' ] != $current_details[ 'archived' ] ) { + if ( $details[ 'archived' ] == 1 ) + do_action( 'archive_blog', $blog_id ); + else + do_action( 'unarchive_blog', $blog_id ); + } + + // If deleted status changed, issue actions. + if ( $details[ 'deleted' ] != $current_details[ 'deleted' ] ) { + if ( $details[ 'deleted' ] == 1 ) + do_action( 'make_delete_blog', $blog_id ); + else + do_action( 'make_undelete_blog', $blog_id ); + } + + if ( isset( $details[ 'public' ] ) ) { + switch_to_blog( $blog_id ); + update_option( 'blog_public', $details[ 'public' ] ); + restore_current_blog(); + } refresh_blog_details($blog_id); @@ -307,114 +341,115 @@ function update_blog_details( $blog_id, $details = array() ) { } /** - * Retrieve option value based on setting name and blog_id. + * Clean the blog cache + * + * @since 3.5.0 + * + * @param stdClass $blog The blog details as returned from get_blog_details() + */ +function clean_blog_cache( $blog ) { + $blog_id = $blog->blog_id; + $domain_path_key = md5( $blog->domain . $blog->path ); + + wp_cache_delete( $blog_id , 'blog-details' ); + wp_cache_delete( $blog_id . 'short' , 'blog-details' ); + wp_cache_delete( $domain_path_key, 'blog-lookup' ); + wp_cache_delete( 'current_blog_' . $blog->domain, 'site-options' ); + wp_cache_delete( 'current_blog_' . $blog->domain . $blog->path, 'site-options' ); + wp_cache_delete( 'get_id_from_blogname_' . trim( $blog->path, '/' ), 'blog-details' ); + wp_cache_delete( $domain_path_key, 'blog-id-cache' ); +} + +/** + * Retrieve option value for a given blog id based on name of option. * * If the option does not exist or does not have a value, then the return value * will be false. This is useful to check whether you need to install an option * and is commonly used during installation of plugin options and to test * whether upgrading is required. * - * There is a filter called 'blog_option_$option' with the $option being - * replaced with the option name. The filter takes two parameters. $value and - * $blog_id. It returns $value. - * The 'option_$option' filter in get_option() is not called. + * If the option was serialized then it will be unserialized when it is returned. * * @since MU - * @uses apply_filters() Calls 'blog_option_$optionname' with the option name value. * - * @param int $blog_id Optional. Blog ID, can be null to refer to the current blog. - * @param string $setting Name of option to retrieve. Should already be SQL-escaped. - * @param string $default (optional) Default value returned if option not found. + * @param int $id A blog ID. Can be null to refer to the current blog. + * @param string $option Name of option to retrieve. Expected to not be SQL-escaped. + * @param mixed $default Optional. Default value to return if the option does not exist. * @return mixed Value set for the option. */ -function get_blog_option( $blog_id, $setting, $default = false ) { - global $wpdb; +function get_blog_option( $id, $option, $default = false ) { + $id = (int) $id; - if ( null === $blog_id ) - $blog_id = $wpdb->blogid; - - $key = $blog_id . '-' . $setting . '-blog_option'; - $value = wp_cache_get( $key, 'site-options' ); - if ( $value == null ) { - if ( $blog_id == $wpdb->blogid ) { - $value = get_option( $setting, $default ); - $notoptions = wp_cache_get( 'notoptions', 'options' ); - if ( isset( $notoptions[$setting] ) ) { - wp_cache_set( $key, 'noop', 'site-options' ); - $value = $default; - } elseif ( $value == false ) { - wp_cache_set( $key, 'falsevalue', 'site-options' ); - } else { - wp_cache_set( $key, $value, 'site-options' ); - } - return apply_filters( 'blog_option_' . $setting, $value, $blog_id ); - } else { - $blog_prefix = $wpdb->get_blog_prefix( $blog_id ); - $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$blog_prefix}options WHERE option_name = %s", $setting ) ); - if ( is_object( $row ) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values - $value = $row->option_value; - if ( $value == false ) - wp_cache_set( $key, 'falsevalue', 'site-options' ); - else - wp_cache_set( $key, $value, 'site-options' ); - } else { // option does not exist, so we must cache its non-existence - wp_cache_set( $key, 'noop', 'site-options' ); - $value = $default; - } - } - } elseif ( $value == 'noop' ) { - $value = $default; - } elseif ( $value == 'falsevalue' ) { - $value = false; - } - // If home is not set use siteurl. - if ( 'home' == $setting && '' == $value ) - return get_blog_option( $blog_id, 'siteurl' ); + if ( empty( $id ) ) + $id = get_current_blog_id(); - if ( 'siteurl' == $setting || 'home' == $setting || 'category_base' == $setting ) - $value = untrailingslashit( $value ); + if ( get_current_blog_id() == $id ) + return get_option( $option, $default ); + + switch_to_blog( $id ); + $value = get_option( $option, $default ); + restore_current_blog(); - return apply_filters( 'blog_option_' . $setting, maybe_unserialize( $value ), $blog_id ); + return apply_filters( 'blog_option_' . $option, $value, $id ); } /** - * Add an option for a particular blog. + * Add a new option for a given blog id. + * + * You do not need to serialize values. If the value needs to be serialized, then + * it will be serialized before it is inserted into the database. Remember, + * resources can not be serialized or added as an option. + * + * You can create options without values and then update the values later. + * Existing options will not be updated and checks are performed to ensure that you + * aren't adding a protected WordPress option. Care should be taken to not name + * options the same as the ones which are protected. * * @since MU * - * @param int $id The blog id - * @param string $key The option key - * @param mixed $value The option value - * @return bool True on success, false on failure. + * @param int $id A blog ID. Can be null to refer to the current blog. + * @param string $option Name of option to add. Expected to not be SQL-escaped. + * @param mixed $value Optional. Option value, can be anything. Expected to not be SQL-escaped. + * @return bool False if option was not added and true if option was added. */ -function add_blog_option( $id, $key, $value ) { +function add_blog_option( $id, $option, $value ) { $id = (int) $id; - switch_to_blog($id); - $return = add_option( $key, $value ); + if ( empty( $id ) ) + $id = get_current_blog_id(); + + if ( get_current_blog_id() == $id ) + return add_option( $option, $value ); + + switch_to_blog( $id ); + $return = add_option( $option, $value ); restore_current_blog(); - if ( $return ) - wp_cache_set( $id . '-' . $key . '-blog_option', $value, 'site-options' ); + return $return; } /** - * Delete an option for a particular blog. + * Removes option by name for a given blog id. Prevents removal of protected WordPress options. * * @since MU * - * @param int $id The blog id - * @param string $key The option key - * @return bool True on success, false on failure. + * @param int $id A blog ID. Can be null to refer to the current blog. + * @param string $option Name of option to remove. Expected to not be SQL-escaped. + * @return bool True, if option is successfully deleted. False on failure. */ -function delete_blog_option( $id, $key ) { +function delete_blog_option( $id, $option ) { $id = (int) $id; - switch_to_blog($id); - $return = delete_option( $key ); + if ( empty( $id ) ) + $id = get_current_blog_id(); + + if ( get_current_blog_id() == $id ) + return delete_option( $option ); + + switch_to_blog( $id ); + $return = delete_option( $option ); restore_current_blog(); - if ( $return ) - wp_cache_set( $id . '-' . $key . '-blog_option', '', 'site-options' ); + return $return; } @@ -424,24 +459,25 @@ function delete_blog_option( $id, $key ) { * @since MU * * @param int $id The blog id - * @param string $key The option key + * @param string $option The option key * @param mixed $value The option value * @return bool True on success, false on failrue. */ -function update_blog_option( $id, $key, $value, $deprecated = null ) { +function update_blog_option( $id, $option, $value, $deprecated = null ) { $id = (int) $id; if ( null !== $deprecated ) _deprecated_argument( __FUNCTION__, '3.1' ); - switch_to_blog($id); - $return = update_option( $key, $value ); + if ( get_current_blog_id() == $id ) + return update_option( $option, $value ); + + switch_to_blog( $id ); + $return = update_option( $option, $value ); restore_current_blog(); refresh_blog_details( $id ); - if ( $return ) - wp_cache_set( $id . '-' . $key . '-blog_option', $value, 'site-options'); return $return; } @@ -459,68 +495,61 @@ function update_blog_option( $id, $key, $value, $deprecated = null ) { * @since MU * * @param int $new_blog The id of the blog you want to switch to. Default: current blog - * @param bool $validate Whether to check if $new_blog exists before proceeding - * @return bool True on success, False if the validation failed + * @param bool $deprecated Deprecated argument + * @return bool True on success, false if the validation failed */ -function switch_to_blog( $new_blog, $validate = false ) { - global $wpdb, $table_prefix, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache; - - if ( empty($new_blog) ) - $new_blog = $blog_id; +function switch_to_blog( $new_blog, $deprecated = null ) { + global $wpdb, $wp_roles; - if ( $validate && ! get_blog_details( $new_blog ) ) - return false; + if ( empty( $new_blog ) ) + $new_blog = $GLOBALS['blog_id']; - if ( empty($switched_stack) ) - $switched_stack = array(); - - $switched_stack[] = $blog_id; + $GLOBALS['_wp_switched_stack'][] = $GLOBALS['blog_id']; /* If we're switching to the same blog id that we're on, * set the right vars, do the associated actions, but skip * the extra unnecessary work */ - if ( $blog_id == $new_blog ) { - do_action( 'switch_blog', $blog_id, $blog_id ); - $switched = true; + if ( $new_blog == $GLOBALS['blog_id'] ) { + do_action( 'switch_blog', $new_blog, $new_blog ); + $GLOBALS['switched'] = true; return true; } - $wpdb->set_blog_id($new_blog); - $table_prefix = $wpdb->prefix; - $prev_blog_id = $blog_id; - $blog_id = $new_blog; - - if ( is_object( $wp_roles ) ) { - $wpdb->suppress_errors(); - if ( method_exists( $wp_roles ,'_init' ) ) - $wp_roles->_init(); - elseif ( method_exists( $wp_roles, '__construct' ) ) - $wp_roles->__construct(); - $wpdb->suppress_errors( false ); + $wpdb->set_blog_id( $new_blog ); + $GLOBALS['table_prefix'] = $wpdb->prefix; + $prev_blog_id = $GLOBALS['blog_id']; + $GLOBALS['blog_id'] = $new_blog; + + if ( function_exists( 'wp_cache_switch_to_blog' ) ) { + wp_cache_switch_to_blog( $new_blog ); + } else { + global $wp_object_cache; + + if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) + $global_groups = $wp_object_cache->global_groups; + else + $global_groups = false; + + wp_cache_init(); + + if ( function_exists( 'wp_cache_add_global_groups' ) ) { + if ( is_array( $global_groups ) ) + wp_cache_add_global_groups( $global_groups ); + else + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', ' blog-id-cache' ) ); + wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); + } } - if ( did_action('init') ) { + if ( did_action( 'init' ) ) { + $wp_roles->reinit(); $current_user = wp_get_current_user(); - if ( is_object( $current_user ) ) - $current_user->for_blog( $blog_id ); + $current_user->for_blog( $new_blog ); } - if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) - $global_groups = $wp_object_cache->global_groups; - else - $global_groups = false; + do_action( 'switch_blog', $new_blog, $prev_blog_id ); + $GLOBALS['switched'] = true; - wp_cache_init(); - if ( function_exists('wp_cache_add_global_groups') ) { - if ( is_array( $global_groups ) ) - wp_cache_add_global_groups( $global_groups ); - else - wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); - wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); - } - - do_action('switch_blog', $blog_id, $prev_blog_id); - $switched = true; return true; } @@ -530,66 +559,74 @@ function switch_to_blog( $new_blog, $validate = false ) { * @see switch_to_blog() * @since MU * - * @return bool True on success, False if we're already on the current blog + * @return bool True on success, false if we're already on the current blog */ function restore_current_blog() { - global $table_prefix, $wpdb, $blog_id, $switched, $switched_stack, $wp_roles, $wp_object_cache; + global $wpdb, $wp_roles; - if ( !$switched ) + if ( empty( $GLOBALS['_wp_switched_stack'] ) ) return false; - if ( !is_array( $switched_stack ) ) - return false; + $blog = array_pop( $GLOBALS['_wp_switched_stack'] ); - $blog = array_pop( $switched_stack ); - if ( $blog_id == $blog ) { + if ( $GLOBALS['blog_id'] == $blog ) { do_action( 'switch_blog', $blog, $blog ); - /* If we still have items in the switched stack, consider ourselves still 'switched' */ - $switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 ); + // If we still have items in the switched stack, consider ourselves still 'switched' + $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] ); return true; } - $wpdb->set_blog_id($blog); - $prev_blog_id = $blog_id; - $blog_id = $blog; - $table_prefix = $wpdb->prefix; - - if ( is_object( $wp_roles ) ) { - $wpdb->suppress_errors(); - if ( method_exists( $wp_roles ,'_init' ) ) - $wp_roles->_init(); - elseif ( method_exists( $wp_roles, '__construct' ) ) - $wp_roles->__construct(); - $wpdb->suppress_errors( false ); + $wpdb->set_blog_id( $blog ); + $prev_blog_id = $GLOBALS['blog_id']; + $GLOBALS['blog_id'] = $blog; + $GLOBALS['table_prefix'] = $wpdb->prefix; + + if ( function_exists( 'wp_cache_switch_to_blog' ) ) { + wp_cache_switch_to_blog( $blog ); + } else { + global $wp_object_cache; + + if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) + $global_groups = $wp_object_cache->global_groups; + else + $global_groups = false; + + wp_cache_init(); + + if ( function_exists( 'wp_cache_add_global_groups' ) ) { + if ( is_array( $global_groups ) ) + wp_cache_add_global_groups( $global_groups ); + else + wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', ' blog-id-cache' ) ); + wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) ); + } } - if ( did_action('init') ) { + if ( did_action( 'init' ) ) { + $wp_roles->reinit(); $current_user = wp_get_current_user(); - if ( is_object( $current_user ) ) - $current_user->for_blog( $blog_id ); + $current_user->for_blog( $blog ); } - if ( is_object( $wp_object_cache ) && isset( $wp_object_cache->global_groups ) ) - $global_groups = $wp_object_cache->global_groups; - else - $global_groups = false; + do_action( 'switch_blog', $blog, $prev_blog_id ); - wp_cache_init(); - if ( function_exists('wp_cache_add_global_groups') ) { - if ( is_array( $global_groups ) ) - wp_cache_add_global_groups( $global_groups ); - else - wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts' ) ); - wp_cache_add_non_persistent_groups(array( 'comment', 'counts', 'plugins' )); - } + // If we still have items in the switched stack, consider ourselves still 'switched' + $GLOBALS['switched'] = ! empty( $GLOBALS['_wp_switched_stack'] ); - do_action('switch_blog', $blog_id, $prev_blog_id); - - /* If we still have items in the switched stack, consider ourselves still 'switched' */ - $switched = ( is_array( $switched_stack ) && count( $switched_stack ) > 0 ); return true; } +/** + * Determines if switch_to_blog() is in effect + * + * @since 3.5.0 + * + * @return bool True if switched, false otherwise. + */ +function ms_is_switched() { + return ! empty( $GLOBALS['_wp_switched_stack'] ); +} + /** * Check if a particular blog is archived. * @@ -632,12 +669,15 @@ function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) { if ( null !== $deprecated ) _deprecated_argument( __FUNCTION__, '3.1' ); - if ( !in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) ) + if ( ! in_array( $pref, array( 'site_id', 'domain', 'path', 'registered', 'last_updated', 'public', 'archived', 'mature', 'spam', 'deleted', 'lang_id') ) ) return $value; - $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) ); + $result = $wpdb->update( $wpdb->blogs, array($pref => $value, 'last_updated' => current_time('mysql', true)), array('blog_id' => $blog_id) ); - refresh_blog_details($blog_id); + if ( false === $result ) + return false; + + refresh_blog_details( $blog_id ); if ( 'spam' == $pref ) ( $value == 1 ) ? do_action( 'make_spam_blog', $blog_id ) : do_action( 'make_ham_blog', $blog_id ); @@ -645,8 +685,8 @@ function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) { ( $value == 1 ) ? do_action( 'mature_blog', $blog_id ) : do_action( 'unmature_blog', $blog_id ); elseif ( 'archived' == $pref ) ( $value == 1 ) ? do_action( 'archive_blog', $blog_id ) : do_action( 'unarchive_blog', $blog_id ); - elseif ( 'archived' == $pref ) - ( $value == 1 ) ? do_action( 'archive_blog', $blog_id ) : do_action( 'unarchive_blog', $blog_id ); + elseif ( 'deleted' == $pref ) + ( $value == 1 ) ? do_action( 'make_delete_blog', $blog_id ) : do_action( 'make_undelete_blog', $blog_id ); return $value; } diff --git a/wp-includes/ms-default-constants.php b/wp-includes/ms-default-constants.php index cc341b14..53dfc9b5 100644 --- a/wp-includes/ms-default-constants.php +++ b/wp-includes/ms-default-constants.php @@ -10,21 +10,31 @@ /** * Defines Multisite upload constants. * + * Exists for backward compatibility with legacy file-serving through + * wp-includes/ms-files.php (wp-content/blogs.php in MU). + * * @since 3.0.0 */ -function ms_upload_constants( ) { +function ms_upload_constants() { global $wpdb; - /** @since 3.0.0 */ + // This filter is attached in ms-default-filters.php but that file is not included during SHORTINIT. + add_filter( 'default_site_option_ms_files_rewriting', '__return_true' ); + + if ( ! get_site_option( 'ms_files_rewriting' ) ) + return; + // Base uploads dir relative to ABSPATH if ( !defined( 'UPLOADBLOGSDIR' ) ) define( 'UPLOADBLOGSDIR', 'wp-content/blogs.dir' ); - /** @since 3.0.0 */ - if ( !defined( 'UPLOADS' ) ) { - // Uploads dir relative to ABSPATH + // Note, the main site in a post-MU network uses wp-content/uploads. + // This is handled in wp_upload_dir() by ignoring UPLOADS for this case. + if ( ! defined( 'UPLOADS' ) ) { define( 'UPLOADS', UPLOADBLOGSDIR . "/{$wpdb->blogid}/files/" ); - if ( 'wp-content/blogs.dir' == UPLOADBLOGSDIR ) + + // Uploads dir relative to ABSPATH + if ( 'wp-content/blogs.dir' == UPLOADBLOGSDIR && ! defined( 'BLOGUPLOADDIR' ) ) define( 'BLOGUPLOADDIR', WP_CONTENT_DIR . "/blogs.dir/{$wpdb->blogid}/files/" ); } } @@ -53,7 +63,7 @@ function ms_cookie_constants( ) { * @since 2.6.0 */ if ( !defined( 'ADMIN_COOKIE_PATH' ) ) { - if( !is_subdomain_install() ) { + if ( ! is_subdomain_install() || trim( parse_url( get_option( 'siteurl' ), PHP_URL_PATH ), '/' ) ) { define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH ); } else { define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' ); @@ -74,9 +84,12 @@ function ms_cookie_constants( ) { /** * Defines Multisite file constants. * + * Exists for backward compatibility with legacy file-serving through + * wp-includes/ms-files.php (wp-content/blogs.php in MU). + * * @since 3.0.0 */ -function ms_file_constants( ) { +function ms_file_constants() { /** * Optional support for X-Sendfile header * @since 3.0.0 diff --git a/wp-includes/ms-default-filters.php b/wp-includes/ms-default-filters.php index 44d8294a..34dc151c 100644 --- a/wp-includes/ms-default-filters.php +++ b/wp-includes/ms-default-filters.php @@ -45,6 +45,7 @@ add_filter( 'wp_upload_bits', 'upload_is_file_too_big' ); add_filter( 'import_upload_size_limit', 'fix_import_form_size' ); add_filter( 'upload_mimes', 'check_upload_mimes' ); add_filter( 'upload_size_limit', 'upload_size_limit_filter' ); +add_action( 'upload_ui_over_quota', 'multisite_over_quota_message' ); // Mail add_action( 'phpmailer_init', 'fix_phpmailer_messageid' ); @@ -60,3 +61,6 @@ add_filter( 'force_filtered_html_on_import', '__return_true' ); // WP_HOME and WP_SITEURL should not have any effect in MS remove_filter( 'option_siteurl', '_config_wp_siteurl' ); remove_filter( 'option_home', '_config_wp_home' ); + +// If the network upgrade hasn't run yet, assume ms-files.php rewriting is used. +add_filter( 'default_site_option_ms_files_rewriting', '__return_true' ); \ No newline at end of file diff --git a/wp-includes/ms-functions.php b/wp-includes/ms-functions.php index f4fe306b..0f6794b5 100644 --- a/wp-includes/ms-functions.php +++ b/wp-includes/ms-functions.php @@ -152,17 +152,12 @@ function get_blog_count( $id = 0 ) { * * @param int $blog_id ID of the blog. * @param int $post_id ID of the post you're looking for. - * @return object The post. + * @return WP_Post|null WP_Post on success or null on failure */ function get_blog_post( $blog_id, $post_id ) { - global $wpdb; - - $key = $blog_id . '-' . $post_id; - $post = wp_cache_get( $key, 'global-posts' ); - if ( $post == false ) { - $post = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . $wpdb->get_blog_prefix( $blog_id ) . 'posts WHERE ID = %d', $post_id ) ); - wp_cache_add( $key, $post, 'global-posts' ); - } + switch_to_blog( $blog_id ); + $post = get_post( $post_id ); + restore_current_blog(); return $post; } @@ -183,11 +178,11 @@ function get_blog_post( $blog_id, $post_id ) { function add_user_to_blog( $blog_id, $user_id, $role ) { switch_to_blog($blog_id); - $user = new WP_User($user_id); + $user = get_userdata( $user_id ); - if ( ! $user->exists() ) { + if ( ! $user ) { restore_current_blog(); - return new WP_Error('user_does_not_exist', __('That user does not exist.')); + return new WP_Error( 'user_does_not_exist', __( 'The requested user does not exist.' ) ); } if ( !get_user_meta($user_id, 'primary_blog', true) ) { @@ -246,8 +241,8 @@ function remove_user_from_blog($user_id, $blog_id = '', $reassign = '') { } // wp_revoke_user($user_id); - $user = new WP_User($user_id); - if ( ! $user->exists() ) { + $user = get_userdata( $user_id ); + if ( ! $user ) { restore_current_blog(); return new WP_Error('user_does_not_exist', __('That user does not exist.')); } @@ -313,19 +308,15 @@ function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) { * * @since MU 1.0 * - * @param int $_blog_id ID of the source blog. + * @param int $blog_id ID of the source blog. * @param int $post_id ID of the desired post. * @return string The post's permalink */ -function get_blog_permalink( $_blog_id, $post_id ) { - $key = "{$_blog_id}-{$post_id}-blog_permalink"; - $link = wp_cache_get( $key, 'site-options' ); - if ( $link == false ) { - switch_to_blog( $_blog_id ); - $link = get_permalink( $post_id ); - restore_current_blog(); - wp_cache_add( $key, $link, 'site-options', 360 ); - } +function get_blog_permalink( $blog_id, $post_id ) { + switch_to_blog( $blog_id ); + $link = get_permalink( $post_id ); + restore_current_blog(); + return $link; } @@ -341,27 +332,27 @@ function get_blog_permalink( $_blog_id, $post_id ) { * * @param string $domain * @param string $path Optional. Not required for subdomain installations. - * @return int + * @return int 0 if no blog found, otherwise the ID of the matching blog */ function get_blog_id_from_url( $domain, $path = '/' ) { global $wpdb; - $domain = strtolower( $wpdb->escape( $domain ) ); - $path = strtolower( $wpdb->escape( $path ) ); + $domain = strtolower( $domain ); + $path = strtolower( $path ); $id = wp_cache_get( md5( $domain . $path ), 'blog-id-cache' ); - if ( $id == -1 ) { // blog does not exist + if ( $id == -1 ) // blog does not exist return 0; - } elseif ( $id ) { - return (int)$id; - } + elseif ( $id ) + return (int) $id; - $id = $wpdb->get_var( "SELECT blog_id FROM $wpdb->blogs WHERE domain = '$domain' and path = '$path' /* get_blog_id_from_url */" ); + $id = $wpdb->get_var( $wpdb->prepare( "SELECT blog_id FROM $wpdb->blogs WHERE domain = %s and path = %s /* get_blog_id_from_url */", $domain, $path ) ); - if ( !$id ) { + if ( ! $id ) { wp_cache_set( md5( $domain . $path ), -1, 'blog-id-cache' ); - return false; + return 0; } + wp_cache_set( md5( $domain . $path ), $id, 'blog-id-cache' ); return $id; @@ -384,25 +375,32 @@ function get_blog_id_from_url( $domain, $path = '/' ) { */ function is_email_address_unsafe( $user_email ) { $banned_names = get_site_option( 'banned_email_domains' ); - if ($banned_names && !is_array( $banned_names )) - $banned_names = explode( "\n", $banned_names); + if ( $banned_names && ! is_array( $banned_names ) ) + $banned_names = explode( "\n", $banned_names ); + + $is_email_address_unsafe = false; - if ( is_array( $banned_names ) && empty( $banned_names ) == false ) { - $email_domain = strtolower( substr( $user_email, 1 + strpos( $user_email, '@' ) ) ); - foreach ( (array) $banned_names as $banned_domain ) { - if ( $banned_domain == '' ) + if ( $banned_names && is_array( $banned_names ) ) { + list( $email_local_part, $email_domain ) = explode( '@', $user_email ); + + foreach ( $banned_names as $banned_domain ) { + if ( ! $banned_domain ) continue; - if ( - strstr( $email_domain, $banned_domain ) || - ( - strstr( $banned_domain, '/' ) && - preg_match( $banned_domain, $email_domain ) - ) - ) - return true; + + if ( $email_domain == $banned_domain ) { + $is_email_address_unsafe = true; + break; + } + + $dotted_domain = ".$banned_domain"; + if ( $dotted_domain === substr( $user_email, -strlen( $dotted_domain ) ) ) { + $is_email_address_unsafe = true; + break; + } } } - return false; + + return apply_filters( 'is_email_address_unsafe', $is_email_address_unsafe, $user_email ); } /** @@ -471,7 +469,7 @@ function wpmu_validate_user_signup($user_name, $user_email) { $errors->add('user_name', __('Sorry, usernames must have letters too!')); if ( !is_email( $user_email ) ) - $errors->add('user_email', __( 'Please enter a correct email address.' ) ); + $errors->add('user_email', __( 'Please enter a valid email address.' ) ); $limited_email_domains = get_site_option( 'limited_email_domains' ); if ( is_array( $limited_email_domains ) && empty( $limited_email_domains ) == false ) { @@ -482,11 +480,11 @@ function wpmu_validate_user_signup($user_name, $user_email) { // Check if the username has been used already. if ( username_exists($user_name) ) - $errors->add('user_name', __('Sorry, that username already exists!')); + $errors->add( 'user_name', __( 'Sorry, that username already exists!' ) ); // Check if the email address has been used already. if ( email_exists($user_email) ) - $errors->add('user_email', __('Sorry, that email address is already used!')); + $errors->add( 'user_email', __( 'Sorry, that email address is already used!' ) ); // Has someone already signed up for this username? $signup = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->signups WHERE user_login = %s", $user_name) ); @@ -495,7 +493,7 @@ function wpmu_validate_user_signup($user_name, $user_email) { $now = current_time( 'timestamp', true ); $diff = $now - $registered_at; // If registered more than two days ago, cancel registration and let this signup go through. - if ( $diff > 172800 ) + if ( $diff > 2 * DAY_IN_SECONDS ) $wpdb->delete( $wpdb->signups, array( 'user_login' => $user_name ) ); else $errors->add('user_name', __('That username is currently reserved but may be available in a couple of days.')); @@ -508,7 +506,7 @@ function wpmu_validate_user_signup($user_name, $user_email) { if ( $signup != null ) { $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); // If registered more than two days ago, cancel registration and let this signup go through. - if ( $diff > 172800 ) + if ( $diff > 2 * DAY_IN_SECONDS ) $wpdb->delete( $wpdb->signups, array( 'user_email' => $user_email ) ); else $errors->add('user_email', __('That email address has already been used. Please check your inbox for an activation email. It will become available in a couple of days if you do nothing.')); @@ -542,7 +540,9 @@ function wpmu_validate_user_signup($user_name, $user_email) { * @return array Contains the new site data and error messages. */ function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { - global $wpdb, $domain, $base, $current_site; + global $wpdb, $domain, $current_site; + + $base = $current_site->path; $blog_title = strip_tags( $blog_title ); $blog_title = substr( $blog_title, 0, 50 ); @@ -562,7 +562,7 @@ function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { $errors->add('blogname', __( 'Please enter a site name.' ) ); if ( preg_match( '/[^a-z0-9]+/', $blogname ) ) - $errors->add('blogname', __( 'Only lowercase letters and numbers allowed.' ) ); + $errors->add('blogname', __( 'Only lowercase letters (a-z) and numbers are allowed.' ) ); if ( in_array( $blogname, $illegal_names ) == true ) $errors->add('blogname', __( 'That name is not allowed.' ) ); @@ -598,8 +598,8 @@ function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { $mydomain = "$domain"; $path = $base.$blogname.'/'; } - if ( domain_exists($mydomain, $path) ) - $errors->add('blogname', __('Sorry, that site already exists!')); + if ( domain_exists($mydomain, $path, $current_site->id) ) + $errors->add( 'blogname', __( 'Sorry, that site already exists!' ) ); if ( username_exists( $blogname ) ) { if ( is_object( $user ) == false || ( is_object($user) && ( $user->user_login != $blogname ) ) ) @@ -611,13 +611,13 @@ function wpmu_validate_blog_signup($blogname, $blog_title, $user = '') { if ( ! empty($signup) ) { $diff = current_time( 'timestamp', true ) - mysql2date('U', $signup->registered); // If registered more than two days ago, cancel registration and let this signup go through. - if ( $diff > 172800 ) + if ( $diff > 2 * DAY_IN_SECONDS ) $wpdb->delete( $wpdb->signups, array( 'domain' => $mydomain , 'path' => $path ) ); else $errors->add('blogname', __('That site is currently reserved but may be available in a couple days.')); } - $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'errors' => $errors); + $result = array('domain' => $mydomain, 'path' => $path, 'blogname' => $blogname, 'blog_title' => $blog_title, 'user' => $user, 'errors' => $errors); return apply_filters('wpmu_validate_blog_signup', $result); } @@ -790,7 +790,7 @@ function wpmu_signup_user_notification($user, $user_email, $key, $meta = '') { $message_headers = "From: \"{$from_name}\" <{$admin_email}>\n" . "Content-Type: text/plain; charset=\"" . get_option('blog_charset') . "\"\n"; $message = sprintf( apply_filters( 'wpmu_signup_user_notification_email', - __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login.\n\n" ), + __( "To activate your user, please click the following link:\n\n%s\n\nAfter you activate, you will receive *another email* with your login." ), $user, $user_email, $key, $meta ), site_url( "wp-activate.php?key=$key" ) @@ -965,7 +965,7 @@ function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id // Check if the domain has been used already. We should return an error message. if ( domain_exists($domain, $path, $site_id) ) - return new WP_Error('blog_taken', __('Site already exists.')); + return new WP_Error( 'blog_taken', __( 'Sorry, that site already exists!' ) ); if ( !defined('WP_INSTALLING') ) define( 'WP_INSTALLING', true ); @@ -1024,11 +1024,11 @@ function newblog_notify_siteadmin( $blog_id, $deprecated = '' ) { $siteurl = site_url(); restore_current_blog(); - $msg = sprintf( __( 'New Site: %1s -URL: %2s -Remote IP: %3s + $msg = sprintf( __( 'New Site: %1$s +URL: %2$s +Remote IP: %3$s -Disable these notifications: %4s' ), $blogname, $siteurl, $_SERVER['REMOTE_ADDR'], $options_site_url); +Disable these notifications: %4$s' ), $blogname, $siteurl, $_SERVER['REMOTE_ADDR'], $options_site_url); $msg = apply_filters( 'newblog_notify_siteadmin', $msg ); wp_mail( $email, sprintf( __( 'New Site Registration: %s' ), $siteurl ), $msg ); @@ -1056,13 +1056,13 @@ function newuser_notify_siteadmin( $user_id ) { if ( is_email($email) == false ) return false; - $user = new WP_User($user_id); + $user = get_userdata( $user_id ); $options_site_url = esc_url(network_admin_url('settings.php')); - $msg = sprintf(__('New User: %1s -Remote IP: %2s + $msg = sprintf(__('New User: %1$s +Remote IP: %2$s -Disable these notifications: %3s'), $user->user_login, $_SERVER['REMOTE_ADDR'], $options_site_url); +Disable these notifications: %3$s'), $user->user_login, $_SERVER['REMOTE_ADDR'], $options_site_url); $msg = apply_filters( 'newuser_notify_siteadmin', $msg, $user ); wp_mail( $email, sprintf(__('New User Registration: %s'), $user->user_login), $msg ); @@ -1084,7 +1084,8 @@ Disable these notifications: %3s'), $user->user_login, $_SERVER['REMOTE_ADDR'], */ function domain_exists($domain, $path, $site_id = 1) { global $wpdb; - return $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) ); + $result = $wpdb->get_var( $wpdb->prepare("SELECT blog_id FROM $wpdb->blogs WHERE domain = %s AND path = %s AND site_id = %d", $domain, $path, $site_id) ); + return apply_filters( 'domain_exists', $result, $domain, $path, $site_id ); } /** @@ -1129,20 +1130,19 @@ function insert_blog($domain, $path, $site_id) { * @param string $blog_title The title of the new site. */ function install_blog($blog_id, $blog_title = '') { - global $wpdb, $table_prefix, $wp_roles; - $wpdb->suppress_errors(); + global $wpdb, $wp_roles, $current_site; // Cast for security $blog_id = (int) $blog_id; require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); - if ( $wpdb->get_results("SELECT ID FROM $wpdb->posts") ) - die(__('

    Already Installed

    You appear to have already installed WordPress. To reinstall please clear your old database tables first.

    ') . ''); + $wpdb->suppress_errors(); + if ( $wpdb->get_results( "DESCRIBE {$wpdb->posts}" ) ) + die( '

    ' . __( 'Already Installed' ) . '

    ' . __( 'You appear to have already installed WordPress. To reinstall please clear your old database tables first.' ) . '

    ' ); + $wpdb->suppress_errors( false ); - $wpdb->suppress_errors(false); - - $url = get_blogaddress_by_id($blog_id); + $url = get_blogaddress_by_id( $blog_id ); // Set everything up make_db_current_silent( 'blog' ); @@ -1150,21 +1150,23 @@ function install_blog($blog_id, $blog_title = '') { populate_roles(); $wp_roles->_init(); - // fix url. - update_option('siteurl', $url); - update_option('home', $url); - update_option('fileupload_url', $url . "files" ); - update_option('upload_path', UPLOADBLOGSDIR . "/$blog_id/files"); - update_option('blogname', stripslashes( $blog_title ) ); - update_option('admin_email', ''); - $wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') ); + $url = untrailingslashit( $url ); - // remove all perms - $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'user_level' ) ); + update_option( 'siteurl', $url ); + update_option( 'home', $url ); - $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'capabilities' ) ); + if ( get_site_option( 'ms_files_rewriting' ) ) + update_option( 'upload_path', UPLOADBLOGSDIR . "/$blog_id/files" ); + else + update_option( 'upload_path', get_blog_option( $current_site->blog_id, 'upload_path' ) ); - $wpdb->suppress_errors( false ); + update_option( 'blogname', stripslashes( $blog_title ) ); + update_option( 'admin_email', '' ); + + // remove all perms + $table_prefix = $wpdb->get_blog_prefix(); + delete_metadata( 'user', 0, $table_prefix . 'user_level', null, true ); // delete all + delete_metadata( 'user', 0, $table_prefix . 'capabilities', null, true ); // delete all } /** @@ -1232,7 +1234,7 @@ We hope you enjoy your new site. Thanks! --The Team @ SITE_NAME' ) ); $url = get_blogaddress_by_id($blog_id); - $user = new WP_User($user_id); + $user = get_userdata( $user_id ); $welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email ); $welcome_email = str_replace( 'BLOG_TITLE', $title, $welcome_email ); @@ -1281,7 +1283,7 @@ function wpmu_welcome_user_notification($user_id, $password, $meta = '') { $welcome_email = get_site_option( 'welcome_user_email' ); - $user = new WP_User($user_id); + $user = get_userdata( $user_id ); $welcome_email = apply_filters( 'update_welcome_user_email', $welcome_email, $user_id, $password, $meta); $welcome_email = str_replace( 'SITE_NAME', $current_site->site_name, $welcome_email ); @@ -1416,7 +1418,7 @@ function get_dirsize( $directory ) { $dirsize[ $directory ][ 'size' ] = recurse_dirsize( $directory ); - set_transient( 'dirsize_cache', $dirsize, 3600 ); + set_transient( 'dirsize_cache', $dirsize, HOUR_IN_SECONDS ); return $dirsize[ $directory ][ 'size' ]; } @@ -1457,34 +1459,6 @@ function recurse_dirsize( $directory ) { return $size; } -/** - * Check whether a blog has used its allotted upload space. - * - * @since MU - * @uses get_dirsize() - * - * @param bool $echo Optional. If $echo is set and the quota is exceeded, a warning message is echoed. Default is true. - * @return int - */ -function upload_is_user_over_quota( $echo = true ) { - if ( get_site_option( 'upload_space_check_disabled' ) ) - return false; - - $spaceAllowed = get_space_allowed(); - if ( empty( $spaceAllowed ) || !is_numeric( $spaceAllowed ) ) - $spaceAllowed = 10; // Default space allowed is 10 MB - - $size = get_dirsize( BLOGUPLOADDIR ) / 1024 / 1024; - - if ( ($spaceAllowed-$size) < 0 ) { - if ( $echo ) - _e( 'Sorry, you have used your space allocation. Please delete some files to upload more files.' ); // No space left - return true; - } else { - return false; - } -} - /** * Check an array of MIME types against a whitelist. * @@ -1535,33 +1509,10 @@ function update_posts_count( $deprecated = '' ) { */ function wpmu_log_new_registrations( $blog_id, $user_id ) { global $wpdb; - $user = new WP_User( (int) $user_id ); + $user = get_userdata( (int) $user_id ); $wpdb->insert( $wpdb->registration_log, array('email' => $user->user_email, 'IP' => preg_replace( '/[^0-9., ]/', '',$_SERVER['REMOTE_ADDR'] ), 'blog_id' => $blog_id, 'date_registered' => current_time('mysql')) ); } -/** - * Get the remaining upload space for this blog. - * - * @since MU - * @uses upload_is_user_over_quota() - * @uses get_space_allowed() - * @uses get_dirsize() - * - * @param int $size - * @return int - */ -function fix_import_form_size( $size ) { - if ( upload_is_user_over_quota( false ) == true ) - return 0; - - $spaceAllowed = 1024 * 1024 * get_space_allowed(); - $dirsize = get_dirsize( BLOGUPLOADDIR ); - if ( $size > $spaceAllowed - $dirsize ) - return $spaceAllowed - $dirsize; // remaining space - else - return $size; // default -} - /** * Maintains a canonical list of terms by syncing terms created for each blog with the global terms table. * @@ -1652,7 +1603,7 @@ function redirect_this_site( $deprecated = '' ) { * @return mixed If the upload is under the size limit, $upload is returned. Otherwise returns an error message. */ function upload_is_file_too_big( $upload ) { - if ( is_array( $upload ) == false || defined( 'WP_IMPORTING' ) ) + if ( is_array( $upload ) == false || defined( 'WP_IMPORTING' ) || get_site_option( 'upload_space_check_disabled' ) ) return $upload; if ( strlen( $upload['bits'] ) > ( 1024 * get_site_option( 'fileupload_maxk', 1500 ) ) ) @@ -1687,7 +1638,7 @@ function signup_nonce_check( $result ) { return $result; if ( wp_create_nonce('signup_form_' . $_POST[ 'signup_form_id' ]) != $_POST['_signup_form'] ) - wp_die( __('Please try again!') ); + wp_die( __( 'Please try again.' ) ); return $result; } @@ -1734,7 +1685,7 @@ function maybe_add_existing_user_to_blog() { if ( empty( $details ) || is_wp_error( add_existing_user_to_blog( $details ) ) ) wp_die( sprintf(__('An error occurred adding you to this site. Back to the homepage.'), home_url() ) ); - wp_die( sprintf(__('You have been added to this site. Please visit the homepage or log in using your username and password.'), home_url(), admin_url() ), __('Success') ); + wp_die( sprintf( __( 'You have been added to this site. Please visit the homepage or log in using your username and password.' ), home_url(), admin_url() ), __( 'WordPress › Success' ) ); } /** @@ -1801,7 +1752,7 @@ function is_user_spammy( $username = 0 ) { } else { $user_id = get_user_id_from_string( $username ); } - $u = new WP_User( $user_id ); + $u = get_userdata( $user_id ); return ( isset( $u->spam ) && $u->spam == 1 ); } @@ -1934,21 +1885,21 @@ function force_ssl_content( $force = '' ) { } /** - * Formats an String URL to use HTTPS if HTTP is found. + * Formats a URL to use https. + * * Useful as a filter. * * @since 2.8.5 - **/ + * + * @param string URL + * @return string URL with https as the scheme + */ function filter_SSL( $url ) { - if ( !is_string( $url ) ) - return get_bloginfo( 'url' ); //return home blog url with proper scheme - - $arrURL = parse_url( $url ); + if ( ! is_string( $url ) ) + return get_bloginfo( 'url' ); // Return home blog url with proper scheme - if ( force_ssl_content() && is_ssl() ) { - if ( 'http' === $arrURL['scheme'] ) - $url = str_replace( $arrURL['scheme'], 'https', $url ); - } + if ( force_ssl_content() && is_ssl() ) + $url = set_url_scheme( $url, 'https' ); return $url; } @@ -1977,6 +1928,89 @@ function wp_update_network_counts() { $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(blog_id) as c FROM $wpdb->blogs WHERE site_id = %d AND spam = '0' AND deleted = '0' and archived = '0'", $wpdb->siteid) ); update_site_option( 'blog_count', $count ); - $count = $wpdb->get_var( $wpdb->prepare("SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'") ); + $count = $wpdb->get_var( "SELECT COUNT(ID) as c FROM $wpdb->users WHERE spam = '0' AND deleted = '0'" ); update_site_option( 'user_count', $count ); } + +/** + * Returns the space used by the current blog. + * + * @since 3.5.0 + * + * @return int Used space in megabytes + */ +function get_space_used() { + // Allow for an alternative way of tracking storage space used + $space_used = apply_filters( 'pre_get_space_used', false ); + if ( false === $space_used ) { + $upload_dir = wp_upload_dir(); + $space_used = get_dirsize( $upload_dir['basedir'] ) / 1024 / 1024; + } + + return $space_used; +} + +/** + * Returns the upload quota for the current blog. + * + * @since MU + * + * @return int Quota in megabytes + */ +function get_space_allowed() { + $space_allowed = get_option( 'blog_upload_space' ); + + if ( ! is_numeric( $space_allowed ) ) + $space_allowed = get_site_option( 'blog_upload_space' ); + + if ( empty( $space_allowed ) || ! is_numeric( $space_allowed ) ) + $space_allowed = 50; + + return $space_allowed; +} + +/** + * Determines if there is any upload space left in the current blog's quota. + * + * @since 3.0.0 + * + * @return int of upload space available in bytes + */ +function get_upload_space_available() { + $space_allowed = get_space_allowed() * 1024 * 1024; + if ( get_site_option( 'upload_space_check_disabled' ) ) + return $space_allowed; + + $space_used = get_space_used() * 1024 * 1024; + + if ( ( $space_allowed - $space_used ) <= 0 ) + return 0; + + return $space_allowed - $space_used; +} + +/** + * Determines if there is any upload space left in the current blog's quota. + * + * @since 3.0.0 + * @return bool True if space is available, false otherwise. + */ +function is_upload_space_available() { + if ( get_site_option( 'upload_space_check_disabled' ) ) + return true; + + return (bool) get_upload_space_available(); +} + +/** + * @since 3.0.0 + * + * @return int of upload size limit in bytes + */ +function upload_size_limit_filter( $size ) { + $fileupload_maxk = 1024 * get_site_option( 'fileupload_maxk', 1500 ); + if ( get_site_option( 'upload_space_check_disabled' ) ) + return min( $size, $fileupload_maxk ); + + return min( $size, $fileupload_maxk, get_upload_space_available() ); +} \ No newline at end of file diff --git a/wp-includes/ms-load.php b/wp-includes/ms-load.php index 58826e78..6a26b9cf 100644 --- a/wp-includes/ms-load.php +++ b/wp-includes/ms-load.php @@ -69,7 +69,9 @@ function wp_get_active_network_plugins() { * @return bool|string Returns true on success, or drop-in file to include. */ function ms_site_check() { - global $wpdb, $current_blog; + global $wpdb; + + $blog = get_blog_details(); // Allow short-circuiting $check = apply_filters('ms_site_check', null); @@ -80,21 +82,21 @@ function ms_site_check() { if ( is_super_admin() ) return true; - if ( '1' == $current_blog->deleted ) { + if ( '1' == $blog->deleted ) { if ( file_exists( WP_CONTENT_DIR . '/blog-deleted.php' ) ) return WP_CONTENT_DIR . '/blog-deleted.php'; else wp_die( __( 'This user has elected to delete their account and the content is no longer available.' ), '', array( 'response' => 410 ) ); } - if ( '2' == $current_blog->deleted ) { + if ( '2' == $blog->deleted ) { if ( file_exists( WP_CONTENT_DIR . '/blog-inactive.php' ) ) return WP_CONTENT_DIR . '/blog-inactive.php'; else wp_die( sprintf( __( 'This site has not been activated yet. If you are having problems activating your site, please contact %1$s.' ), str_replace( '@', ' AT ', get_site_option( 'admin_email', "support@{$current_site->domain}" ) ) ) ); } - if ( $current_blog->archived == '1' || $current_blog->spam == '1' ) { + if ( $blog->archived == '1' || $blog->spam == '1' ) { if ( file_exists( WP_CONTENT_DIR . '/blog-suspended.php' ) ) return WP_CONTENT_DIR . '/blog-suspended.php'; else @@ -232,7 +234,7 @@ function ms_not_installed() { wp_load_translations_early(); - $title = __( 'Error establishing database connection' ); + $title = __( 'Error establishing a database connection' ); $msg = '

    ' . $title . '

    '; if ( ! is_admin() ) die( $msg ); diff --git a/wp-includes/ms-settings.php b/wp-includes/ms-settings.php index 5dd460e3..af2ea0d9 100644 --- a/wp-includes/ms-settings.php +++ b/wp-includes/ms-settings.php @@ -126,6 +126,8 @@ if ( !isset( $current_site ) || !isset( $current_blog ) ) { $wpdb->set_prefix( $table_prefix, false ); // $table_prefix can be set in sunrise.php $wpdb->set_blog_id( $current_blog->blog_id, $current_blog->site_id ); $table_prefix = $wpdb->get_blog_prefix(); +$_wp_switched_stack = array(); +$switched = false; // need to init cache again after blog_id is set wp_start_object_cache(); diff --git a/wp-includes/nav-menu-template.php b/wp-includes/nav-menu-template.php index 4b9293b1..df5612d2 100644 --- a/wp-includes/nav-menu-template.php +++ b/wp-includes/nav-menu-template.php @@ -65,7 +65,6 @@ class Walker_Nav_Menu extends Walker { * @param object $args */ function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) { - global $wp_query; $indent = ( $depth ) ? str_repeat( "\t", $depth ) : ''; $class_names = $value = ''; @@ -156,7 +155,7 @@ function wp_nav_menu( $args = array() ) { if ( ! $menu && !$args->theme_location ) { $menus = wp_get_nav_menus(); foreach ( $menus as $menu_maybe ) { - if ( $menu_items = wp_get_nav_menu_items($menu_maybe->term_id) ) { + if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) { $menu = $menu_maybe; break; } @@ -165,15 +164,21 @@ function wp_nav_menu( $args = array() ) { // If the menu exists, get its items. if ( $menu && ! is_wp_error($menu) && !isset($menu_items) ) - $menu_items = wp_get_nav_menu_items( $menu->term_id ); + $menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) ); - // If no menu was found or if the menu has no items and no location was requested, call the fallback_cb if it exists + /* + * If no menu was found: + * - Fallback (if one was specified), or bail. + * + * If no menu items were found: + * - Fallback, but only if no theme location was specified. + * - Otherwise, bail. + */ if ( ( !$menu || is_wp_error($menu) || ( isset($menu_items) && empty($menu_items) && !$args->theme_location ) ) && $args->fallback_cb && is_callable( $args->fallback_cb ) ) return call_user_func( $args->fallback_cb, (array) $args ); - // If no fallback function was specified and the menu doesn't exists, bail. - if ( !$menu || is_wp_error($menu) ) + if ( !$menu || is_wp_error( $menu ) || empty( $menu_items ) ) return false; $nav_menu = $items = ''; @@ -287,8 +292,6 @@ function _wp_menu_item_classes_by_context( &$menu_items ) { } } } - } elseif ( ! empty( $queried_object->post_type ) && is_post_type_hierarchical( $queried_object->post_type ) ) { - _get_post_ancestors( $queried_object ); } elseif ( ! empty( $queried_object->taxonomy ) && is_taxonomy_hierarchical( $queried_object->taxonomy ) ) { $term_hierarchy = _get_term_hierarchy( $queried_object->taxonomy ); $term_to_ancestor = array(); @@ -334,7 +337,7 @@ function _wp_menu_item_classes_by_context( &$menu_items ) { ( ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && $wp_query->is_home && $home_page_id == $menu_item->object_id ) || ( 'post_type' == $menu_item->type && $wp_query->is_singular ) || - ( 'taxonomy' == $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) ) + ( 'taxonomy' == $menu_item->type && ( $wp_query->is_category || $wp_query->is_tag || $wp_query->is_tax ) && $queried_object->taxonomy == $menu_item->object ) ) ) { $classes[] = 'current-menu-item'; @@ -361,7 +364,7 @@ function _wp_menu_item_classes_by_context( &$menu_items ) { // if the menu item corresponds to the currently-requested URL } elseif ( 'custom' == $menu_item->object ) { $_root_relative_current = untrailingslashit( $_SERVER['REQUEST_URI'] ); - $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_root_relative_current; + $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_root_relative_current ); $raw_item_url = strpos( $menu_item->url, '#' ) ? substr( $menu_item->url, 0, strpos( $menu_item->url, '#' ) ) : $menu_item->url; $item_url = untrailingslashit( $raw_item_url ); $_indexless_current = untrailingslashit( preg_replace( '/index.php$/', '', $current_url ) ); @@ -472,7 +475,7 @@ function walk_nav_menu_tree( $items, $depth, $r ) { $walker = ( empty($r->walker) ) ? new Walker_Nav_Menu : $r->walker; $args = array( $items, $depth, $r ); - return call_user_func_array( array(&$walker, 'walk'), $args ); + return call_user_func_array( array($walker, 'walk'), $args ); } /** diff --git a/wp-includes/nav-menu.php b/wp-includes/nav-menu.php index 361a8de6..7a5da9e2 100644 --- a/wp-includes/nav-menu.php +++ b/wp-includes/nav-menu.php @@ -279,10 +279,6 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item if ( ( ! $menu && 0 !== $menu_id ) || is_wp_error( $menu ) ) return $menu; - $menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); - - $count = count( $menu_items ); - $defaults = array( 'menu-item-db-id' => $menu_item_db_id, 'menu-item-object-id' => 0, @@ -305,8 +301,9 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item if ( 0 == $menu_id ) { $args['menu-item-position'] = 1; } elseif ( 0 == (int) $args['menu-item-position'] ) { + $menu_items = 0 == $menu_id ? array() : (array) wp_get_nav_menu_items( $menu_id, array( 'post_status' => 'publish,draft' ) ); $last_item = array_pop( $menu_items ); - $args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : $count; + $args['menu-item-position'] = ( $last_item && isset( $last_item->menu_order ) ) ? 1 + $last_item->menu_order : count( $menu_items ); } $original_parent = 0 < $menu_item_db_id ? get_post_field( 'post_parent', $menu_item_db_id ) : 0; @@ -350,20 +347,19 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item 'post_type' => 'nav_menu_item', ); - if ( 0 != $menu_id ) + $update = 0 != $menu_item_db_id; + + // Only set the menu term if it isn't set to avoid unnecessary wp_get_object_terms() + if ( $menu_id && ( ! $update || ! is_object_in_term( $menu_item_db_id, 'nav_menu', (int) $menu->term_id ) ) ) $post['tax_input'] = array( 'nav_menu' => array( intval( $menu->term_id ) ) ); // New menu item. Default is draft status - if ( 0 == $menu_item_db_id ) { + if ( ! $update ) { $post['ID'] = 0; $post['post_status'] = 'publish' == $args['menu-item-status'] ? 'publish' : 'draft'; $menu_item_db_id = wp_insert_post( $post ); - - // Update existing menu item. Default is publish status - } else { - $post['ID'] = $menu_item_db_id; - $post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish'; - wp_update_post( $post ); + if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) + return $menu_item_db_id; } if ( 'custom' == $args['menu-item-type'] ) { @@ -371,14 +367,11 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item $args['menu-item-object'] = 'custom'; } - if ( ! $menu_item_db_id || is_wp_error( $menu_item_db_id ) ) - return $menu_item_db_id; - $menu_item_db_id = (int) $menu_item_db_id; update_post_meta( $menu_item_db_id, '_menu_item_type', sanitize_key($args['menu-item-type']) ); - update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', (int) $args['menu-item-parent-id'] ); - update_post_meta( $menu_item_db_id, '_menu_item_object_id', (int) $args['menu-item-object-id'] ); + update_post_meta( $menu_item_db_id, '_menu_item_menu_item_parent', strval( (int) $args['menu-item-parent-id'] ) ); + update_post_meta( $menu_item_db_id, '_menu_item_object_id', strval( (int) $args['menu-item-object-id'] ) ); update_post_meta( $menu_item_db_id, '_menu_item_object', sanitize_key($args['menu-item-object']) ); update_post_meta( $menu_item_db_id, '_menu_item_target', sanitize_key($args['menu-item-target']) ); @@ -389,10 +382,17 @@ function wp_update_nav_menu_item( $menu_id = 0, $menu_item_db_id = 0, $menu_item update_post_meta( $menu_item_db_id, '_menu_item_url', esc_url_raw($args['menu-item-url']) ); if ( 0 == $menu_id ) - update_post_meta( $menu_item_db_id, '_menu_item_orphaned', time() ); - else + update_post_meta( $menu_item_db_id, '_menu_item_orphaned', (string) time() ); + elseif ( get_post_meta( $menu_item_db_id, '_menu_item_orphaned' ) ) delete_post_meta( $menu_item_db_id, '_menu_item_orphaned' ); + // Update existing menu item. Default is publish status + if ( $update ) { + $post['ID'] = $menu_item_db_id; + $post['post_status'] = 'draft' == $args['menu-item-status'] ? 'draft' : 'publish'; + wp_update_post( $post ); + } + do_action('wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args ); return $menu_item_db_id; @@ -483,8 +483,7 @@ function wp_get_nav_menu_items( $menu, $args = array() ) { return $items; $defaults = array( 'order' => 'ASC', 'orderby' => 'menu_order', 'post_type' => 'nav_menu_item', - 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true, - 'update_post_term_cache' => false ); + 'post_status' => 'publish', 'output' => ARRAY_A, 'output_key' => 'menu_order', 'nopaging' => true ); $args = wp_parse_args( $args, $defaults ); if ( count( $items ) > 1 ) $args['include'] = implode( ',', $items ); diff --git a/wp-includes/option.php b/wp-includes/option.php index 33897b60..722d1f30 100644 --- a/wp-includes/option.php +++ b/wp-includes/option.php @@ -32,15 +32,15 @@ function get_option( $option, $default = false ) { global $wpdb; + $option = trim( $option ); + if ( empty( $option ) ) + return false; + // Allow plugins to short-circuit options. $pre = apply_filters( 'pre_option_' . $option, false ); if ( false !== $pre ) return $pre; - $option = trim($option); - if ( empty($option) ) - return false; - if ( defined( 'WP_SETUP_CONFIG' ) ) return false; @@ -174,7 +174,7 @@ function wp_load_core_site_options( $site_id = null ) { if ( empty($site_id) ) $site_id = $wpdb->siteid; - $core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled' ); + $core_options = array('site_name', 'siteurl', 'active_sitewide_plugins', '_site_transient_timeout_theme_roots', '_site_transient_theme_roots', 'site_admins', 'can_compress_scripts', 'global_terms_enabled', 'ms_files_rewriting' ); $core_options_in = "'" . implode("', '", $core_options) . "'"; $options = $wpdb->get_results( $wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->sitemeta WHERE meta_key IN ($core_options_in) AND site_id = %d", $site_id) ); @@ -540,6 +540,11 @@ function wp_user_settings() { if ( ! $user = wp_get_current_user() ) return; + if ( is_super_admin( $user->ID ) && + ! in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user->ID ) ) ) + ) + return; + $settings = get_user_option( 'user-settings', $user->ID ); if ( isset( $_COOKIE['wp-settings-' . $user->ID] ) ) { @@ -560,8 +565,8 @@ function wp_user_settings() { } } - setcookie( 'wp-settings-' . $user->ID, $settings, time() + 31536000, SITECOOKIEPATH ); - setcookie( 'wp-settings-time-' . $user->ID, time(), time() + 31536000, SITECOOKIEPATH ); + setcookie( 'wp-settings-' . $user->ID, $settings, time() + YEAR_IN_SECONDS, SITECOOKIEPATH ); + setcookie( 'wp-settings-time-' . $user->ID, time(), time() + YEAR_IN_SECONDS, SITECOOKIEPATH ); $_COOKIE['wp-settings-' . $user->ID] = $settings; } @@ -697,6 +702,11 @@ function wp_set_all_user_settings($all) { if ( ! $user = wp_get_current_user() ) return false; + if ( is_super_admin( $user->ID ) && + ! in_array( get_current_blog_id(), array_keys( get_blogs_of_user( $user->ID ) ) ) + ) + return; + $_updated_user_settings = $all; $settings = ''; foreach ( $all as $k => $v ) { @@ -724,7 +734,7 @@ function delete_all_user_settings() { return; update_user_option( $user->ID, 'user-settings', '', false ); - setcookie('wp-settings-' . $user->ID, ' ', time() - 31536000, SITECOOKIEPATH); + setcookie('wp-settings-' . $user->ID, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH); } /** diff --git a/wp-includes/pluggable-deprecated.php b/wp-includes/pluggable-deprecated.php index 2a202ace..69e78f5f 100644 --- a/wp-includes/pluggable-deprecated.php +++ b/wp-includes/pluggable-deprecated.php @@ -168,3 +168,25 @@ function wp_login($username, $password, $deprecated = '') { else : _deprecated_function( 'wp_login', '2.5', 'wp_signon()' ); endif; + +/** + * WordPress AtomPub API implementation. + * + * Originally stored in wp-app.php, and later wp-includes/class-wp-atom-server.php. + * It is kept here in case a plugin directly referred to the class. + * + * @since 2.2.0 + * @deprecated 3.5.0 + * @link http://wordpress.org/extend/plugins/atom-publishing-protocol/ + */ +if ( ! class_exists( 'wp_atom_server' ) ) { + class wp_atom_server { + public function __call( $name, $arguments ) { + _deprecated_function( __CLASS__ . '::' . $name, '3.5', 'the Atom Publishing Platform plugin' ); + } + + public static function __callStatic( $name, $arguments ) { + _deprecated_function( __CLASS__ . '::' . $name, '3.5', 'the Atom Publishing Platform plugin' ); + } + } +} \ No newline at end of file diff --git a/wp-includes/pluggable.php b/wp-includes/pluggable.php index ac308a99..37ddb83f 100644 --- a/wp-includes/pluggable.php +++ b/wp-includes/pluggable.php @@ -529,7 +529,7 @@ function wp_validate_auth_cookie($cookie = '', $scheme = '') { // Allow a grace period for POST and AJAX requests if ( defined('DOING_AJAX') || 'POST' == $_SERVER['REQUEST_METHOD'] ) - $expired += 3600; + $expired += HOUR_IN_SECONDS; // Quick check to see if an honest cookie has expired if ( $expired < time() ) { @@ -694,24 +694,24 @@ if ( !function_exists('wp_clear_auth_cookie') ) : function wp_clear_auth_cookie() { do_action('clear_auth_cookie'); - setcookie(AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN); - setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, ADMIN_COOKIE_PATH, COOKIE_DOMAIN); - setcookie(AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN); - setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN); - setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); - setcookie(LOGGED_IN_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); + setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, ADMIN_COOKIE_PATH, COOKIE_DOMAIN ); + setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); + setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, PLUGINS_COOKIE_PATH, COOKIE_DOMAIN ); + setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); + setcookie( LOGGED_IN_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); // Old cookies - setcookie(AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); - setcookie(AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); - setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); - setcookie(SECURE_AUTH_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); + setcookie( AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); + setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); + setcookie( SECURE_AUTH_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); // Even older cookies - setcookie(USER_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); - setcookie(PASS_COOKIE, ' ', time() - 31536000, COOKIEPATH, COOKIE_DOMAIN); - setcookie(USER_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); - setcookie(PASS_COOKIE, ' ', time() - 31536000, SITECOOKIEPATH, COOKIE_DOMAIN); + setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); + setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN ); + setcookie( USER_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); + setcookie( PASS_COOKIE, ' ', time() - YEAR_IN_SECONDS, SITECOOKIEPATH, COOKIE_DOMAIN ); } endif; @@ -748,11 +748,11 @@ function auth_redirect() { // If https is required and request is http, redirect if ( $secure && !is_ssl() && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { - if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { - wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); + if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { + wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); exit(); } else { - wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); exit(); } } @@ -767,11 +767,11 @@ function auth_redirect() { // If the user wants ssl but the session is not ssl, redirect. if ( !$secure && get_user_option('use_ssl', $user_id) && false !== strpos($_SERVER['REQUEST_URI'], 'wp-admin') ) { - if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { - wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); + if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { + wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); exit(); } else { - wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); exit(); } } @@ -782,12 +782,7 @@ function auth_redirect() { // The cookie is no good so force login nocache_headers(); - if ( is_ssl() ) - $proto = 'https://'; - else - $proto = 'http://'; - - $redirect = ( strpos($_SERVER['REQUEST_URI'], '/options.php') && wp_get_referer() ) ? wp_get_referer() : $proto . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $redirect = ( strpos( $_SERVER['REQUEST_URI'], '/options.php' ) && wp_get_referer() ) ? wp_get_referer() : set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); $login_url = wp_login_url($redirect, true); @@ -1195,7 +1190,7 @@ if ( !function_exists('wp_new_user_notification') ) : * @param string $plaintext_pass Optional. The user's plaintext password */ function wp_new_user_notification($user_id, $plaintext_pass = '') { - $user = new WP_User($user_id); + $user = get_userdata( $user_id ); $user_login = stripslashes($user->user_login); $user_email = stripslashes($user->user_email); @@ -1234,7 +1229,7 @@ if ( !function_exists('wp_nonce_tick') ) : * @return int */ function wp_nonce_tick() { - $nonce_life = apply_filters('nonce_life', 86400); + $nonce_life = apply_filters( 'nonce_life', DAY_IN_SECONDS ); return ceil(time() / ( $nonce_life / 2 )); } @@ -1256,6 +1251,8 @@ if ( !function_exists('wp_verify_nonce') ) : function wp_verify_nonce($nonce, $action = -1) { $user = wp_get_current_user(); $uid = (int) $user->ID; + if ( ! $uid ) + $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); $i = wp_nonce_tick(); @@ -1282,6 +1279,8 @@ if ( !function_exists('wp_create_nonce') ) : function wp_create_nonce($action = -1) { $user = wp_get_current_user(); $uid = (int) $user->ID; + if ( ! $uid ) + $uid = apply_filters( 'nonce_user_logged_out', $uid, $action ); $i = wp_nonce_tick(); @@ -1501,13 +1500,13 @@ function wp_generate_password( $length = 12, $special_chars = true, $extra_speci endif; if ( !function_exists('wp_rand') ) : - /** +/** * Generates a random number * * @since 2.6.2 * - * @param int $min Lower limit for the generated number (optional, default is 0) - * @param int $max Upper limit for the generated number (optional, default is 4294967295) + * @param int $min Lower limit for the generated number + * @param int $max Upper limit for the generated number * @return int A random number between min and max */ function wp_rand( $min = 0, $max = 0 ) { @@ -1536,10 +1535,12 @@ function wp_rand( $min = 0, $max = 0 ) { $value = abs(hexdec($value)); + // Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. + $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff + // Reduce the value to be within the min - max range - // 4294967295 = 0xffffffff = max random number if ( $max != 0 ) - $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1))); + $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); return abs(intval($value)); } @@ -1577,7 +1578,7 @@ if ( !function_exists( 'get_avatar' ) ) : * @param int|string|object $id_or_email A user ID, email address, or comment object * @param int $size Size of the avatar image * @param string $default URL to a default image to use if no avatar is available - * @param string $alt Alternate text to use in image tag. Defaults to blank + * @param string $alt Alternative text to use in image tag. Defaults to blank * @return string tag for the user's avatar */ function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) { @@ -1639,7 +1640,7 @@ function get_avatar( $id_or_email, $size = '96', $default = '', $alt = false ) { if ( 'mystery' == $default ) $default = "$host/avatar/ad516503a11cd5ca435acc9bb6523536?s={$size}"; // ad516503a11cd5ca435acc9bb6523536 == md5('unknown@gravatar.com') elseif ( 'blank' == $default ) - $default = includes_url('images/blank.gif'); + $default = $email ? 'blank' : includes_url( 'images/blank.gif' ); elseif ( !empty($email) && 'gravatar_default' == $default ) $default = ''; elseif ( 'gravatar_default' == $default ) diff --git a/wp-includes/plugin.php b/wp-includes/plugin.php index 914d7065..7e387080 100644 --- a/wp-includes/plugin.php +++ b/wp-includes/plugin.php @@ -80,8 +80,11 @@ function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) * @global array $wp_filter Stores all of the filters * * @param string $tag The name of the filter hook. - * @param callback $function_to_check optional. If specified, return the priority of that function on this hook or false if not attached. - * @return int|boolean Optionally returns the priority on that hook for the specified function. + * @param callback $function_to_check optional. + * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered. + * When checking a specific function, the priority of that hook is returned, or false if the function is not attached. + * When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false + * (e.g.) 0, so use the === operator for testing the return value. */ function has_filter($tag, $function_to_check = false) { global $wp_filter; @@ -254,7 +257,7 @@ function apply_filters_ref_array($tag, $args) { * @param int $accepted_args optional. The number of arguments the function accepts (default: 1). * @return boolean Whether the function existed before it was removed. */ -function remove_filter($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { +function remove_filter( $tag, $function_to_remove, $priority = 10 ) { $function_to_remove = _wp_filter_build_unique_id($tag, $function_to_remove, $priority); $r = isset($GLOBALS['wp_filter'][$tag][$priority][$function_to_remove]); @@ -497,8 +500,11 @@ function do_action_ref_array($tag, $args) { * @see has_filter() has_action() is an alias of has_filter(). * * @param string $tag The name of the action hook. - * @param callback $function_to_check optional. If specified, return the priority of that function on this hook or false if not attached. - * @return int|boolean Optionally returns the priority on that hook for the specified function. + * @param callback $function_to_check optional. + * @return mixed If $function_to_check is omitted, returns boolean for whether the hook has anything registered. + * When checking a specific function, the priority of that hook is returned, or false if the function is not attached. + * When using the $function_to_check argument, this function may return a non-boolean value that evaluates to false + * (e.g.) 0, so use the === operator for testing the return value. */ function has_action($tag, $function_to_check = false) { return has_filter($tag, $function_to_check); @@ -518,11 +524,10 @@ function has_action($tag, $function_to_check = false) { * @param string $tag The action hook to which the function to be removed is hooked. * @param callback $function_to_remove The name of the function which should be removed. * @param int $priority optional The priority of the function (default: 10). - * @param int $accepted_args optional. The number of arguments the function accepts (default: 1). * @return boolean Whether the function is removed. */ -function remove_action($tag, $function_to_remove, $priority = 10, $accepted_args = 1) { - return remove_filter($tag, $function_to_remove, $priority, $accepted_args); +function remove_action( $tag, $function_to_remove, $priority = 10 ) { + return remove_filter( $tag, $function_to_remove, $priority ); } /** diff --git a/wp-includes/pomo/entry.php b/wp-includes/pomo/entry.php index 6432dbed..097e92ca 100644 --- a/wp-includes/pomo/entry.php +++ b/wp-includes/pomo/entry.php @@ -2,7 +2,7 @@ /** * Contains Translation_Entry class * - * @version $Id: entry.php 621 2011-06-13 12:21:50Z nbachiyski $ + * @version $Id: entry.php 718 2012-10-31 00:32:02Z nbachiyski $ * @package pomo * @subpackage entry */ @@ -65,14 +65,14 @@ class Translation_Entry { // prepend context and EOT, like in MO files return is_null($this->context)? $this->singular : $this->context.chr(4).$this->singular; } - + function merge_with(&$other) { $this->flags = array_unique( array_merge( $this->flags, $other->flags ) ); $this->references = array_unique( array_merge( $this->references, $other->references ) ); if ( $this->extracted_comments != $other->extracted_comments ) { $this->extracted_comments .= $other->extracted_comments; } - + } } endif; \ No newline at end of file diff --git a/wp-includes/pomo/mo.php b/wp-includes/pomo/mo.php index d76cda5c..68c0792f 100644 --- a/wp-includes/pomo/mo.php +++ b/wp-includes/pomo/mo.php @@ -2,7 +2,7 @@ /** * Class for working with MO files * - * @version $Id: mo.php 602 2011-01-30 12:43:29Z nbachiyski $ + * @version $Id: mo.php 718 2012-10-31 00:32:02Z nbachiyski $ * @package pomo * @subpackage mo */ @@ -34,7 +34,7 @@ class MO extends Gettext_Translations { fclose($fh); return $res; } - + function export() { $tmp_fh = fopen("php://temp", 'r+'); if ( !$tmp_fh ) return false; @@ -42,9 +42,21 @@ class MO extends Gettext_Translations { rewind( $tmp_fh ); return stream_get_contents( $tmp_fh ); } - + + function is_entry_good_for_export( $entry ) { + if ( empty( $entry->translations ) ) { + return false; + } + + if ( !array_filter( $entry->translations ) ) { + return false; + } + + return true; + } + function export_to_file_handle($fh) { - $entries = array_filter($this->entries, create_function('$e', 'return !empty($e->translations);')); + $entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) ); ksort($entries); $magic = 0x950412de; $revision = 0; @@ -57,7 +69,7 @@ class MO extends Gettext_Translations { fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr, $translations_lenghts_addr, $size_of_hash, $hash_addr)); fseek($fh, $originals_lenghts_addr); - + // headers' msgid is an empty string fwrite($fh, pack('VV', 0, $current_addr)); $current_addr++; @@ -69,24 +81,24 @@ class MO extends Gettext_Translations { fwrite($fh, pack('VV', $length, $current_addr)); $current_addr += $length + 1; // account for the NULL byte after } - + $exported_headers = $this->export_headers(); fwrite($fh, pack('VV', strlen($exported_headers), $current_addr)); $current_addr += strlen($exported_headers) + 1; $translations_table = $exported_headers . chr(0); - + foreach($entries as $entry) { $translations_table .= $this->export_translations($entry) . chr(0); $length = strlen($this->export_translations($entry)); fwrite($fh, pack('VV', $length, $current_addr)); $current_addr += $length + 1; } - + fwrite($fh, $originals_table); fwrite($fh, $translations_table); return true; } - + function export_original($entry) { //TODO: warnings for control characters $exported = $entry->singular; @@ -94,12 +106,12 @@ class MO extends Gettext_Translations { if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported; return $exported; } - + function export_translations($entry) { //TODO: warnings for control characters return implode(chr(0), $entry->translations); } - + function export_headers() { $exported = ''; foreach($this->headers as $header => $value) { @@ -195,8 +207,7 @@ class MO extends Gettext_Translations { $translation = $reader->substr( $strings, $t['pos'], $t['length'] ); if ('' === $original) { - $headers = $this->make_headers($translation); - $this->set_headers($headers); + $this->set_headers($this->make_headers($translation)); } else { $entry = &$this->make_entry($original, $translation); $this->entries[$entry->key()] = &$entry; @@ -208,7 +219,7 @@ class MO extends Gettext_Translations { /** * Build a Translation_Entry from original string and translation strings, * found in a MO file - * + * * @static * @param string $original original string to translate from MO file. Might contain * 0x04 as context separator or 0x00 as singular/plural separator diff --git a/wp-includes/pomo/po.php b/wp-includes/pomo/po.php index 8320bc1e..f76be011 100644 --- a/wp-includes/pomo/po.php +++ b/wp-includes/pomo/po.php @@ -2,7 +2,7 @@ /** * Class for working with PO files * - * @version $Id: po.php 589 2010-12-18 01:40:57Z nbachiyski $ + * @version $Id: po.php 718 2012-10-31 00:32:02Z nbachiyski $ * @package pomo * @subpackage po */ @@ -18,7 +18,7 @@ ini_set('auto_detect_line_endings', 1); */ if ( !class_exists( 'PO' ) ): class PO extends Gettext_Translations { - + var $comments_before_headers = ''; /** @@ -80,10 +80,10 @@ class PO extends Gettext_Translations { if (false === $res) return false; return fclose($fh); } - + /** * Text to include as a comment before the start of the PO contents - * + * * Doesn't need to include # in the beginning of lines, these are added automatically */ function set_comment_before_headers( $text ) { @@ -120,10 +120,10 @@ class PO extends Gettext_Translations { $po = str_replace("$newline$quote$quote", '', $po); return $po; } - + /** * Gives back the original string from a PO-formatted string - * + * * @static * @param string $string PO-formatted string * @return string enascaped string @@ -153,7 +153,7 @@ class PO extends Gettext_Translations { } /** - * Inserts $with in the beginning of every new line of $string and + * Inserts $with in the beginning of every new line of $string and * returns the modified string * * @static @@ -229,9 +229,15 @@ class PO extends Gettext_Translations { } } PO::read_line($f, 'clear'); - return $res !== false; + if ( false === $res ) { + return false; + } + if ( ! $this->headers && ! $this->entries ) { + return false; + } + return true; } - + function read_entry($f, $lineno = 0) { $entry = new Translation_Entry(); // where were we in the last step @@ -336,7 +342,7 @@ class PO extends Gettext_Translations { } return array('entry' => $entry, 'lineno' => $lineno); } - + function read_line($f, $action = 'read') { static $last_line = ''; static $use_last_line = false; @@ -349,11 +355,12 @@ class PO extends Gettext_Translations { return true; } $line = $use_last_line? $last_line : fgets($f); + $line = ( "\r\n" == substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line; $last_line = $line; $use_last_line = false; return $line; } - + function add_comment_to_entry(&$entry, $po_comment_line) { $first_two = substr($po_comment_line, 0, 2); $comment = trim(substr($po_comment_line, 2)); @@ -367,11 +374,11 @@ class PO extends Gettext_Translations { $entry->translator_comments = trim($entry->translator_comments . "\n" . $comment); } } - + function trim_quotes($s) { if ( substr($s, 0, 1) == '"') $s = substr($s, 1); if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1); return $s; } } -endif; \ No newline at end of file +endif; diff --git a/wp-includes/pomo/streams.php b/wp-includes/pomo/streams.php index efaffa5a..dbb1de80 100644 --- a/wp-includes/pomo/streams.php +++ b/wp-includes/pomo/streams.php @@ -3,22 +3,22 @@ * Classes, which help reading streams of data from files. * Based on the classes from Danilo Segan * - * @version $Id: streams.php 597 2011-01-16 20:14:36Z nbachiyski $ + * @version $Id: streams.php 718 2012-10-31 00:32:02Z nbachiyski $ * @package pomo * @subpackage streams */ if ( !class_exists( 'POMO_Reader' ) ): class POMO_Reader { - + var $endian = 'little'; var $_post = ''; - + function POMO_Reader() { $this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr'); $this->_pos = 0; } - + /** * Sets the endianness of the file. * @@ -57,8 +57,8 @@ class POMO_Reader { $endian_letter = ('big' == $this->endian)? 'N' : 'V'; return unpack($endian_letter.$count, $bytes); } - - + + function substr($string, $start, $length) { if ($this->is_overloaded) { return mb_substr($string, $start, $length, 'ascii'); @@ -66,7 +66,7 @@ class POMO_Reader { return substr($string, $start, $length); } } - + function strlen($string) { if ($this->is_overloaded) { return mb_strlen($string, 'ascii'); @@ -74,7 +74,7 @@ class POMO_Reader { return strlen($string); } } - + function str_split($string, $chunk_size) { if (!function_exists('str_split')) { $length = $this->strlen($string); @@ -86,8 +86,8 @@ class POMO_Reader { return str_split( $string, $chunk_size ); } } - - + + function pos() { return $this->_pos; } @@ -95,7 +95,7 @@ class POMO_Reader { function is_resource() { return true; } - + function close() { return true; } @@ -108,11 +108,11 @@ class POMO_FileReader extends POMO_Reader { parent::POMO_Reader(); $this->_f = fopen($filename, 'rb'); } - + function read($bytes) { return fread($this->_f, $bytes); } - + function seekto($pos) { if ( -1 == fseek($this->_f, $pos, SEEK_SET)) { return false; @@ -120,19 +120,19 @@ class POMO_FileReader extends POMO_Reader { $this->_pos = $pos; return true; } - + function is_resource() { return is_resource($this->_f); } - + function feof() { return feof($this->_f); } - + function close() { return fclose($this->_f); } - + function read_all() { $all = ''; while ( !$this->feof() ) @@ -148,9 +148,9 @@ if ( !class_exists( 'POMO_StringReader' ) ): * of a physical file. */ class POMO_StringReader extends POMO_Reader { - + var $_str = ''; - + function POMO_StringReader($str = '') { parent::POMO_Reader(); $this->_str = $str; @@ -178,7 +178,7 @@ class POMO_StringReader extends POMO_Reader { function read_all() { return $this->substr($this->_str, $this->_pos, $this->strlen($this->_str)); } - + } endif; diff --git a/wp-includes/pomo/translations.php b/wp-includes/pomo/translations.php index 951583ac..856e38aa 100644 --- a/wp-includes/pomo/translations.php +++ b/wp-includes/pomo/translations.php @@ -2,7 +2,7 @@ /** * Class for a set of entries for translation and their associated headers * - * @version $Id: translations.php 590 2010-12-20 19:58:37Z nbachiyski $ + * @version $Id: translations.php 718 2012-10-31 00:32:02Z nbachiyski $ * @package pomo * @subpackage translations */ @@ -29,7 +29,7 @@ class Translations { $this->entries[$key] = &$entry; return true; } - + function add_entry_or_merge($entry) { if (is_array($entry)) { $entry = new Translation_Entry($entry); @@ -121,7 +121,7 @@ class Translations { $this->entries[$entry->key()] = $entry; } } - + function merge_originals_with(&$other) { foreach( $other->entries as $entry ) { if ( !isset( $this->entries[$entry->key()] ) ) @@ -134,7 +134,7 @@ class Translations { class Gettext_Translations extends Translations { /** - * The gettext implmentation of select_plural_form. + * The gettext implementation of select_plural_form. * * It lives in this class, because there are more than one descendand, which will use it and * they can't share it effectively. @@ -148,7 +148,7 @@ class Gettext_Translations extends Translations { } return call_user_func($this->_gettext_select_plural_form, $count); } - + function nplurals_and_expression_from_header($header) { if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) { $nplurals = (int)$matches[1]; @@ -174,7 +174,7 @@ class Gettext_Translations extends Translations { /** * Adds parantheses to the inner parts of ternary operators in * plural expressions, because PHP evaluates ternary oerators from left to right - * + * * @param string $expression the expression without parentheses * @return string the expression with parentheses added */ @@ -202,7 +202,7 @@ class Gettext_Translations extends Translations { } return rtrim($res, ';'); } - + function make_headers($translation) { $headers = array(); // sometimes \ns are used instead of real new lines @@ -215,7 +215,7 @@ class Gettext_Translations extends Translations { } return $headers; } - + function set_header($header, $value) { parent::set_header($header, $value); if ('Plural-Forms' == $header) { @@ -234,7 +234,7 @@ if ( !class_exists( 'NOOP_Translations' ) ): class NOOP_Translations { var $entries = array(); var $headers = array(); - + function add_entry($entry) { return true; } diff --git a/wp-includes/post-template.php b/wp-includes/post-template.php index b5b8847e..21620b45 100644 --- a/wp-includes/post-template.php +++ b/wp-includes/post-template.php @@ -26,8 +26,7 @@ function the_ID() { * @return int */ function get_the_ID() { - global $post; - return $post->ID; + return get_post()->ID; } /** @@ -97,24 +96,25 @@ function the_title_attribute( $args = '' ) { * * @since 0.71 * - * @param int $id Optional. Post ID. + * @param mixed $post Optional. Post ID or object. * @return string */ -function get_the_title( $id = 0 ) { - $post = &get_post($id); - - $title = isset($post->post_title) ? $post->post_title : ''; - $id = isset($post->ID) ? $post->ID : (int) $id; - - if ( !is_admin() ) { - if ( !empty($post->post_password) ) { - $protected_title_format = apply_filters('protected_title_format', __('Protected: %s')); - $title = sprintf($protected_title_format, $title); - } else if ( isset($post->post_status) && 'private' == $post->post_status ) { - $private_title_format = apply_filters('private_title_format', __('Private: %s')); - $title = sprintf($private_title_format, $title); +function get_the_title( $post = 0 ) { + $post = get_post( $post ); + + $title = isset( $post->post_title ) ? $post->post_title : ''; + $id = isset( $post->ID ) ? $post->ID : 0; + + if ( ! is_admin() ) { + if ( ! empty( $post->post_password ) ) { + $protected_title_format = apply_filters( 'protected_title_format', __( 'Protected: %s' ) ); + $title = sprintf( $protected_title_format, $title ); + } else if ( isset( $post->post_status ) && 'private' == $post->post_status ) { + $private_title_format = apply_filters( 'private_title_format', __( 'Private: %s' ) ); + $title = sprintf( $private_title_format, $title ); } } + return apply_filters( 'the_title', $title, $id ); } @@ -148,7 +148,7 @@ function the_guid( $id = 0 ) { * @return string */ function get_the_guid( $id = 0 ) { - $post = &get_post($id); + $post = get_post($id); return apply_filters('get_the_guid', $post->guid); } @@ -177,8 +177,10 @@ function the_content($more_link_text = null, $stripteaser = false) { * @param bool $stripteaser Optional. Strip teaser content before the more text. Default is false. * @return string */ -function get_the_content($more_link_text = null, $stripteaser = false) { - global $post, $more, $page, $pages, $multipage, $preview; +function get_the_content( $more_link_text = null, $stripteaser = false ) { + global $more, $page, $pages, $multipage, $preview; + + $post = get_post(); if ( null === $more_link_text ) $more_link_text = __( '(more...)' ); @@ -187,7 +189,7 @@ function get_the_content($more_link_text = null, $stripteaser = false) { $hasTeaser = false; // If post password required and it doesn't match the cookie. - if ( post_password_required($post) ) + if ( post_password_required() ) return get_the_password_form(); if ( $page > count($pages) ) // if the requested page doesn't exist @@ -231,7 +233,7 @@ function get_the_content($more_link_text = null, $stripteaser = false) { * @since 3.1.0 * @access private * @param array $match Match array from preg_replace_callback - * @returns string + * @return string */ function _convert_urlencoded_to_entities( $match ) { return '&#' . base_convert( $match[1], 16, 10 ) . ';'; @@ -259,14 +261,13 @@ function get_the_excerpt( $deprecated = '' ) { if ( !empty( $deprecated ) ) _deprecated_argument( __FUNCTION__, '2.3' ); - global $post; - $output = $post->post_excerpt; - if ( post_password_required($post) ) { - $output = __('There is no excerpt because this is a protected post.'); - return $output; + $post = get_post(); + + if ( post_password_required() ) { + return __( 'There is no excerpt because this is a protected post.' ); } - return apply_filters('get_the_excerpt', $output); + return apply_filters( 'get_the_excerpt', $post->post_excerpt ); } /** @@ -278,7 +279,7 @@ function get_the_excerpt( $deprecated = '' ) { * @return bool */ function has_excerpt( $id = 0 ) { - $post = &get_post( $id ); + $post = get_post( $id ); return ( !empty( $post->post_excerpt ) ); } @@ -321,7 +322,8 @@ function get_post_class( $class = '', $post_id = null ) { return $classes; $classes[] = 'post-' . $post->ID; - $classes[] = $post->post_type; + if ( ! is_admin() ) + $classes[] = $post->post_type; $classes[] = 'type-' . $post->post_type; $classes[] = 'status-' . $post->post_status; @@ -427,17 +429,19 @@ function get_body_class( $class = '' ) { $post = $wp_query->get_queried_object(); $classes[] = 'single'; - $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id); - $classes[] = 'postid-' . $post_id; - - // Post Format - if ( post_type_supports( $post->post_type, 'post-formats' ) ) { - $post_format = get_post_format( $post->ID ); - - if ( $post_format && !is_wp_error($post_format) ) - $classes[] = 'single-format-' . sanitize_html_class( $post_format ); - else - $classes[] = 'single-format-standard'; + if ( isset( $post->post_type ) ) { + $classes[] = 'single-' . sanitize_html_class($post->post_type, $post_id); + $classes[] = 'postid-' . $post_id; + + // Post Format + if ( post_type_supports( $post->post_type, 'post-formats' ) ) { + $post_format = get_post_format( $post->ID ); + + if ( $post_format && !is_wp_error($post_format) ) + $classes[] = 'single-format-' . sanitize_html_class( $post_format ); + else + $classes[] = 'single-format-standard'; + } } if ( is_attachment() ) { @@ -453,30 +457,38 @@ function get_body_class( $class = '' ) { } else if ( is_author() ) { $author = $wp_query->get_queried_object(); $classes[] = 'author'; - $classes[] = 'author-' . sanitize_html_class( $author->user_nicename , $author->ID ); - $classes[] = 'author-' . $author->ID; + if ( isset( $author->user_nicename ) ) { + $classes[] = 'author-' . sanitize_html_class( $author->user_nicename, $author->ID ); + $classes[] = 'author-' . $author->ID; + } } elseif ( is_category() ) { $cat = $wp_query->get_queried_object(); $classes[] = 'category'; - $classes[] = 'category-' . sanitize_html_class( $cat->slug, $cat->term_id ); - $classes[] = 'category-' . $cat->term_id; + if ( isset( $cat->term_id ) ) { + $classes[] = 'category-' . sanitize_html_class( $cat->slug, $cat->term_id ); + $classes[] = 'category-' . $cat->term_id; + } } elseif ( is_tag() ) { $tags = $wp_query->get_queried_object(); $classes[] = 'tag'; - $classes[] = 'tag-' . sanitize_html_class( $tags->slug, $tags->term_id ); - $classes[] = 'tag-' . $tags->term_id; + if ( isset( $tags->term_id ) ) { + $classes[] = 'tag-' . sanitize_html_class( $tags->slug, $tags->term_id ); + $classes[] = 'tag-' . $tags->term_id; + } } elseif ( is_tax() ) { $term = $wp_query->get_queried_object(); - $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy ); - $classes[] = 'term-' . sanitize_html_class( $term->slug, $term->term_id ); - $classes[] = 'term-' . $term->term_id; + if ( isset( $term->term_id ) ) { + $classes[] = 'tax-' . sanitize_html_class( $term->taxonomy ); + $classes[] = 'term-' . sanitize_html_class( $term->slug, $term->term_id ); + $classes[] = 'term-' . $term->term_id; + } } } elseif ( is_page() ) { $classes[] = 'page'; $page_id = $wp_query->get_queried_object_id(); - $post = get_page($page_id); + $post = get_post($page_id); $classes[] = 'page-id-' . $page_id; @@ -498,8 +510,10 @@ function get_body_class( $class = '' ) { if ( is_user_logged_in() ) $classes[] = 'logged-in'; - if ( is_admin_bar_showing() ) + if ( is_admin_bar_showing() ) { $classes[] = 'admin-bar'; + $classes[] = 'no-customize-support'; + } if ( get_theme_mod( 'background_color' ) || get_background_image() ) $classes[] = 'custom-background'; @@ -574,20 +588,6 @@ function post_password_required( $post = null ) { return ! $wp_hasher->CheckPassword( $post->post_password, $hash ); } -/** - * Display "sticky" CSS class, if a post is sticky. - * - * @since 2.7.0 - * - * @param int $post_id An optional post ID. - */ -function sticky_class( $post_id = null ) { - if ( !is_sticky($post_id) ) - return; - - echo " sticky"; -} - /** * Page Template Functions for usage in Themes * @@ -692,7 +692,8 @@ function wp_link_pages($args = '') { * @return string Link. */ function _wp_link_page( $i ) { - global $post, $wp_rewrite; + global $wp_rewrite; + $post = get_post(); if ( 1 == $i ) { $url = get_permalink(); @@ -881,6 +882,7 @@ function wp_list_pages($args = '') { * @since 2.7.0 * * @param array|string $args + * @return string html menu */ function wp_page_menu( $args = array() ) { $defaults = array('sort_column' => 'menu_order, post_title', 'menu_class' => 'menu', 'echo' => true, 'link_before' => '', 'link_after' => ''); @@ -945,7 +947,7 @@ function walk_page_tree($pages, $depth, $current_page, $r) { $walker = $r['walker']; $args = array($pages, $depth, $r, $current_page); - return call_user_func_array(array(&$walker, 'walk'), $args); + return call_user_func_array(array($walker, 'walk'), $args); } /** @@ -962,7 +964,7 @@ function walk_page_dropdown_tree() { else $walker = $args[2]['walker']; - return call_user_func_array(array(&$walker, 'walk'), $args); + return call_user_func_array(array($walker, 'walk'), $args); } /** @@ -994,6 +996,7 @@ class Walker_Page extends Walker { * * @param string $output Passed by reference. Used to append additional content. * @param int $depth Depth of page. Used for padding. + * @param array $args */ function start_lvl( &$output, $depth = 0, $args = array() ) { $indent = str_repeat("\t", $depth); @@ -1006,6 +1009,7 @@ class Walker_Page extends Walker { * * @param string $output Passed by reference. Used to append additional content. * @param int $depth Depth of page. Used for padding. + * @param array $args */ function end_lvl( &$output, $depth = 0, $args = array() ) { $indent = str_repeat("\t", $depth); @@ -1031,9 +1035,8 @@ class Walker_Page extends Walker { extract($args, EXTR_SKIP); $css_class = array('page_item', 'page-item-'.$page->ID); if ( !empty($current_page) ) { - $_current_page = get_page( $current_page ); - _get_post_ancestors($_current_page); - if ( isset($_current_page->ancestors) && in_array($page->ID, (array) $_current_page->ancestors) ) + $_current_page = get_post( $current_page ); + if ( in_array( $page->ID, $_current_page->ancestors ) ) $css_class[] = 'current_page_ancestor'; if ( $page->ID == $current_page ) $css_class[] = 'current_page_item'; @@ -1064,6 +1067,7 @@ class Walker_Page extends Walker { * @param string $output Passed by reference. Used to append additional content. * @param object $page Page data object. Not used. * @param int $depth Depth of page. Not Used. + * @param array $args */ function end_el( &$output, $page, $depth = 0, $args = array() ) { $output .= "\n"; @@ -1102,6 +1106,7 @@ class Walker_PageDropdown extends Walker { * @param object $page Page data object. * @param int $depth Depth of page in reference to parent pages. Used for padding. * @param array $args Uses 'selected' argument for selected page to set selected HTML attribute for option element. + * @param int $id */ function start_el(&$output, $page, $depth, $args, $id = 0) { $pad = str_repeat(' ', $depth * 3); @@ -1150,12 +1155,12 @@ function the_attachment_link( $id = 0, $fullsize = false, $deprecated = false, $ * @param string $size Optional, default is 'thumbnail'. Size of image, either array or string. * @param bool $permalink Optional, default is false. Whether to add permalink to image. * @param bool $icon Optional, default is false. Whether to include icon. - * @param string $text Optional, default is false. If string, then will be link text. + * @param string|bool $text Optional, default is false. If string, then will be link text. * @return string HTML content. */ function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = false, $icon = false, $text = false ) { $id = intval( $id ); - $_post = & get_post( $id ); + $_post = get_post( $id ); if ( empty( $_post ) || ( 'attachment' != $_post->post_type ) || ! $url = wp_get_attachment_url( $_post->ID ) ) return __( 'Missing Attachment' ); @@ -1188,7 +1193,7 @@ function wp_get_attachment_link( $id = 0, $size = 'thumbnail', $permalink = fals * @return string */ function prepend_attachment($content) { - global $post; + $post = get_post(); if ( empty($post->post_type) || $post->post_type != 'attachment' ) return $content; @@ -1215,7 +1220,7 @@ function prepend_attachment($content) { * @return string HTML content for password form for password protected post. */ function get_the_password_form() { - global $post; + $post = get_post(); $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID ); $output = '

    ' . __("This post is password protected. To view it please enter your password below:") . '

    @@ -1261,7 +1266,7 @@ function is_page_template( $template = '' ) { * * @since 3.4.0 * - * @param int $id The page ID to check. Defaults to the current post, when used in the loop. + * @param int $post_id The page ID to check. Defaults to the current post, when used in the loop. * @return string|bool Page template filename. Returns an empty string when the default page template * is in use. Returns false if the post is not a page. */ @@ -1432,9 +1437,9 @@ function wp_list_post_revisions( $post_id = 0, $args = null ) { - - - + + + diff --git a/wp-includes/post.php b/wp-includes/post.php index dee484e0..54f17f41 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -52,21 +52,27 @@ function create_initial_post_types() { register_post_type( 'attachment', array( 'labels' => array( - 'name' => __( 'Media' ), - 'edit_item' => __( 'Edit Media' ), + 'name' => _x('Media', 'post type general name'), + 'name_admin_bar' => _x( 'Media', 'add new from admin bar' ), + 'add_new' => _x( 'Add New', 'add new media' ), + 'edit_item' => __( 'Edit Media' ), + 'view_item' => __( 'View Attachment Page' ), ), 'public' => true, - 'show_ui' => false, + 'show_ui' => true, '_builtin' => true, /* internal use only. don't use this when registering your own post type. */ - '_edit_link' => 'media.php?attachment_id=%d', /* internal use only. don't use this when registering your own post type. */ + '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */ 'capability_type' => 'post', + 'capabilities' => array( + 'create_posts' => 'upload_files', + ), 'map_meta_cap' => true, 'hierarchical' => false, 'rewrite' => false, 'query_var' => false, 'show_in_nav_menus' => false, 'delete_with_user' => true, - 'supports' => array( 'comments', 'author' ), + 'supports' => array( 'title', 'author', 'comments' ), ) ); register_post_type( 'revision', array( @@ -204,9 +210,10 @@ function update_attached_file( $attachment_id, $file ) { return false; $file = apply_filters( 'update_attached_file', $file, $attachment_id ); - $file = _wp_relative_upload_path($file); - - return update_post_meta( $attachment_id, '_wp_attached_file', $file ); + if ( $file = _wp_relative_upload_path( $file ) ) + return update_post_meta( $attachment_id, '_wp_attached_file', $file ); + else + return delete_post_meta( $attachment_id, '_wp_attached_file' ); } /** @@ -223,11 +230,10 @@ function update_attached_file( $attachment_id, $file ) { function _wp_relative_upload_path( $path ) { $new_path = $path; - if ( ($uploads = wp_upload_dir()) && false === $uploads['error'] ) { - if ( 0 === strpos($new_path, $uploads['basedir']) ) { - $new_path = str_replace($uploads['basedir'], '', $new_path); - $new_path = ltrim($new_path, '/'); - } + $uploads = wp_upload_dir(); + if ( 0 === strpos( $new_path, $uploads['basedir'] ) ) { + $new_path = str_replace( $uploads['basedir'], '', $new_path ); + $new_path = ltrim( $new_path, '/' ); } return apply_filters( '_wp_relative_upload_path', $new_path, $path ); @@ -372,56 +378,297 @@ function get_extended($post) { * @uses $wpdb * @link http://codex.wordpress.org/Function_Reference/get_post * - * @param int|object $post Post ID or post object. + * @param int|object $post Post ID or post object. Optional, default is the current post from the loop. * @param string $output Optional, default is Object. Either OBJECT, ARRAY_A, or ARRAY_N. * @param string $filter Optional, default is raw. - * @return mixed Post data + * @return WP_Post|null WP_Post on success or null on failure */ -function &get_post(&$post, $output = OBJECT, $filter = 'raw') { - global $wpdb; - $null = null; +function get_post( $post = null, $output = OBJECT, $filter = 'raw' ) { + if ( empty( $post ) && isset( $GLOBALS['post'] ) ) + $post = $GLOBALS['post']; - if ( empty($post) ) { - if ( isset($GLOBALS['post']) ) - $_post = & $GLOBALS['post']; - else - return $null; - } elseif ( is_object($post) && empty($post->filter) ) { - _get_post_ancestors($post); - $_post = sanitize_post($post, 'raw'); - wp_cache_add($post->ID, $_post, 'posts'); - } elseif ( is_object($post) && 'raw' == $post->filter ) { + if ( is_a( $post, 'WP_Post' ) ) { $_post = $post; + } elseif ( is_object( $post ) ) { + if ( empty( $post->filter ) ) { + $_post = sanitize_post( $post, 'raw' ); + $_post = new WP_Post( $_post ); + } elseif ( 'raw' == $post->filter ) { + $_post = new WP_Post( $post ); + } else { + $_post = WP_Post::get_instance( $post->ID ); + } } else { - if ( is_object($post) ) - $post_id = $post->ID; - else - $post_id = $post; + $_post = WP_Post::get_instance( $post ); + } + + if ( ! $_post ) + return null; + + $_post = $_post->filter( $filter ); + + if ( $output == ARRAY_A ) + return $_post->to_array(); + elseif ( $output == ARRAY_N ) + return array_values( $_post->to_array() ); + + return $_post; +} + +/** + * WordPress Post class. + * + * @since 3.5.0 + * + */ +final class WP_Post { + + /** + * + * @var int + */ + public $ID; + + /** + * + * @var int + */ + public $post_author = 0; + + /** + * + * @var string + */ + public $post_date = '0000-00-00 00:00:00'; + + /** + * + * @var string + */ + public $post_date_gmt = '0000-00-00 00:00:00'; + + /** + * + * @var string + */ + public $post_content = ''; + + /** + * + * @var string + */ + public $post_title = ''; + + /** + * + * @var string + */ + public $post_excerpt = ''; + + /** + * + * @var string + */ + public $post_status = 'publish'; + + /** + * + * @var string + */ + public $comment_status = 'open'; + + /** + * + * @var string + */ + public $ping_status = 'open'; + + /** + * + * @var string + */ + public $post_password = ''; + + /** + * + * @var string + */ + public $post_name = ''; + + /** + * + * @var string + */ + public $to_ping = ''; + + /** + * + * @var string + */ + public $pinged = ''; + + /** + * + * @var string + */ + public $post_modified = '0000-00-00 00:00:00'; + + /** + * + * @var string + */ + public $post_modified_gmt = '0000-00-00 00:00:00'; + + /** + * + * @var string + */ + public $post_content_filtered = ''; + + /** + * + * @var int + */ + public $post_parent = 0; + + /** + * + * @var string + */ + public $guid = ''; + + /** + * + * @var int + */ + public $menu_order = 0; + + /** + * + * @var string + */ + public $post_type = 'post'; + + /** + * + * @var string + */ + public $post_mime_type = ''; + + /** + * + * @var int + */ + public $comment_count = 0; + + /** + * + * @var string + */ + public $filter; + + public static function get_instance( $post_id ) { + global $wpdb; $post_id = (int) $post_id; - if ( ! $_post = wp_cache_get($post_id, 'posts') ) { - $_post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id)); + if ( ! $post_id ) + return false; + + $_post = wp_cache_get( $post_id, 'posts' ); + + if ( ! $_post ) { + $_post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $post_id ) ); + if ( ! $_post ) - return $null; - _get_post_ancestors($_post); - $_post = sanitize_post($_post, 'raw'); - wp_cache_add($_post->ID, $_post, 'posts'); + return false; + + $_post = sanitize_post( $_post, 'raw' ); + wp_cache_add( $_post->ID, $_post, 'posts' ); + } elseif ( empty( $_post->filter ) ) { + $_post = sanitize_post( $_post, 'raw' ); } + + return new WP_Post( $_post ); } - if ($filter != 'raw') - $_post = sanitize_post($_post, $filter); + public function __construct( $post ) { + foreach ( get_object_vars( $post ) as $key => $value ) + $this->$key = $value; + } - if ( $output == OBJECT ) { - return $_post; - } elseif ( $output == ARRAY_A ) { - $__post = get_object_vars($_post); - return $__post; - } elseif ( $output == ARRAY_N ) { - $__post = array_values(get_object_vars($_post)); - return $__post; - } else { - return $_post; + public function __isset( $key ) { + if ( 'ancestors' == $key ) + return true; + + if ( 'page_template' == $key ) + return ( 'page' == $this->post_type ); + + if ( 'post_category' == $key ) + return true; + + if ( 'tags_input' == $key ) + return true; + + return metadata_exists( 'post', $this->ID, $key ); + } + + public function __get( $key ) { + if ( 'page_template' == $key && $this->__isset( $key ) ) { + return get_post_meta( $this->ID, '_wp_page_template', true ); + } + + if ( 'post_category' == $key ) { + if ( is_object_in_taxonomy( $this->post_type, 'category' ) ) + $terms = get_the_terms( $this, 'category' ); + + if ( empty( $terms ) ) + return array(); + + return wp_list_pluck( $terms, 'term_id' ); + } + + if ( 'tags_input' == $key ) { + if ( is_object_in_taxonomy( $this->post_type, 'post_tag' ) ) + $terms = get_the_terms( $this, 'post_tag' ); + + if ( empty( $terms ) ) + return array(); + + return wp_list_pluck( $terms, 'name' ); + } + + // Rest of the values need filtering + + if ( 'ancestors' == $key ) + $value = get_post_ancestors( $this ); + else + $value = get_post_meta( $this->ID, $key, true ); + + if ( $this->filter ) + $value = sanitize_post_field( $key, $value, $this->ID, $this->filter ); + + return $value; + } + + public function filter( $filter ) { + if ( $this->filter == $filter ) + return $this; + + if ( $filter == 'raw' ) + return self::get_instance( $this->ID ); + + return sanitize_post( $this, $filter ); + } + + public function to_array() { + $post = get_object_vars( $this ); + + foreach ( array( 'ancestors', 'page_template', 'post_category', 'tags_input' ) as $key ) { + if ( $this->__isset( $key ) ) + $post[ $key ] = $this->__get( $key ); + } + + return $post; } } @@ -433,16 +680,28 @@ function &get_post(&$post, $output = OBJECT, $filter = 'raw') { * @param int|object $post Post ID or post object * @return array Ancestor IDs or empty array if none are found. */ -function get_post_ancestors($post) { - $post = get_post($post); +function get_post_ancestors( $post ) { + if ( ! $post ) + return false; - if ( ! isset( $post->ancestors ) ) - _get_post_ancestors( $post ); + $post = get_post( $post ); - if ( ! empty( $post->ancestors ) ) - return $post->ancestors; + if ( empty( $post->post_parent ) || $post->post_parent == $post->ID ) + return array(); - return array(); + $ancestors = array(); + + $id = $ancestors[] = $post->post_parent; + + while ( $ancestor = get_post( $id ) ) { + // Loop detection: If the ancestor has been seen before, break. + if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors ) ) + break; + + $id = $ancestors[] = $ancestor->post_parent; + } + + return $ancestors; } /** @@ -460,16 +719,12 @@ function get_post_ancestors($post) { * @param string $field Post field name * @param id $post Post ID * @param string $context Optional. How to filter the field. Default is display. - * @return WP_Error|string Value in post field or WP_Error on failure + * @return bool|string False on failure or returns the value in post field */ function get_post_field( $field, $post, $context = 'display' ) { - $post = (int) $post; $post = get_post( $post ); - if ( is_wp_error($post) ) - return $post; - - if ( !is_object($post) ) + if ( !$post ) return ''; if ( !isset($post->$field) ) @@ -490,7 +745,7 @@ function get_post_field( $field, $post, $context = 'display' ) { * @return bool|string False on failure or returns the mime type */ function get_post_mime_type($ID = '') { - $post = & get_post($ID); + $post = get_post($ID); if ( is_object($post) ) return $post->post_mime_type; @@ -671,7 +926,19 @@ function register_post_status($post_status, $args = array()) { $wp_post_statuses = array(); // Args prefixed with an underscore are reserved for internal use. - $defaults = array('label' => false, 'label_count' => false, 'exclude_from_search' => null, '_builtin' => false, '_edit_link' => 'post.php?post=%d', 'capability_type' => 'post', 'hierarchical' => false, 'public' => null, 'internal' => null, 'protected' => null, 'private' => null, 'show_in_admin_all' => null, 'publicly_queryable' => null, 'show_in_admin_status_list' => null, 'show_in_admin_all_list' => null, 'single_view_cap' => null); + $defaults = array( + 'label' => false, + 'label_count' => false, + 'exclude_from_search' => null, + '_builtin' => false, + 'public' => null, + 'internal' => null, + 'protected' => null, + 'private' => null, + 'publicly_queryable' => null, + 'show_in_admin_status_list' => null, + 'show_in_admin_all_list' => null, + ); $args = wp_parse_args($args, $defaults); $args = (object) $args; @@ -703,10 +970,7 @@ function register_post_status($post_status, $args = array()) { $args->show_in_admin_all_list = !$args->internal; if ( null === $args->show_in_admin_status_list ) - $args->show_in_admin_status_list = !$args->internal; - - if ( null === $args->single_view_cap ) - $args->single_view_cap = $args->public ? '' : 'edit'; + $args->show_in_admin_status_list = !$args->internal; if ( false === $args->label ) $args->label = $post_status; @@ -804,19 +1068,12 @@ function post_type_exists( $post_type ) { * * @uses $post The Loop current post global * - * @param mixed $the_post Optional. Post object or post ID. + * @param mixed $post Optional. Post object or post ID. * @return bool|string post type or false on failure. */ -function get_post_type( $the_post = false ) { - global $post; - - if ( false === $the_post ) - $the_post = $post; - elseif ( is_numeric($the_post) ) - $the_post = get_post($the_post); - - if ( is_object($the_post) ) - return $the_post->post_type; +function get_post_type( $post = null ) { + if ( $post = get_post( $post ) ) + return $post->post_type; return false; } @@ -1020,7 +1277,7 @@ function register_post_type( $post_type, $args = array() ) { if ( ! empty($args->supports) ) { add_post_type_support($post_type, $args->supports); unset($args->supports); - } else { + } elseif ( false !== $args->supports ) { // Add default features add_post_type_support($post_type, array('title', 'editor')); } @@ -1028,7 +1285,8 @@ function register_post_type( $post_type, $args = array() ) { if ( false !== $args->query_var && !empty($wp) ) { if ( true === $args->query_var ) $args->query_var = $post_type; - $args->query_var = sanitize_title_with_dashes($args->query_var); + else + $args->query_var = sanitize_title_with_dashes($args->query_var); $wp->add_query_var($args->query_var); } @@ -1182,6 +1440,10 @@ function get_post_type_capabilities( $args ) { $capabilities = array_merge( $default_capabilities, $args->capabilities ); + // Post creation capability simply maps to edit_posts by default: + if ( ! isset( $capabilities['create_posts'] ) ) + $capabilities['create_posts'] = $capabilities['edit_posts']; + // Remember meta capabilities for future reference. if ( $args->map_meta_cap ) _post_type_meta_capabilities( $capabilities ); @@ -1245,7 +1507,11 @@ function get_post_type_labels( $post_type_object ) { 'all_items' => array( __( 'All Posts' ), __( 'All Pages' ) ) ); $nohier_vs_hier_defaults['menu_name'] = $nohier_vs_hier_defaults['name']; - return _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults ); + + $labels = _get_custom_object_labels( $post_type_object, $nohier_vs_hier_defaults ); + + $post_type = $post_type_object->name; + return apply_filters( "post_type_labels_{$post_type}", $labels ); } /** @@ -1668,9 +1934,9 @@ function is_sticky( $post_id = 0 ) { * @since 2.3.0 * @uses sanitize_post_field() Used to sanitize the fields. * - * @param object|array $post The Post Object or Array + * @param object|WP_Post|array $post The Post Object or Array * @param string $context Optional, default is 'display'. How to sanitize post fields. - * @return object|array The now sanitized Post Object or Array (will be the same type as $post) + * @return object|WP_Post|array The now sanitized Post Object or Array (will be the same type as $post) */ function sanitize_post($post, $context = 'display') { if ( is_object($post) ) { @@ -1916,6 +2182,23 @@ function wp_count_attachments( $mime_type = '' ) { return (object) $stats; } +/** + * Get default post mime types + * + * @since 2.9.0 + * + * @return array + */ +function get_post_mime_types() { + $post_mime_types = array( // array( adj, noun ) + 'image' => array(__('Images'), __('Manage Images'), _n_noop('Image (%s)', 'Images (%s)')), + 'audio' => array(__('Audio'), __('Manage Audio'), _n_noop('Audio (%s)', 'Audio (%s)')), + 'video' => array(__('Video'), __('Manage Video'), _n_noop('Video (%s)', 'Video (%s)')), + ); + + return apply_filters('post_mime_types', $post_mime_types); +} + /** * Check a MIME-Type against a list. * @@ -2086,8 +2369,8 @@ function wp_delete_post( $postid = 0, $force_delete = false ) { clean_post_cache( $post ); - if ( is_post_type_hierarchical( $post->post_type ) ) { - foreach ( (array) $children as $child ) + if ( is_post_type_hierarchical( $post->post_type ) && $children ) { + foreach ( $children as $child ) clean_post_cache( $child ); } @@ -2115,7 +2398,7 @@ function wp_trash_post($post_id = 0) { if ( !EMPTY_TRASH_DAYS ) return wp_delete_post($post_id, true); - if ( !$post = wp_get_single_post($post_id, ARRAY_A) ) + if ( !$post = get_post($post_id, ARRAY_A) ) return $post; if ( $post['post_status'] == 'trash' ) @@ -2147,7 +2430,7 @@ function wp_trash_post($post_id = 0) { * @return mixed False on failure */ function wp_untrash_post($post_id = 0) { - if ( !$post = wp_get_single_post($post_id, ARRAY_A) ) + if ( !$post = get_post($post_id, ARRAY_A) ) return $post; if ( $post['post_status'] != 'trash' ) @@ -2377,49 +2660,6 @@ function wp_get_recent_posts( $args = array(), $output = ARRAY_A ) { } -/** - * Retrieve a single post, based on post ID. - * - * Has categories in 'post_category' property or key. Has tags in 'tags_input' - * property or key. - * - * @since 1.0.0 - * - * @param int $postid Post ID. - * @param string $mode How to return result, either OBJECT, ARRAY_N, or ARRAY_A. - * @return object|array Post object or array holding post contents and information - */ -function wp_get_single_post($postid = 0, $mode = OBJECT) { - $postid = (int) $postid; - - $post = get_post($postid, $mode); - - if ( - ( OBJECT == $mode && empty( $post->ID ) ) || - ( OBJECT != $mode && empty( $post['ID'] ) ) - ) - return ( OBJECT == $mode ? null : array() ); - - // Set categories and tags - if ( $mode == OBJECT ) { - $post->post_category = array(); - if ( is_object_in_taxonomy($post->post_type, 'category') ) - $post->post_category = wp_get_post_categories($postid); - $post->tags_input = array(); - if ( is_object_in_taxonomy($post->post_type, 'post_tag') ) - $post->tags_input = wp_get_post_tags($postid, array('fields' => 'names')); - } else { - $post['post_category'] = array(); - if ( is_object_in_taxonomy($post['post_type'], 'category') ) - $post['post_category'] = wp_get_post_categories($postid); - $post['tags_input'] = array(); - if ( is_object_in_taxonomy($post['post_type'], 'post_tag') ) - $post['tags_input'] = wp_get_post_tags($postid, array('fields' => 'names')); - } - - return $post; -} - /** * Insert a post. * @@ -2547,6 +2787,18 @@ function wp_insert_post($postarr, $wp_error = false) { if ( empty($post_date) || '0000-00-00 00:00:00' == $post_date ) $post_date = current_time('mysql'); + // validate the date + $mm = substr( $post_date, 5, 2 ); + $jj = substr( $post_date, 8, 2 ); + $aa = substr( $post_date, 0, 4 ); + $valid_date = wp_checkdate( $mm, $jj, $aa, $post_date ); + if ( !$valid_date ) { + if ( $wp_error ) + return new WP_Error( 'invalid_date', __( 'Whoops, the provided date is invalid.' ) ); + else + return 0; + } + if ( empty($post_date_gmt) || '0000-00-00 00:00:00' == $post_date_gmt ) { if ( !in_array( $post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) $post_date_gmt = get_gmt_from_date($post_date); @@ -2667,18 +2919,18 @@ function wp_insert_post($postarr, $wp_error = false) { $current_guid = get_post_field( 'guid', $post_ID ); - clean_post_cache( $post_ID ); - // Set GUID if ( !$update && '' == $current_guid ) $wpdb->update( $wpdb->posts, array( 'guid' => get_permalink( $post_ID ) ), $where ); + clean_post_cache( $post_ID ); + $post = get_post($post_ID); if ( !empty($page_template) && 'page' == $data['post_type'] ) { $post->page_template = $page_template; - $page_templates = get_page_templates(); - if ( 'default' != $page_template && !in_array($page_template, $page_templates) ) { + $page_templates = wp_get_theme()->get_page_templates(); + if ( 'default' != $page_template && ! isset( $page_templates[ $page_template ] ) ) { if ( $wp_error ) return new WP_Error('invalid_page_template', __('The page template is invalid.')); else @@ -2710,9 +2962,10 @@ function wp_insert_post($postarr, $wp_error = false) { * @since 1.0.0 * * @param array|object $postarr Post data. Arrays are expected to be escaped, objects are not. - * @return int 0 on failure, Post ID on success. + * @param bool $wp_error Optional. Allow return of WP_Error on failure. + * @return int|WP_Error The value 0 or WP_Error on failure. The post ID on success. */ -function wp_update_post($postarr = array()) { +function wp_update_post( $postarr = array(), $wp_error = false ) { if ( is_object($postarr) ) { // non-escaped post was passed $postarr = get_object_vars($postarr); @@ -2720,7 +2973,7 @@ function wp_update_post($postarr = array()) { } // First, get all of the original fields - $post = wp_get_single_post($postarr['ID'], ARRAY_A); + $post = get_post($postarr['ID'], ARRAY_A); // Escape data pulled from DB. $post = add_magic_quotes($post); @@ -2750,39 +3003,25 @@ function wp_update_post($postarr = array()) { if ($postarr['post_type'] == 'attachment') return wp_insert_attachment($postarr); - return wp_insert_post($postarr); + return wp_insert_post( $postarr, $wp_error ); } /** * Publish a post by transitioning the post status. * * @since 2.1.0 - * @uses $wpdb - * @uses do_action() Calls 'edit_post', 'save_post', and 'wp_insert_post' on post_id and post data. + * @uses wp_update_post() * - * @param int $post_id Post ID. - * @return null + * @param mixed $post Post ID or object. */ -function wp_publish_post($post_id) { - global $wpdb; - - $post = get_post($post_id); - - if ( empty($post) ) +function wp_publish_post( $post ) { + if ( ! $post = get_post( $post ) ) return; - if ( 'publish' == $post->post_status ) return; - $wpdb->update( $wpdb->posts, array( 'post_status' => 'publish' ), array( 'ID' => $post_id ) ); - - $old_status = $post->post_status; $post->post_status = 'publish'; - wp_transition_post_status('publish', $old_status, $post); - - do_action('edit_post', $post_id, $post); - do_action('save_post', $post_id, $post); - do_action('wp_insert_post', $post_id, $post); + wp_update_post( $post ); } /** @@ -2837,6 +3076,8 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p global $wpdb, $wp_rewrite; + $original_slug = $slug; + $feeds = $wp_rewrite->feeds; if ( ! is_array( $feeds ) ) $feeds = array(); @@ -2857,6 +3098,8 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p $slug = $alt_post_name; } } elseif ( in_array( $post_type, $hierarchical_post_types ) ) { + if ( 'nav_menu_item' == $post_type ) + return $slug; // Page slugs must be unique within their own trees. Pages are in a separate // namespace than posts so page slugs are allowed to overlap post slugs. $check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d LIMIT 1"; @@ -2887,7 +3130,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p } } - return apply_filters( 'wp_unique_post_slug', $slug, $post_ID, $post_status, $post_type, $post_parent ); + return apply_filters( 'wp_unique_post_slug', $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ); } /** @@ -2953,11 +3196,10 @@ function wp_set_post_terms( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $a // Hierarchical taxonomies must always pass IDs rather than names so that children with the same // names but different parents aren't confused. if ( is_taxonomy_hierarchical( $taxonomy ) ) { - $tags = array_map( 'intval', $tags ); - $tags = array_unique( $tags ); + $tags = array_unique( array_map( 'intval', $tags ) ); } - return wp_set_object_terms($post_id, $tags, $taxonomy, $append); + return wp_set_object_terms( $post_id, $tags, $taxonomy, $append ); } /** @@ -2986,12 +3228,7 @@ function wp_set_post_categories($post_ID = 0, $post_categories = array()) { return true; } - if ( !empty($post_categories) ) { - $post_categories = array_map('intval', $post_categories); - $post_categories = array_unique($post_categories); - } - - return wp_set_object_terms($post_ID, $post_categories, 'category'); + return wp_set_post_terms($post_ID, $post_categories, 'category'); } /** @@ -3127,7 +3364,7 @@ function get_to_ping($post_id) { function trackback_url_list($tb_list, $post_id) { if ( ! empty( $tb_list ) ) { // get post data - $postdata = wp_get_single_post($post_id, ARRAY_A); + $postdata = get_post($post_id, ARRAY_A); // import postdata as variables extract($postdata, EXTR_SKIP); @@ -3174,16 +3411,18 @@ function get_all_page_ids() { /** * Retrieves page data given a page ID or page object. * + * Use get_post() instead of get_page(). + * * @since 1.5.1 + * @deprecated 3.5.0 * * @param mixed $page Page object or page ID. Passed by reference. * @param string $output What to output. OBJECT, ARRAY_A, or ARRAY_N. * @param string $filter How the return value should be filtered. - * @return mixed Page data. + * @return WP_Post|null WP_Post on success or null on failure */ -function &get_page(&$page, $output = OBJECT, $filter = 'raw') { - $p = get_post($page, $output, $filter); - return $p; +function get_page( $page, $output = OBJECT, $filter = 'raw') { + return get_post( $page, $output, $filter ); } /** @@ -3195,7 +3434,7 @@ function &get_page(&$page, $output = OBJECT, $filter = 'raw') { * @param string $page_path Page path * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. * @param string $post_type Optional. Post type. Default page. - * @return mixed Null when complete. + * @return WP_Post|null WP_Post on success or null on failure */ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { global $wpdb; @@ -3210,7 +3449,7 @@ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { $in_string = "'". implode( "','", $parts ) . "'"; $post_type_sql = $post_type; $wpdb->escape_by_ref( $post_type_sql ); - $pages = $wpdb->get_results( "SELECT ID, post_name, post_parent FROM $wpdb->posts WHERE post_name IN ($in_string) AND (post_type = '$post_type_sql' OR post_type = 'attachment')", OBJECT_K ); + $pages = $wpdb->get_results( "SELECT ID, post_name, post_parent, post_type FROM $wpdb->posts WHERE post_name IN ($in_string) AND (post_type = '$post_type_sql' OR post_type = 'attachment')", OBJECT_K ); $revparts = array_reverse( $parts ); @@ -3229,13 +3468,14 @@ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { if ( $p->post_parent == 0 && $count+1 == count( $revparts ) && $p->post_name == $revparts[ $count ] ) { $foundid = $page->ID; - break; + if ( $page->post_type == $post_type ) + break; } } } if ( $foundid ) - return get_page( $foundid, $output ); + return get_post( $foundid, $output ); return null; } @@ -3249,13 +3489,13 @@ function get_page_by_path($page_path, $output = OBJECT, $post_type = 'page') { * @param string $page_title Page title * @param string $output Optional. Output type. OBJECT, ARRAY_N, or ARRAY_A. Default OBJECT. * @param string $post_type Optional. Post type. Default page. - * @return mixed + * @return WP_Post|null WP_Post on success or null on failure */ function get_page_by_title($page_title, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", $page_title, $post_type ) ); if ( $page ) - return get_page($page, $output); + return get_post( $page, $output ); return null; } @@ -3273,7 +3513,7 @@ function get_page_by_title($page_title, $output = OBJECT, $post_type = 'page' ) * @param array $pages List of pages' objects. * @return array */ -function &get_page_children($page_id, $pages) { +function get_page_children($page_id, $pages) { $page_list = array(); foreach ( (array) $pages as $page ) { if ( $page->post_parent == $page_id ) { @@ -3297,7 +3537,7 @@ function &get_page_children($page_id, $pages) { * @param int $page_id Parent page ID. * @return array A list arranged by hierarchy. Children immediately follow their parents. */ -function &get_page_hierarchy( &$pages, $page_id = 0 ) { +function get_page_hierarchy( &$pages, $page_id = 0 ) { if ( empty( $pages ) ) { $result = array(); return $result; @@ -3342,16 +3582,11 @@ function _page_traverse_name( $page_id, &$children, &$result ){ */ function get_page_uri($page) { if ( ! is_object($page) ) - $page = get_page($page); + $page = get_post( $page ); $uri = $page->post_name; - // A page cannot be it's own parent. - if ( $page->post_parent == $page->ID ) - return $uri; - - while ($page->post_parent != 0) { - $page = get_page($page->post_parent); - $uri = $page->post_name . "/" . $uri; + foreach ( $page->ancestors as $parent ) { + $uri = get_post( $parent )->post_name . "/" . $uri; } return $uri; @@ -3370,9 +3605,11 @@ function get_page_uri($page) { * @param mixed $args Optional. Array or string of options that overrides defaults. * @return array List of pages matching defaults or $args */ -function &get_pages($args = '') { +function get_pages($args = '') { global $wpdb; + $pages = false; + $defaults = array( 'child_of' => 0, 'sort_order' => 'ASC', 'sort_column' => 'post_title', 'hierarchical' => 1, @@ -3391,19 +3628,21 @@ function &get_pages($args = '') { // Make sure the post type is hierarchical $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) ); if ( !in_array( $post_type, $hierarchical_post_types ) ) - return false; + return $pages; // Make sure we have a valid post status if ( !is_array( $post_status ) ) $post_status = explode( ',', $post_status ); if ( array_diff( $post_status, get_post_stati() ) ) - return false; + return $pages; $cache = array(); $key = md5( serialize( compact(array_keys($defaults)) ) ); if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) { - if ( is_array($cache) && isset( $cache[ $key ] ) ) { - $pages = apply_filters('get_pages', $cache[ $key ], $r ); + if ( is_array($cache) && isset( $cache[ $key ] ) && is_array( $cache[ $key ] ) ) { + // Convert to WP_Post instances + $pages = array_map( 'get_post', $cache[ $key ] ); + $pages = apply_filters( 'get_pages', $pages, $r ); return $pages; } } @@ -3559,7 +3798,7 @@ function &get_pages($args = '') { update_post_cache( $pages ); if ( $child_of || $hierarchical ) - $pages = & get_page_children($child_of, $pages); + $pages = get_page_children($child_of, $pages); if ( !empty($exclude_tree) ) { $exclude = (int) $exclude_tree; @@ -3578,6 +3817,9 @@ function &get_pages($args = '') { $cache[ $key ] = $pages; wp_cache_set( 'get_pages', $cache, 'posts' ); + // Convert to WP_Post instances + $pages = array_map( 'get_post', $pages ); + $pages = apply_filters('get_pages', $pages, $r); return $pages; @@ -3601,7 +3843,7 @@ function is_local_attachment($url) { if (strpos($url, home_url('/?attachment_id=')) !== false) return true; if ( $id = url_to_postid($url) ) { - $post = & get_post($id); + $post = get_post($id); if ( 'attachment' == $post->post_type ) return true; } @@ -3676,13 +3918,12 @@ function wp_insert_attachment($object, $file = false, $parent = 0) { if ( ! in_array( $post_status, array( 'inherit', 'private' ) ) ) $post_status = 'inherit'; + if ( !empty($post_category) ) + $post_category = array_filter($post_category); // Filter out empty terms + // Make sure we set a valid category. - if ( !isset($post_category) || 0 == count($post_category) || !is_array($post_category) ) { - // 'post' requires at least one category. - if ( 'post' == $post_type ) - $post_category = array( get_option('default_category') ); - else - $post_category = array(); + if ( empty($post_category) || 0 == count($post_category) || !is_array($post_category) ) { + $post_category = array(); } // Are we updating or creating? @@ -3767,7 +4008,22 @@ function wp_insert_attachment($object, $file = false, $parent = 0) { $wpdb->update( $wpdb->posts, compact("post_name"), array( 'ID' => $post_ID ) ); } - wp_set_post_categories($post_ID, $post_category); + if ( is_object_in_taxonomy($post_type, 'category') ) + wp_set_post_categories( $post_ID, $post_category ); + + if ( isset( $tags_input ) && is_object_in_taxonomy($post_type, 'post_tag') ) + wp_set_post_tags( $post_ID, $tags_input ); + + // support for all custom taxonomies + if ( !empty($tax_input) ) { + foreach ( $tax_input as $taxonomy => $tags ) { + $taxonomy_obj = get_taxonomy($taxonomy); + if ( is_array($tags) ) // array = hierarchical, string = non-hierarchical. + $tags = array_filter($tags); + if ( current_user_can($taxonomy_obj->cap->assign_terms) ) + wp_set_post_terms( $post_ID, $tags, $taxonomy ); + } + } if ( $file ) update_attached_file( $post_ID, $file ); @@ -3897,7 +4153,7 @@ function wp_delete_attachment( $post_id, $force_delete = false ) { */ function wp_get_attachment_metadata( $post_id = 0, $unfiltered = false ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; $data = get_post_meta( $post->ID, '_wp_attachment_metadata', true ); @@ -3919,12 +4175,13 @@ function wp_get_attachment_metadata( $post_id = 0, $unfiltered = false ) { */ function wp_update_attachment_metadata( $post_id, $data ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; - $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ); - - return update_post_meta( $post->ID, '_wp_attachment_metadata', $data); + if ( $data = apply_filters( 'wp_update_attachment_metadata', $data, $post->ID ) ) + return update_post_meta( $post->ID, '_wp_attachment_metadata', $data ); + else + return delete_post_meta( $post->ID, '_wp_attachment_metadata' ); } /** @@ -3937,7 +4194,7 @@ function wp_update_attachment_metadata( $post_id, $data ) { */ function wp_get_attachment_url( $post_id = 0 ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; if ( 'attachment' != $post->post_type ) @@ -3976,7 +4233,7 @@ function wp_get_attachment_url( $post_id = 0 ) { */ function wp_get_attachment_thumb_file( $post_id = 0 ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; if ( !is_array( $imagedata = wp_get_attachment_metadata( $post->ID ) ) ) return false; @@ -3998,7 +4255,7 @@ function wp_get_attachment_thumb_file( $post_id = 0 ) { */ function wp_get_attachment_thumb_url( $post_id = 0 ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; if ( !$url = wp_get_attachment_url( $post->ID ) ) return false; @@ -4025,7 +4282,7 @@ function wp_get_attachment_thumb_url( $post_id = 0 ) { */ function wp_attachment_is_image( $post_id = 0 ) { $post_id = (int) $post_id; - if ( !$post =& get_post( $post_id ) ) + if ( !$post = get_post( $post_id ) ) return false; if ( !$file = get_attached_file( $post->ID ) ) @@ -4033,7 +4290,7 @@ function wp_attachment_is_image( $post_id = 0 ) { $ext = preg_match('/\.([^.]+)$/', $file, $matches) ? strtolower($matches[1]) : false; - $image_exts = array('jpg', 'jpeg', 'gif', 'png'); + $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' ); if ( 'image/' == substr($post->post_mime_type, 0, 6) || $ext && 'import' == $post->post_mime_type && in_array($ext, $image_exts) ) return true; @@ -4051,12 +4308,13 @@ function wp_attachment_is_image( $post_id = 0 ) { function wp_mime_type_icon( $mime = 0 ) { if ( !is_numeric($mime) ) $icon = wp_cache_get("mime_type_icon_$mime"); + + $post_id = 0; if ( empty($icon) ) { - $post_id = 0; $post_mimes = array(); if ( is_numeric($mime) ) { $mime = (int) $mime; - if ( $post =& get_post( $mime ) ) { + if ( $post = get_post( $mime ) ) { $post_id = (int) $post->ID; $ext = preg_replace('/^.+?\.([^.]+)$/', '$1', $post->guid); if ( !empty($ext) ) { @@ -4098,7 +4356,7 @@ function wp_mime_type_icon( $mime = 0 ) { closedir($dh); } } - wp_cache_set('icon_files', $icon_files, 600); + wp_cache_add( 'icon_files', $icon_files, 'default', 600 ); } // Icon basename - extension = MIME wildcard @@ -4118,7 +4376,7 @@ function wp_mime_type_icon( $mime = 0 ) { if ( isset($types[$wilds[0]])) { $icon = $types[$wilds[0]]; if ( !is_numeric($mime) ) - wp_cache_set("mime_type_icon_$mime", $icon); + wp_cache_add("mime_type_icon_$mime", $icon); break; } } @@ -4195,9 +4453,10 @@ function get_private_posts_cap_sql( $post_type ) { * @param string $post_type Post type. * @param bool $full Optional. Returns a full WHERE statement instead of just an 'andalso' term. * @param int $post_author Optional. Query posts having a single author ID. + * @param bool $public_only Optional. Only return public posts. Skips cap checks for $current_user. Default is false. * @return string SQL WHERE code that can be added to a query. */ -function get_posts_by_author_sql( $post_type, $full = true, $post_author = null ) { +function get_posts_by_author_sql( $post_type, $full = true, $post_author = null, $public_only = false ) { global $user_ID, $wpdb; // Private posts @@ -4221,18 +4480,21 @@ function get_posts_by_author_sql( $post_type, $full = true, $post_author = null $sql .= "(post_status = 'publish'"; - if ( current_user_can( $cap ) ) { - // Does the user have the capability to view private posts? Guess so. - $sql .= " OR post_status = 'private'"; - } elseif ( is_user_logged_in() ) { - // Users can view their own private posts. - $id = (int) $user_ID; - if ( null === $post_author || ! $full ) { - $sql .= " OR post_status = 'private' AND post_author = $id"; - } elseif ( $id == (int) $post_author ) { + // Only need to check the cap if $public_only is false + if ( false === $public_only ) { + if ( current_user_can( $cap ) ) { + // Does the user have the capability to view private posts? Guess so. $sql .= " OR post_status = 'private'"; + } elseif ( is_user_logged_in() ) { + // Users can view their own private posts. + $id = (int) $user_ID; + if ( null === $post_author || ! $full ) { + $sql .= " OR post_status = 'private' AND post_author = $id"; + } elseif ( $id == (int) $post_author ) { + $sql .= " OR post_status = 'private'"; + } // else none } // else none - } // else none + } $sql .= ')'; @@ -4351,8 +4613,6 @@ function update_post_cache( &$posts ) { * Cleaning means delete from the cache of the post. Will call to clean the term * object cache associated with the post ID. * - * clean_post_cache() will call itself recursively for each child post. - * * This function not run if $_wp_suspend_cache_invalidation is not empty. See * wp_suspend_cache_invalidation(). * @@ -4383,23 +4643,13 @@ function clean_post_cache( $post ) { do_action( 'clean_post_cache', $post->ID, $post ); + if ( is_post_type_hierarchical( $post->post_type ) ) + wp_cache_delete( 'get_pages', 'posts' ); + if ( 'page' == $post->post_type ) { wp_cache_delete( 'all_page_ids', 'posts' ); - wp_cache_delete( 'get_pages', 'posts' ); do_action( 'clean_page_cache', $post->ID ); } - - if ( $children = $wpdb->get_results( $wpdb->prepare("SELECT ID, post_type FROM $wpdb->posts WHERE post_parent = %d", $post->ID) ) ) { - foreach ( $children as $child ) { - // Loop detection - if ( $child->ID == $post->ID ) - continue; - clean_post_cache( $child ); - } - } - - if ( is_multisite() ) - wp_cache_delete( $wpdb->blogid . '-' . $post->ID, 'global-posts' ); } /** @@ -4430,8 +4680,8 @@ function update_post_caches(&$posts, $post_type = 'post', $update_term_cache = t foreach ( $posts as $post ) $post_ids[] = $post->ID; - if ( empty($post_type) ) - $post_type = 'post'; + if ( ! $post_type ) + $post_type = 'any'; if ( $update_term_cache ) { if ( is_array($post_type) ) { @@ -4571,9 +4821,8 @@ function _future_post_hook( $deprecated = '', $post ) { * @since 2.3.0 * @access private * @uses $wpdb - * @uses XMLRPC_REQUEST and APP_REQUEST constants. + * @uses XMLRPC_REQUEST constant. * @uses do_action() Calls 'xmlprc_publish_post' on post ID if XMLRPC_REQUEST is defined. - * @uses do_action() Calls 'app_publish_post' on post ID if APP_REQUEST is defined. * * @param int $post_id The ID in the database table of the post being published */ @@ -4582,8 +4831,6 @@ function _publish_post_hook($post_id) { if ( defined('XMLRPC_REQUEST') ) do_action('xmlrpc_publish_post', $post_id); - if ( defined('APP_REQUEST') ) - do_action('app_publish_post', $post_id); if ( defined('WP_IMPORTING') ) return; @@ -4595,58 +4842,6 @@ function _publish_post_hook($post_id) { wp_schedule_single_event(time(), 'do_pings'); } -/** - * Hook used to prevent page/post cache from staying dirty when a post is saved. - * - * @since 2.3.0 - * @access private - * - * @param int $post_id The ID in the database table for the $post - * @param object $post Object type containing the post information - */ -function _save_post_hook( $post_id, $post ) { - clean_post_cache( $post ); -} - -/** - * Retrieve post ancestors and append to post ancestors property. - * - * Will only retrieve ancestors once, if property is already set, then nothing - * will be done. If there is not a parent post, or post ID and post parent ID - * are the same then nothing will be done. - * - * The parameter is passed by reference, so nothing needs to be returned. The - * property will be updated and can be referenced after the function is - * complete. The post parent will be an ancestor and the parent of the post - * parent will be an ancestor. There will only be two ancestors at the most. - * - * @since 2.5.0 - * @access private - * @uses $wpdb - * - * @param object $_post Post data. - * @return null When nothing needs to be done. - */ -function _get_post_ancestors(&$_post) { - global $wpdb; - - if ( isset($_post->ancestors) ) - return; - - $_post->ancestors = array(); - - if ( empty($_post->post_parent) || $_post->ID == $_post->post_parent ) - return; - - $id = $_post->ancestors[] = (int) $_post->post_parent; - while ( $ancestor = $wpdb->get_var( $wpdb->prepare("SELECT `post_parent` FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id) ) ) { - // Loop detection: If the ancestor has been seen before, break. - if ( ( $ancestor == $_post->ID ) || in_array($ancestor, $_post->ancestors) ) - break; - $id = $_post->ancestors[] = (int) $ancestor; - } -} - /** * Determines which fields of posts are to be saved in revisions. * @@ -4726,6 +4921,9 @@ function wp_save_post_revision( $post_id ) { if ( !$post = get_post( $post_id, ARRAY_A ) ) return; + if ( 'auto-draft' == $post['post_status'] ) + return; + if ( !post_type_supports($post['post_type'], 'revisions') ) return; @@ -4890,7 +5088,7 @@ function _wp_put_post_revision( $post = null, $autosave = false ) { * @param string $filter Optional sanitation filter. @see sanitize_post() * @return mixed Null if error or post object if success */ -function &wp_get_post_revision(&$post, $output = OBJECT, $filter = 'raw') { +function wp_get_post_revision(&$post, $output = OBJECT, $filter = 'raw') { $null = null; if ( !$revision = get_post( $post, OBJECT, $filter ) ) return $revision; @@ -5166,10 +5364,10 @@ function set_post_thumbnail( $post, $thumbnail_id ) { $post = get_post( $post ); $thumbnail_id = absint( $thumbnail_id ); if ( $post && $thumbnail_id && get_post( $thumbnail_id ) ) { - $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' ); - if ( ! empty( $thumbnail_html ) ) { + if ( $thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'thumbnail' ) ) return update_post_meta( $post->ID, '_thumbnail_id', $thumbnail_id ); - } + else + return delete_post_meta( $post->ID, '_thumbnail_id' ); } return false; } diff --git a/wp-includes/query.php b/wp-includes/query.php index 5f6ccddf..443d0bb7 100644 --- a/wp-includes/query.php +++ b/wp-includes/query.php @@ -86,8 +86,7 @@ function set_query_var($var, $value) { * @param string $query * @return array List of posts */ -function &query_posts($query) { - unset($GLOBALS['wp_query']); +function query_posts($query) { $GLOBALS['wp_query'] = new WP_Query(); return $GLOBALS['wp_query']->query($query); } @@ -103,7 +102,6 @@ function &query_posts($query) { * @uses $wp_query */ function wp_reset_query() { - unset($GLOBALS['wp_query']); $GLOBALS['wp_query'] = $GLOBALS['wp_the_query']; wp_reset_postdata(); } @@ -128,7 +126,7 @@ function wp_reset_postdata() { */ /** - * Is the query for an archive page? + * Is the query for an existing archive page? * * Month, Year, Category, Author, Post Type archive... * @@ -150,7 +148,7 @@ function is_archive() { } /** - * Is the query for a post type archive page? + * Is the query for an existing post type archive page? * * @see WP_Query::is_post_type_archive() * @since 3.1.0 @@ -171,7 +169,7 @@ function is_post_type_archive( $post_types = '' ) { } /** - * Is the query for an attachment page? + * Is the query for an existing attachment page? * * @see WP_Query::is_attachment() * @since 2.0.0 @@ -191,7 +189,7 @@ function is_attachment() { } /** - * Is the query for an author archive page? + * Is the query for an existing author archive page? * * If the $author parameter is specified, this function will additionally * check if the query is for one of the authors specified. @@ -215,7 +213,7 @@ function is_author( $author = '' ) { } /** - * Is the query for a category archive page? + * Is the query for an existing category archive page? * * If the $category parameter is specified, this function will additionally * check if the query is for one of the categories specified. @@ -239,7 +237,7 @@ function is_category( $category = '' ) { } /** - * Is the query for a tag archive page? + * Is the query for an existing tag archive page? * * If the $tag parameter is specified, this function will additionally * check if the query is for one of the tags specified. @@ -263,7 +261,7 @@ function is_tag( $slug = '' ) { } /** - * Is the query for a taxonomy archive page? + * Is the query for an existing taxonomy archive page? * * If the $taxonomy parameter is specified, this function will additionally * check if the query is for that specific $taxonomy. @@ -312,7 +310,7 @@ function is_comments_popup() { } /** - * Is the query for a date archive? + * Is the query for an existing date archive? * * @see WP_Query::is_date() * @since 1.5.0 @@ -332,7 +330,7 @@ function is_date() { } /** - * Is the query for a day archive? + * Is the query for an existing day archive? * * @see WP_Query::is_day() * @since 1.5.0 @@ -452,7 +450,7 @@ function is_home() { } /** - * Is the query for a month archive? + * Is the query for an existing month archive? * * @see WP_Query::is_month() * @since 1.5.0 @@ -472,7 +470,7 @@ function is_month() { } /** - * Is the query for a single page? + * Is the query for an existing single page? * * If the $page parameter is specified, this function will additionally * check if the query is for one of the pages specified. @@ -579,7 +577,7 @@ function is_search() { } /** - * Is the query for a single post? + * Is the query for an existing single post? * * Works for any post type, except attachments and pages * @@ -608,7 +606,7 @@ function is_single( $post = '' ) { } /** - * Is the query for a single post of any post type (post, attachment, page, ... )? + * Is the query for an existing single post of any post type (post, attachment, page, ... )? * * If the $post_types parameter is specified, this function will additionally * check if the query is for one of the Posts Types specified. @@ -675,7 +673,7 @@ function is_trackback() { } /** - * Is the query for a specific year? + * Is the query for an existing year archive? * * @see WP_Query::is_year() * @since 1.5.0 @@ -979,7 +977,9 @@ class WP_Query { var $comment; /** - * Amount of posts if limit clause was not used. + * The amount of found posts for the current query. + * + * If limit clause was not used, equals $post_count. * * @since 2.1.0 * @access public @@ -1398,6 +1398,7 @@ class WP_Query { , 's' , 'sentence' , 'fields' + , 'menu_order' ); foreach ( $keys as $key ) { @@ -1452,6 +1453,7 @@ class WP_Query { if ( '' !== $qv['hour'] ) $qv['hour'] = absint($qv['hour']); if ( '' !== $qv['minute'] ) $qv['minute'] = absint($qv['minute']); if ( '' !== $qv['second'] ) $qv['second'] = absint($qv['second']); + if ( '' !== $qv['menu_order'] ) $qv['menu_order'] = absint($qv['menu_order']); // Compat. Map subpost to attachment. if ( '' != $qv['subpost'] ) @@ -1785,13 +1787,13 @@ class WP_Query { // Tag stuff if ( '' != $q['tag'] && !$this->is_singular && $this->query_vars_changed ) { if ( strpos($q['tag'], ',') !== false ) { - $tags = preg_split('/[,\s]+/', $q['tag']); + $tags = preg_split('/[,\r\n\t ]+/', $q['tag']); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); $q['tag_slug__in'][] = $tag; } - } else if ( preg_match('/[+\s]+/', $q['tag']) || !empty($q['cat']) ) { - $tags = preg_split('/[+\s]+/', $q['tag']); + } else if ( preg_match('/[+\r\n\t ]+/', $q['tag']) || !empty($q['cat']) ) { + $tags = preg_split('/[+\r\n\t ]+/', $q['tag']); foreach ( (array) $tags as $tag ) { $tag = sanitize_term_field('slug', $tag, 0, 'post_tag', 'db'); $q['tag_slug__and'][] = $tag; @@ -1914,7 +1916,7 @@ class WP_Query { * * @return array List of posts. */ - function &get_posts() { + function get_posts() { global $wpdb, $user_ID, $_wp_using_ext_object_cache; $this->parse_query(); @@ -2040,6 +2042,9 @@ class WP_Query { $fields = "$wpdb->posts.*"; } + if ( '' !== $q['menu_order'] ) + $where .= " AND $wpdb->posts.menu_order = " . $q['menu_order']; + // If a month is specified in the querystring, load that month if ( $q['m'] ) { $q['m'] = '' . preg_replace('|[^0-9]|', '', $q['m']); @@ -2128,7 +2133,7 @@ class WP_Query { $q['pagename'] = sanitize_title_for_query( wp_basename( $q['pagename'] ) ); $q['name'] = $q['pagename']; $where .= " AND ($wpdb->posts.ID = '$reqpage')"; - $reqpage_obj = get_page($reqpage); + $reqpage_obj = get_post( $reqpage ); if ( is_object($reqpage_obj) && 'attachment' == $reqpage_obj->post_type ) { $this->is_attachment = true; $post_type = $q['post_type'] = 'attachment'; @@ -2177,6 +2182,8 @@ class WP_Query { if ( !empty($q['s']) ) { // added slashes screw with quote grouping when done early, so done later $q['s'] = stripslashes($q['s']); + if ( empty( $_GET['s'] ) && $this->is_main_query() ) + $q['s'] = urldecode($q['s']); if ( !empty($q['sentence']) ) { $q['search_terms'] = array($q['s']); } else { @@ -2213,7 +2220,17 @@ class WP_Query { if ( $this->is_tax ) { if ( empty($post_type) ) { - $post_type = 'any'; + // Do a fully inclusive search for currently registered post types of queried taxonomies + $post_type = array(); + $taxonomies = wp_list_pluck( $this->tax_query->queries, 'taxonomy' ); + foreach ( get_post_types( array( 'exclude_from_search' => false ) ) as $pt ) { + $object_taxonomies = $pt === 'attachment' ? get_taxonomies_for_attachments() : get_object_taxonomies( $pt ); + if ( array_intersect( $taxonomies, $object_taxonomies ) ) + $post_type[] = $pt; + } + if ( ! $post_type ) + $post_type = 'any'; + $post_status_join = true; } elseif ( in_array('attachment', (array) $post_type) ) { $post_status_join = true; @@ -2324,6 +2341,8 @@ class WP_Query { $orderby = "$wpdb->posts.post_date " . $q['order']; } elseif ( 'none' == $q['orderby'] ) { $orderby = ''; + } elseif ( $q['orderby'] == 'post__in' && ! empty( $post__in ) ) { + $orderby = "FIELD( {$wpdb->posts}.ID, $post__in )"; } else { // Used to filter values $allowed_keys = array('name', 'author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count'); @@ -2386,7 +2405,7 @@ class WP_Query { if ( 'any' == $post_type ) { $in_search_post_types = get_post_types( array('exclude_from_search' => false) ); if ( ! empty( $in_search_post_types ) ) - $where .= $wpdb->prepare(" AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')"); + $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $in_search_post_types ) . "')"; } elseif ( !empty( $post_type ) && is_array( $post_type ) ) { $where .= " AND $wpdb->posts.post_type IN ('" . join("', '", $post_type) . "')"; } elseif ( ! empty( $post_type ) ) { @@ -2612,13 +2631,17 @@ class WP_Query { } if ( 'ids' == $q['fields'] ) { - $this->posts = $wpdb->get_col($this->request); + $this->posts = $wpdb->get_col( $this->request ); + $this->post_count = count( $this->posts ); + $this->set_found_posts( $q, $limits ); return $this->posts; } if ( 'id=>parent' == $q['fields'] ) { - $this->posts = $wpdb->get_results($this->request); + $this->posts = $wpdb->get_results( $this->request ); + $this->post_count = count( $this->posts ); + $this->set_found_posts( $q, $limits ); $r = array(); foreach ( $this->posts as $post ) @@ -2640,13 +2663,10 @@ class WP_Query { $ids = $wpdb->get_col( $this->request ); if ( $ids ) { + $this->posts = $ids; $this->set_found_posts( $q, $limits ); - _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); - - $this->posts = array_map( 'get_post', $ids ); } else { - $this->found_posts = $this->max_num_pages = 0; $this->posts = array(); } } else { @@ -2654,6 +2674,10 @@ class WP_Query { $this->set_found_posts( $q, $limits ); } + // Convert to WP_Post objects + if ( $this->posts ) + $this->posts = array_map( 'get_post', $this->posts ); + // Raw results filter. Prior to status checks. if ( !$q['suppress_filters'] ) $this->posts = apply_filters_ref_array('posts_results', array( $this->posts, &$this ) ); @@ -2700,7 +2724,7 @@ class WP_Query { } if ( $this->is_preview && $this->posts && current_user_can( $edit_cap, $this->posts[0]->ID ) ) - $this->posts[0] = apply_filters_ref_array('the_preview', array( $this->posts[0], &$this )); + $this->posts[0] = get_post( apply_filters_ref_array( 'the_preview', array( $this->posts[0], &$this ) ) ); } // Put sticky posts at the top of the posts array @@ -2730,24 +2754,15 @@ class WP_Query { // Fetch sticky posts that weren't in the query results if ( !empty($sticky_posts) ) { - $stickies__in = implode(',', array_map( 'absint', $sticky_posts )); - // honor post type(s) if not set to any - $stickies_where = ''; - if ( 'any' != $post_type && '' != $post_type ) { - if ( is_array( $post_type ) ) { - $post_types = join( "', '", $post_type ); - } else { - $post_types = $post_type; - } - $stickies_where = "AND $wpdb->posts.post_type IN ('" . $post_types . "')"; - } + $stickies = get_posts( array( + 'post__in' => $sticky_posts, + 'post_type' => $post_type, + 'post_status' => 'publish', + 'nopaging' => true + ) ); - $stickies = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE $wpdb->posts.ID IN ($stickies__in) $stickies_where" ); foreach ( $stickies as $sticky_post ) { - // Ignore sticky posts the current user cannot read or are not published. - if ( 'publish' != $sticky_post->post_status ) - continue; - array_splice($this->posts, $sticky_offset, 0, array($sticky_post)); + array_splice( $this->posts, $sticky_offset, 0, array( $sticky_post ) ); $sticky_offset++; } } @@ -2756,33 +2771,49 @@ class WP_Query { if ( !$q['suppress_filters'] ) $this->posts = apply_filters_ref_array('the_posts', array( $this->posts, &$this ) ); - $this->post_count = count($this->posts); + // Ensure that any posts added/modified via one of the filters above are + // of the type WP_Post and are filtered. + if ( $this->posts ) { + $this->post_count = count( $this->posts ); - // Always sanitize - foreach ( $this->posts as $i => $post ) { - $this->posts[$i] = sanitize_post( $post, 'raw' ); - } + $this->posts = array_map( 'get_post', $this->posts ); - if ( $q['cache_results'] ) - update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']); + if ( $q['cache_results'] ) + update_post_caches($this->posts, $post_type, $q['update_post_term_cache'], $q['update_post_meta_cache']); - if ( $this->post_count > 0 ) { - $this->post = $this->posts[0]; + $this->post = reset( $this->posts ); + } else { + $this->post_count = 0; + $this->posts = array(); } return $this->posts; } + /** + * Set up the amount of found posts and the number of pages (if limit clause was used) + * for the current query. + * + * @since 3.5.0 + * @access private + */ function set_found_posts( $q, $limits ) { global $wpdb; - if ( $q['no_found_rows'] || empty( $limits ) ) + // Bail if posts is an empty array. Continue if posts is an empty string + // null, or false to accommodate caching plugins that fill posts later. + if ( $q['no_found_rows'] || ( is_array( $this->posts ) && ! $this->posts ) ) return; - $this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) ); + if ( ! empty( $limits ) ) + $this->found_posts = $wpdb->get_var( apply_filters_ref_array( 'found_posts_query', array( 'SELECT FOUND_ROWS()', &$this ) ) ); + else + $this->found_posts = count( $this->posts ); + $this->found_posts = apply_filters_ref_array( 'found_posts', array( $this->found_posts, &$this ) ); - $this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] ); + if ( ! empty( $limits ) ) + $this->max_num_pages = ceil( $this->found_posts / $q['posts_per_page'] ); } /** @@ -2791,7 +2822,7 @@ class WP_Query { * @since 1.5.0 * @access public * - * @return object Next post. + * @return WP_Post Next post. */ function next_post() { @@ -2935,7 +2966,7 @@ class WP_Query { * @param string $query URL query string. * @return array List of posts. */ - function &query( $query ) { + function query( $query ) { $this->init(); $this->query = $this->query_vars = wp_parse_args( $query ); return $this->get_posts(); @@ -2967,10 +2998,10 @@ class WP_Query { if ( 'term_id' == $query['field'] ) $term = get_term( reset( $query['terms'] ), $query['taxonomy'] ); - else + elseif ( $query['terms'] ) $term = get_term_by( $query['field'], reset( $query['terms'] ), $query['taxonomy'] ); - if ( $term && ! is_wp_error($term) ) { + if ( ! empty( $term ) && ! is_wp_error( $term ) ) { $this->queried_object = $term; $this->queried_object_id = (int) $term->term_id; @@ -2981,7 +3012,7 @@ class WP_Query { $this->queried_object = get_post_type_object( $this->get('post_type') ); } elseif ( $this->is_posts_page ) { $page_for_posts = get_option('page_for_posts'); - $this->queried_object = get_page( $page_for_posts ); + $this->queried_object = get_post( $page_for_posts ); $this->queried_object_id = (int) $this->queried_object->ID; } elseif ( $this->is_singular && !is_null($this->post) ) { $this->queried_object = $this->post; @@ -3030,7 +3061,7 @@ class WP_Query { } /** - * Is the query for an archive page? + * Is the query for an existing archive page? * * Month, Year, Category, Author, Post Type archive... * @@ -3043,7 +3074,7 @@ class WP_Query { } /** - * Is the query for a post type archive page? + * Is the query for an existing post type archive page? * * @since 3.1.0 * @@ -3060,7 +3091,7 @@ class WP_Query { } /** - * Is the query for an attachment page? + * Is the query for an existing attachment page? * * @since 3.1.0 * @@ -3071,7 +3102,7 @@ class WP_Query { } /** - * Is the query for an author archive page? + * Is the query for an existing author archive page? * * If the $author parameter is specified, this function will additionally * check if the query is for one of the authors specified. @@ -3103,7 +3134,7 @@ class WP_Query { } /** - * Is the query for a category archive page? + * Is the query for an existing category archive page? * * If the $category parameter is specified, this function will additionally * check if the query is for one of the categories specified. @@ -3135,7 +3166,7 @@ class WP_Query { } /** - * Is the query for a tag archive page? + * Is the query for an existing tag archive page? * * If the $tag parameter is specified, this function will additionally * check if the query is for one of the tags specified. @@ -3163,7 +3194,7 @@ class WP_Query { } /** - * Is the query for a taxonomy archive page? + * Is the query for an existing taxonomy archive page? * * If the $taxonomy parameter is specified, this function will additionally * check if the query is for that specific $taxonomy. @@ -3191,8 +3222,13 @@ class WP_Query { $tax_array = array_intersect( array_keys( $wp_taxonomies ), (array) $taxonomy ); $term_array = (array) $term; - if ( empty( $term ) ) // Only a Taxonomy provided - return isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ); + // Check that the taxonomy matches. + if ( ! ( isset( $queried_object->taxonomy ) && count( $tax_array ) && in_array( $queried_object->taxonomy, $tax_array ) ) ) + return false; + + // Only a Taxonomy provided. + if ( empty( $term ) ) + return true; return isset( $queried_object->term_id ) && count( array_intersect( @@ -3213,7 +3249,7 @@ class WP_Query { } /** - * Is the query for a date archive? + * Is the query for an existing date archive? * * @since 3.1.0 * @@ -3224,7 +3260,7 @@ class WP_Query { } /** - * Is the query for a day archive? + * Is the query for an existing day archive? * * @since 3.1.0 * @@ -3311,7 +3347,7 @@ class WP_Query { } /** - * Is the query for a month archive? + * Is the query for an existing month archive? * * @since 3.1.0 * @@ -3322,7 +3358,7 @@ class WP_Query { } /** - * Is the query for a single page? + * Is the query for an existing single page? * * If the $page parameter is specified, this function will additionally * check if the query is for one of the pages specified. @@ -3401,7 +3437,7 @@ class WP_Query { } /** - * Is the query for a single post? + * Is the query for an existing single post? * * Works for any post type, except attachments and pages * @@ -3438,7 +3474,7 @@ class WP_Query { } /** - * Is the query for a single post of any post type (post, attachment, page, ... )? + * Is the query for an existing single post of any post type (post, attachment, page, ... )? * * If the $post_types parameter is specified, this function will additionally * check if the query is for one of the Posts Types specified. @@ -3483,7 +3519,7 @@ class WP_Query { } /** - * Is the query for a specific year? + * Is the query for an existing year archive? * * @since 3.1.0 * diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php index 740ffebb..486922a3 100644 --- a/wp-includes/rewrite.php +++ b/wp-includes/rewrite.php @@ -1525,8 +1525,11 @@ class WP_Rewrite { $home_path = parse_url( home_url() ); $robots_rewrite = ( empty( $home_path['path'] ) || '/' == $home_path['path'] ) ? array( 'robots\.txt$' => $this->index . '?robots=1' ) : array(); - // Old feed files - $old_feed_files = array( '.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$' => $this->index . '?feed=old' ); + // Old feed and service files + $deprecated_files = array( + '.*wp-(atom|rdf|rss|rss2|feed|commentsrss2)\.php$' => $this->index . '?feed=old', + '.*wp-app\.php(/.*)?$' => $this->index . '?error=403', + ); // Registration rules $registration_pages = array(); @@ -1585,9 +1588,9 @@ class WP_Rewrite { // Put them together. if ( $this->use_verbose_page_rules ) - $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $old_feed_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules); + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $page_rewrite, $post_rewrite, $this->extra_rules); else - $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $old_feed_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules); + $this->rules = array_merge($this->extra_rules_top, $robots_rewrite, $deprecated_files, $registration_pages, $root_rewrite, $comments_rewrite, $search_rewrite, $author_rewrite, $date_rewrite, $post_rewrite, $page_rewrite, $this->extra_rules); do_action_ref_array('generate_rewrite_rules', array(&$this)); $this->rules = apply_filters('rewrite_rules_array', $this->rules); @@ -1638,7 +1641,7 @@ class WP_Rewrite { if ( ! $this->using_permalinks() ) return ''; - $site_root = parse_url(get_option('siteurl')); + $site_root = parse_url( site_url() ); if ( isset( $site_root['path'] ) ) $site_root = trailingslashit($site_root['path']); @@ -1726,75 +1729,17 @@ class WP_Rewrite { '; } - if ( !is_multisite() ) { - $rules .= ' - - - - - - - - '; - } else { - if (is_subdomain_install()) { - $rules .= ' - - - - - - - - - - - - - - - - - - - - '; - } else { - $rules .= ' - - - - - - - - - - - - - - - - - + + $rules .= ' + + + + + - - - - - - - - - - - - - - '; - } - } + + '; + if ( $add_parent_tags ) { $rules .= ' @@ -1995,9 +1940,10 @@ class WP_Rewrite { */ function set_permalink_structure($permalink_structure) { if ( $permalink_structure != $this->permalink_structure ) { + $old_permalink_structure = $this->permalink_structure; update_option('permalink_structure', $permalink_structure); $this->init(); - do_action('permalink_structure_changed', $this->permalink_structure, $permalink_structure); + do_action('permalink_structure_changed', $old_permalink_structure, $permalink_structure); } } diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 28b4edbe..efc71e60 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -57,9 +57,14 @@ function wp_default_scripts( &$scripts ) { $scripts->default_version = get_bloginfo( 'version' ); $scripts->default_dirs = array('/wp-admin/js/', '/wp-includes/js/'); - $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : ''; + $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - $scripts->add( 'utils', "/wp-admin/js/utils$suffix.js" ); + $scripts->add( 'utils', "/wp-includes/js/utils$suffix.js" ); + did_action( 'init' ) && $scripts->localize( 'utils', 'userSettings', array( + 'url' => (string) SITECOOKIEPATH, + 'uid' => (string) get_current_user_id(), + 'time' => (string) time(), + ) ); $scripts->add( 'common', "/wp-admin/js/common$suffix.js", array('jquery', 'hoverIntent', 'utils'), false, 1 ); did_action( 'init' ) && $scripts->localize( 'common', 'commonL10n', array( @@ -90,8 +95,6 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'wp-fullscreen', "/wp-admin/js/wp-fullscreen$suffix.js", array('jquery'), false, 1 ); - $scripts->add( 'prototype', '/wp-includes/js/prototype.js', array(), '1.6.1'); - $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array('jquery'), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-ajax-response', 'wpAjax', array( 'noPerm' => __('You do not have permission to do that.'), @@ -105,62 +108,67 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response'), false, 1 ); - $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array('wp-ajax-response'), false, 1 ); + $scripts->add( 'wp-lists', "/wp-includes/js/wp-lists$suffix.js", array( 'wp-ajax-response', 'jquery-color' ), false, 1 ); - $scripts->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/wp-scriptaculous.js', array('prototype'), '1.8.3'); - $scripts->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.8.3'); - $scripts->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.8.3'); - $scripts->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.8.3'); - $scripts->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.8.3'); - $scripts->add( 'scriptaculous-sound', '/wp-includes/js/scriptaculous/sound.js', array( 'scriptaculous-root' ), '1.8.3' ); - $scripts->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.8.3'); - $scripts->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.8.3'); + // WordPress no longer uses or bundles Prototype or script.aculo.us. These are now pulled from an external source. + $scripts->add( 'prototype', '//ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js', array(), '1.7.1'); + $scripts->add( 'scriptaculous-root', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js', array('prototype'), '1.9.0'); + $scripts->add( 'scriptaculous-builder', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/builder.js', array('scriptaculous-root'), '1.9.0'); + $scripts->add( 'scriptaculous-dragdrop', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.9.0'); + $scripts->add( 'scriptaculous-effects', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/effects.js', array('scriptaculous-root'), '1.9.0'); + $scripts->add( 'scriptaculous-slider', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/slider.js', array('scriptaculous-effects'), '1.9.0'); + $scripts->add( 'scriptaculous-sound', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/sound.js', array( 'scriptaculous-root' ), '1.9.0' ); + $scripts->add( 'scriptaculous-controls', '//ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/controls.js', array('scriptaculous-root'), '1.9.0'); + $scripts->add( 'scriptaculous', false, array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls') ); // not used in core, replaced by Jcrop.js $scripts->add( 'cropper', '/wp-includes/js/crop/cropper.js', array('scriptaculous-dragdrop') ); - $scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.7.2' ); + $scripts->add( 'jquery', '/wp-includes/js/jquery/jquery.js', array(), '1.8.3' ); // full jQuery UI - $scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui/jquery.ui.core.min.js', array('jquery'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-core', '/wp-includes/js/jquery/ui/jquery.effects.core.min.js', array('jquery'), '1.8.20', 1 ); - - $scripts->add( 'jquery-effects-blind', '/wp-includes/js/jquery/ui/jquery.effects.blind.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-bounce', '/wp-includes/js/jquery/ui/jquery.effects.bounce.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-clip', '/wp-includes/js/jquery/ui/jquery.effects.clip.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-drop', '/wp-includes/js/jquery/ui/jquery.effects.drop.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-explode', '/wp-includes/js/jquery/ui/jquery.effects.explode.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-fade', '/wp-includes/js/jquery/ui/jquery.effects.fade.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-fold', '/wp-includes/js/jquery/ui/jquery.effects.fold.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-highlight', '/wp-includes/js/jquery/ui/jquery.effects.highlight.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-pulsate', '/wp-includes/js/jquery/ui/jquery.effects.pulsate.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-scale', '/wp-includes/js/jquery/ui/jquery.effects.scale.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-shake', '/wp-includes/js/jquery/ui/jquery.effects.shake.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-slide', '/wp-includes/js/jquery/ui/jquery.effects.slide.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-effects-transfer', '/wp-includes/js/jquery/ui/jquery.effects.transfer.min.js', array('jquery-effects-core'), '1.8.20', 1 ); - - $scripts->add( 'jquery-ui-accordion', '/wp-includes/js/jquery/ui/jquery.ui.accordion.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-autocomplete', '/wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-button', '/wp-includes/js/jquery/ui/jquery.ui.button.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-datepicker', '/wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js', array('jquery-ui-core'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-dialog', '/wp-includes/js/jquery/ui/jquery.ui.dialog.min.js', array('jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button', 'jquery-ui-position'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-draggable', '/wp-includes/js/jquery/ui/jquery.ui.draggable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-droppable', '/wp-includes/js/jquery/ui/jquery.ui.droppable.min.js', array('jquery-ui-draggable'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-mouse', '/wp-includes/js/jquery/ui/jquery.ui.mouse.min.js', array('jquery-ui-widget'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-position', '/wp-includes/js/jquery/ui/jquery.ui.position.min.js', array('jquery'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-progressbar', '/wp-includes/js/jquery/ui/jquery.ui.progressbar.min.js', array('jquery-ui-widget'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-resizable', '/wp-includes/js/jquery/ui/jquery.ui.resizable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-selectable', '/wp-includes/js/jquery/ui/jquery.ui.selectable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-slider', '/wp-includes/js/jquery/ui/jquery.ui.slider.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-sortable', '/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-tabs', '/wp-includes/js/jquery/ui/jquery.ui.tabs.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.8.20', 1 ); - $scripts->add( 'jquery-ui-widget', '/wp-includes/js/jquery/ui/jquery.ui.widget.min.js', array('jquery'), '1.8.20', 1 ); + $scripts->add( 'jquery-ui-core', '/wp-includes/js/jquery/ui/jquery.ui.core.min.js', array('jquery'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-core', '/wp-includes/js/jquery/ui/jquery.ui.effect.min.js', array('jquery'), '1.9.2', 1 ); + + $scripts->add( 'jquery-effects-blind', '/wp-includes/js/jquery/ui/jquery.ui.effect-blind.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-bounce', '/wp-includes/js/jquery/ui/jquery.ui.effect-bounce.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-clip', '/wp-includes/js/jquery/ui/jquery.ui.effect-clip.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-drop', '/wp-includes/js/jquery/ui/jquery.ui.effect-drop.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-explode', '/wp-includes/js/jquery/ui/jquery.ui.effect-explode.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-fade', '/wp-includes/js/jquery/ui/jquery.ui.effect-fade.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-fold', '/wp-includes/js/jquery/ui/jquery.ui.effect-fold.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-highlight', '/wp-includes/js/jquery/ui/jquery.ui.effect-highlight.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-pulsate', '/wp-includes/js/jquery/ui/jquery.ui.effect-pulsate.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-scale', '/wp-includes/js/jquery/ui/jquery.ui.effect-scale.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-shake', '/wp-includes/js/jquery/ui/jquery.ui.effect-shake.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-slide', '/wp-includes/js/jquery/ui/jquery.ui.effect-slide.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-effects-transfer', '/wp-includes/js/jquery/ui/jquery.ui.effect-transfer.min.js', array('jquery-effects-core'), '1.9.2', 1 ); + + $scripts->add( 'jquery-ui-accordion', '/wp-includes/js/jquery/ui/jquery.ui.accordion.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-autocomplete', '/wp-includes/js/jquery/ui/jquery.ui.autocomplete.min.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position', 'jquery-ui-menu'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-button', '/wp-includes/js/jquery/ui/jquery.ui.button.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-datepicker', '/wp-includes/js/jquery/ui/jquery.ui.datepicker.min.js', array('jquery-ui-core'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-dialog', '/wp-includes/js/jquery/ui/jquery.ui.dialog.min.js', array('jquery-ui-resizable', 'jquery-ui-draggable', 'jquery-ui-button', 'jquery-ui-position'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-draggable', '/wp-includes/js/jquery/ui/jquery.ui.draggable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-droppable', '/wp-includes/js/jquery/ui/jquery.ui.droppable.min.js', array('jquery-ui-draggable'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-menu', '/wp-includes/js/jquery/ui/jquery.ui.menu.min.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position' ), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-mouse', '/wp-includes/js/jquery/ui/jquery.ui.mouse.min.js', array('jquery-ui-widget'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-position', '/wp-includes/js/jquery/ui/jquery.ui.position.min.js', array('jquery'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-progressbar', '/wp-includes/js/jquery/ui/jquery.ui.progressbar.min.js', array('jquery-ui-widget'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-resizable', '/wp-includes/js/jquery/ui/jquery.ui.resizable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-selectable', '/wp-includes/js/jquery/ui/jquery.ui.selectable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-slider', '/wp-includes/js/jquery/ui/jquery.ui.slider.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-sortable', '/wp-includes/js/jquery/ui/jquery.ui.sortable.min.js', array('jquery-ui-core', 'jquery-ui-mouse'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-spinner', '/wp-includes/js/jquery/ui/jquery.ui.spinner.min.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-button' ), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-tabs', '/wp-includes/js/jquery/ui/jquery.ui.tabs.min.js', array('jquery-ui-core', 'jquery-ui-widget'), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-tooltip', '/wp-includes/js/jquery/ui/jquery.ui.tooltip.min.js', array( 'jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position' ), '1.9.2', 1 ); + $scripts->add( 'jquery-ui-widget', '/wp-includes/js/jquery/ui/jquery.ui.widget.min.js', array('jquery'), '1.9.2', 1 ); // deprecated, not used in core, most functionality is included in jQuery 1.3 $scripts->add( 'jquery-form', "/wp-includes/js/jquery/jquery.form$suffix.js", array('jquery'), '2.73', 1 ); // jQuery plugins - $scripts->add( 'jquery-color', "/wp-includes/js/jquery/jquery.color$suffix.js", array('jquery'), '2.0-4561m', 1 ); + $scripts->add( 'jquery-color', "/wp-includes/js/jquery/jquery.color.min.js", array('jquery'), '2.1.0', 1 ); $scripts->add( 'suggest', "/wp-includes/js/jquery/suggest$suffix.js", array('jquery'), '1.1-20110113', 1 ); $scripts->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20m', 1 ); $scripts->add( 'jquery-query', "/wp-includes/js/jquery/jquery.query.js", array('jquery'), '2.1.7', 1 ); @@ -168,8 +176,9 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'jquery-hotkeys', "/wp-includes/js/jquery/jquery.hotkeys$suffix.js", array('jquery'), '0.0.2m', 1 ); $scripts->add( 'jquery-table-hotkeys', "/wp-includes/js/jquery/jquery.table-hotkeys$suffix.js", array('jquery', 'jquery-hotkeys'), false, 1 ); $scripts->add( 'jquery-touch-punch', "/wp-includes/js/jquery/jquery.ui.touch-punch.js", array('jquery-ui-widget', 'jquery-ui-mouse'), '0.2.2', 1 ); + $scripts->add( 'jquery-masonry', "/wp-includes/js/jquery/jquery.masonry.min.js", array('jquery'), '2.1.05', 1 ); - $scripts->add( 'thickbox', "/wp-includes/js/thickbox/thickbox.js", array('jquery'), '3.1-20111117', 1 ); + $scripts->add( 'thickbox', "/wp-includes/js/thickbox/thickbox.js", array('jquery'), '3.1-20121105', 1 ); did_action( 'init' ) && $scripts->localize( 'thickbox', 'thickboxL10n', array( 'next' => __('Next >'), 'prev' => __('< Prev'), @@ -181,7 +190,7 @@ function wp_default_scripts( &$scripts ) { 'closeImage' => includes_url('js/thickbox/tb-close.png') ) ); - $scripts->add( 'jcrop', "/wp-includes/js/jcrop/jquery.Jcrop$suffix.js", array('jquery'), '0.9.8-20110113'); + $scripts->add( 'jcrop', "/wp-includes/js/jcrop/jquery.Jcrop.min.js", array('jquery'), '0.9.10'); $scripts->add( 'swfobject', "/wp-includes/js/swfobject.js", array(), '2.2-20120417'); @@ -217,7 +226,7 @@ function wp_default_scripts( &$scripts ) { 'error_uploading' => __('“%s” has failed to upload.') ); - $scripts->add( 'plupload', '/wp-includes/js/plupload/plupload.js', '1.5.4' ); + $scripts->add( 'plupload', '/wp-includes/js/plupload/plupload.js', array(), '1.5.4' ); $scripts->add( 'plupload-html5', '/wp-includes/js/plupload/plupload.html5.js', array('plupload'), '1.5.4' ); $scripts->add( 'plupload-flash', '/wp-includes/js/plupload/plupload.flash.js', array('plupload'), '1.5.4' ); $scripts->add( 'plupload-silverlight', '/wp-includes/js/plupload/plupload.silverlight.js', array('plupload'), '1.5.4' ); @@ -229,7 +238,7 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'plupload-handlers', "/wp-includes/js/plupload/handlers$suffix.js", array('plupload-all', 'jquery') ); did_action( 'init' ) && $scripts->localize( 'plupload-handlers', 'pluploadL10n', $uploader_l10n ); - $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array('plupload-all', 'jquery', 'json2') ); + $scripts->add( 'wp-plupload', "/wp-includes/js/plupload/wp-plupload$suffix.js", array('plupload-all', 'jquery', 'json2', 'media-models'), false, 1 ); did_action( 'init' ) && $scripts->localize( 'wp-plupload', 'pluploadL10n', $uploader_l10n ); // keep 'swfupload' for back-compat. @@ -252,6 +261,9 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", array(), '2011-02-23'); + $scripts->add( 'underscore', '/wp-includes/js/underscore.min.js', array(), '1.4.0', 1 ); + $scripts->add( 'backbone', '/wp-includes/js/backbone.min.js', array('underscore','jquery'), '0.9.2', 1 ); + $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 ); $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array('jquery'), false, 1 ); @@ -291,7 +303,7 @@ function wp_default_scripts( &$scripts ) { 'type' => 'characters' == _x( 'words', 'word count: words or characters?' ) ? 'c' : 'w', ) ); - $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox' ), false, 1 ); + $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 ); $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array('jquery'), 'r6', 1 ); @@ -306,8 +318,26 @@ function wp_default_scripts( &$scripts ) { 'cancel' => __( 'Cancel' ), 'close' => __( 'Close' ), 'cheatin' => __( 'Cheatin’ uh?' ), + + // Used for overriding the file types allowed in plupload. + 'allowedFiles' => __( 'Allowed Files' ), ) ); + $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 ); + $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'backbone', 'jquery' ), false, 1 ); + did_action( 'init' ) && $scripts->localize( 'media-models', '_wpMediaModelsL10n', array( + 'settings' => array( + 'ajaxurl' => admin_url( 'admin-ajax.php', 'relative' ), + 'post' => array( 'id' => 0 ), + ), + ) ); + + // To enqueue media-views or media-editor, call wp_enqueue_media(). + // Both rely on numerous settings, styles, and templates to operate correctly. + $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable' ), false, 1 ); + $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); + $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 ); + if ( is_admin() ) { $scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ) ); $scripts->add_data( 'ajaxcat', 'group', 1 ); @@ -361,9 +391,9 @@ function wp_default_scripts( &$scripts ) { 'comma' => _x( ',', 'tag delimiter' ), ) ); - $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array('wp-lists', 'postbox'), false, 1 ); + $scripts->add( 'link', "/wp-admin/js/link$suffix.js", array( 'wp-lists', 'postbox' ), false, 1 ); - $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array('jquery') ); + $scripts->add( 'comment', "/wp-admin/js/comment$suffix.js", array( 'jquery', 'postbox' ) ); $scripts->add_data( 'comment', 'group', 1 ); did_action( 'init' ) && $scripts->localize( 'comment', 'commentL10n', array( 'submittedOn' => __('Submitted on:') @@ -399,6 +429,15 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'farbtastic', '/wp-admin/js/farbtastic.js', array('jquery'), '1.2' ); + $scripts->add( 'iris', '/wp-admin/js/iris.min.js', array( 'jquery-ui-draggable', 'jquery-ui-slider', 'jquery-touch-punch' ), false, 1 ); + $scripts->add( 'wp-color-picker', "/wp-admin/js/color-picker$suffix.js", array( 'iris' ), false, 1 ); + did_action( 'init' ) && $scripts->localize( 'wp-color-picker', 'wpColorPickerL10n', array( + 'clear' => __( 'Clear' ), + 'defaultString' => __( 'Default' ), + 'pick' => __( 'Select Color' ), + 'current' => __( 'Current Color' ), + ) ); + $scripts->add( 'dashboard', "/wp-admin/js/dashboard$suffix.js", array( 'jquery', 'admin-comments', 'postbox' ), false, 1 ); $scripts->add( 'list-revisions', "/wp-includes/js/wp-list-revisions$suffix.js" ); @@ -419,14 +458,15 @@ function wp_default_scripts( &$scripts ) { ) ); // Navigation Menus - $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array('jquery-ui-sortable') ); + $scripts->add( 'nav-menu', "/wp-admin/js/nav-menu$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'wp-lists', 'postbox' ) ); did_action( 'init' ) && $scripts->localize( 'nav-menu', 'navMenuL10n', array( 'noResultsFound' => _x('No results found.', 'search results'), 'warnDeleteMenu' => __( "You are about to permanently delete this menu. \n 'Cancel' to stop, 'OK' to delete." ), 'saveAlert' => __('The changes you made will be lost if you navigate away from this page.') ) ); - $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array('farbtastic'), false, 1 ); + $scripts->add( 'custom-header', "/wp-admin/js/custom-header.js", array( 'jquery-masonry' ), false, 1 ); + $scripts->add( 'custom-background', "/wp-admin/js/custom-background$suffix.js", array( 'wp-color-picker', 'media-views' ), false, 1 ); $scripts->add( 'media-gallery', "/wp-admin/js/media-gallery$suffix.js", array('jquery'), false, 1 ); } } @@ -457,10 +497,10 @@ function wp_default_styles( &$styles ) { $styles->text_direction = function_exists( 'is_rtl' ) && is_rtl() ? 'rtl' : 'ltr'; $styles->default_dirs = array('/wp-admin/', '/wp-includes/css/'); - $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '.dev' : ''; + $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; - $rtl_styles = array( 'wp-admin', 'ie', 'media', 'admin-bar', 'wplink', 'customize-controls' ); - // Any rtl stylesheets that don't have a .dev version for ltr + $rtl_styles = array( 'wp-admin', 'ie', 'media', 'admin-bar', 'customize-controls', 'media-views', 'wp-color-picker' ); + // Any rtl stylesheets that don't have a .min version $no_suffix = array( 'farbtastic' ); $styles->add( 'wp-admin', "/wp-admin/css/wp-admin$suffix.css" ); @@ -469,23 +509,26 @@ function wp_default_styles( &$styles ) { $styles->add_data( 'ie', 'conditional', 'lte IE 7' ); // Register "meta" stylesheet for admin colors. All colors-* style sheets should have the same version string. - $styles->add( 'colors', true, array('wp-admin') ); + $styles->add( 'colors', true, array('wp-admin', 'buttons') ); // do not refer to these directly, the right one is queued by the above "meta" colors handle - $styles->add( 'colors-fresh', "/wp-admin/css/colors-fresh$suffix.css", array('wp-admin') ); - $styles->add( 'colors-classic', "/wp-admin/css/colors-classic$suffix.css", array('wp-admin') ); + $styles->add( 'colors-fresh', "/wp-admin/css/colors-fresh$suffix.css", array('wp-admin', 'buttons') ); + $styles->add( 'colors-classic', "/wp-admin/css/colors-classic$suffix.css", array('wp-admin', 'buttons') ); $styles->add( 'media', "/wp-admin/css/media$suffix.css" ); - $styles->add( 'install', "/wp-admin/css/install$suffix.css" ); - $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css' ); + $styles->add( 'install', "/wp-admin/css/install$suffix.css", array('buttons') ); + $styles->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.css', array(), '20121105' ); $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.3u1' ); - $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); + $styles->add( 'wp-color-picker', "/wp-admin/css/color-picker$suffix.css" ); + $styles->add( 'jcrop', "/wp-includes/js/jcrop/jquery.Jcrop.min.css", array(), '0.9.10' ); $styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.8' ); $styles->add( 'admin-bar', "/wp-includes/css/admin-bar$suffix.css" ); $styles->add( 'wp-jquery-ui-dialog', "/wp-includes/css/jquery-ui-dialog$suffix.css" ); $styles->add( 'editor-buttons', "/wp-includes/css/editor$suffix.css" ); $styles->add( 'wp-pointer', "/wp-includes/css/wp-pointer$suffix.css" ); $styles->add( 'customize-controls', "/wp-admin/css/customize-controls$suffix.css", array( 'wp-admin', 'colors', 'ie' ) ); + $styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons' ) ); + $styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" ); foreach ( $rtl_styles as $rtl_style ) { $styles->add_data( $rtl_style, 'rtl', true ); @@ -503,10 +546,10 @@ function wp_default_styles( &$styles ) { * @return array Reordered array, if needed. */ function wp_prototype_before_jquery( $js_array ) { - if ( false === $jquery = array_search( 'jquery', $js_array, true ) ) + if ( false === $prototype = array_search( 'prototype', $js_array, true ) ) return $js_array; - if ( false === $prototype = array_search( 'prototype', $js_array, true ) ) + if ( false === $jquery = array_search( 'jquery', $js_array, true ) ) return $js_array; if ( $prototype < $jquery ) @@ -572,7 +615,7 @@ function wp_style_loader_src( $src, $handle ) { $url = $color->url; if ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ) - $url = preg_replace('/.css$|.css(?=\?)/', '.dev.css', $url); + $url = preg_replace( '/.min.css$|.min.css(?=\?)/', '.css', $url ); if ( isset($parsed['query']) && $parsed['query'] ) { wp_parse_str( $parsed['query'], $qv ); @@ -646,7 +689,7 @@ function _print_scripts() { if ( $zip && defined('ENFORCE_GZIP') && ENFORCE_GZIP ) $zip = 'gzip'; - if ( !empty($wp_scripts->concat) ) { + if ( $concat = trim( $wp_scripts->concat, ', ' ) ) { if ( !empty($wp_scripts->print_code) ) { echo "\n\n"; } - $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}&load=" . trim($wp_scripts->concat, ', ') . '&ver=' . $wp_scripts->default_version; + $concat = str_split( $concat, 128 ); + $concat = 'load[]=' . implode( '&load[]=', $concat ); + + $src = $wp_scripts->base_url . "/wp-admin/load-scripts.php?c={$zip}&" . $concat . '&ver=' . $wp_scripts->default_version; echo "\n"; } diff --git a/wp-includes/shortcodes.php b/wp-includes/shortcodes.php index 1b860d27..2dfc2774 100644 --- a/wp-includes/shortcodes.php +++ b/wp-includes/shortcodes.php @@ -177,11 +177,12 @@ function get_shortcode_regex() { $tagregexp = join( '|', array_map('preg_quote', $tagnames) ); // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag() + // Also, see shortcode_unautop() and shortcode.js. return '\\[' // Opening bracket . '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]] . "($tagregexp)" // 2: Shortcode name - . '\\b' // Word boundary + . '(?![\\w-])' // Not followed by word character or hyphen . '(' // 3: Unroll the loop: Inside the opening shortcode tag . '[^\\]\\/]*' // Not a closing bracket or forward slash . '(?:' diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php index 514574e2..1932bab3 100644 --- a/wp-includes/taxonomy.php +++ b/wp-includes/taxonomy.php @@ -47,6 +47,7 @@ function create_initial_taxonomies() { 'rewrite' => $rewrite['category'], 'public' => true, 'show_ui' => true, + 'show_admin_column' => true, '_builtin' => true, ) ); @@ -56,6 +57,7 @@ function create_initial_taxonomies() { 'rewrite' => $rewrite['post_tag'], 'public' => true, 'show_ui' => true, + 'show_admin_column' => true, '_builtin' => true, ) ); @@ -89,6 +91,12 @@ function create_initial_taxonomies() { 'add_or_remove_items' => null, 'choose_from_most_used' => null, ), + 'capabilities' => array( + 'manage_terms' => 'manage_links', + 'edit_terms' => 'manage_links', + 'delete_terms' => 'manage_links', + 'assign_terms' => 'manage_links', + ), 'query_var' => false, 'rewrite' => false, 'public' => false, @@ -301,6 +309,7 @@ function is_taxonomy_hierarchical($taxonomy) { * @param string $taxonomy Name of taxonomy object * @param array|string $object_type Name of the object type for the taxonomy object. * @param array|string $args See above description for the two keys values. + * @return null|WP_Error WP_Error if errors, otherwise null. */ function register_taxonomy( $taxonomy, $object_type, $args = array() ) { global $wp_taxonomies, $wp; @@ -322,10 +331,14 @@ function register_taxonomy( $taxonomy, $object_type, $args = array() ) { ); $args = wp_parse_args($args, $defaults); + if ( strlen( $taxonomy ) > 32 ) + return new WP_Error( 'taxonomy_too_long', __( 'Taxonomies cannot exceed 32 characters in length' ) ); + if ( false !== $args['query_var'] && !empty($wp) ) { if ( true === $args['query_var'] ) $args['query_var'] = $taxonomy; - $args['query_var'] = sanitize_title_with_dashes($args['query_var']); + else + $args['query_var'] = sanitize_title_with_dashes($args['query_var']); $wp->add_query_var($args['query_var']); } @@ -651,23 +664,26 @@ class WP_Tax_Query { $join = ''; $where = array(); $i = 0; + $count = count( $this->queries ); - foreach ( $this->queries as $query ) { + foreach ( $this->queries as $index => $query ) { $this->clean_query( $query ); - if ( is_wp_error( $query ) ) { + if ( is_wp_error( $query ) ) return self::$no_results; - } extract( $query ); if ( 'IN' == $operator ) { if ( empty( $terms ) ) { - if ( 'OR' == $this->relation ) + if ( 'OR' == $this->relation ) { + if ( ( $index + 1 === $count ) && empty( $where ) ) + return self::$no_results; continue; - else + } else { return self::$no_results; + } } $terms = implode( ',', $terms ); @@ -711,7 +727,7 @@ class WP_Tax_Query { $i++; } - if ( !empty( $where ) ) + if ( ! empty( $where ) ) $where = ' AND ( ' . implode( " $this->relation ", $where ) . ' )'; else $where = ''; @@ -756,12 +772,11 @@ class WP_Tax_Query { * Transforms a single query, from one field to another. * * @since 3.2.0 - * @access private * * @param array &$query The single query * @param string $resulting_field The resulting field */ - private function transform_query( &$query, $resulting_field ) { + public function transform_query( &$query, $resulting_field ) { global $wpdb; if ( empty( $query['terms'] ) ) @@ -784,7 +799,14 @@ class WP_Tax_Query { AND $wpdb->terms.{$query['field']} IN ($terms) " ); break; - + case 'term_taxonomy_id': + $terms = implode( ',', array_map( 'intval', $query['terms'] ) ); + $terms = $wpdb->get_col( " + SELECT $resulting_field + FROM $wpdb->term_taxonomy + WHERE term_taxonomy_id IN ($terms) + " ); + break; default: $terms = implode( ',', array_map( 'intval', $query['terms'] ) ); $terms = $wpdb->get_col( " @@ -845,7 +867,7 @@ class WP_Tax_Query { * @return mixed|null|WP_Error Term Row from database. Will return null if $term is empty. If taxonomy does not * exist then WP_Error will be returned. */ -function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { +function get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') { global $wpdb; $null = null; @@ -1162,15 +1184,13 @@ function get_term_to_edit( $id, $taxonomy ) { * @param string|array $args The values of what to search for when returning terms * @return array|WP_Error List of Term Objects and their children. Will return WP_Error, if any of $taxonomies do not exist. */ -function &get_terms($taxonomies, $args = '') { +function get_terms($taxonomies, $args = '') { global $wpdb; $empty_array = array(); - $single_taxonomy = false; - if ( !is_array($taxonomies) ) { - $single_taxonomy = true; - $taxonomies = array($taxonomies); - } + $single_taxonomy = ! is_array( $taxonomies ) || 1 === count( $taxonomies ); + if ( ! is_array( $taxonomies ) ) + $taxonomies = array( $taxonomies ); foreach ( $taxonomies as $taxonomy ) { if ( ! taxonomy_exists($taxonomy) ) { @@ -1384,7 +1404,7 @@ function &get_terms($taxonomies, $args = '') { } if ( empty($terms) ) { - wp_cache_add( $cache_key, array(), 'terms', 86400 ); // one day + wp_cache_add( $cache_key, array(), 'terms', DAY_IN_SECONDS ); $terms = apply_filters('get_terms', array(), $taxonomies, $args); return $terms; } @@ -1392,7 +1412,7 @@ function &get_terms($taxonomies, $args = '') { if ( $child_of ) { $children = _get_term_hierarchy($taxonomies[0]); if ( ! empty($children) ) - $terms = & _get_term_children($child_of, $terms, $taxonomies[0]); + $terms = _get_term_children($child_of, $terms, $taxonomies[0]); } // Update term counts to include children. @@ -1435,7 +1455,7 @@ function &get_terms($taxonomies, $args = '') { $terms = array_slice($terms, $offset, $number); } - wp_cache_add( $cache_key, $terms, 'terms', 86400 ); // one day + wp_cache_add( $cache_key, $terms, 'terms', DAY_IN_SECONDS ); $terms = apply_filters('get_terms', $terms, $taxonomies, $args); return $terms; @@ -1665,7 +1685,7 @@ function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) { * * @param string $taxonomy Taxonomy name * @param array|string $args Overwrite defaults. See get_terms() - * @return int How many terms are in $taxonomy + * @return int|WP_Error How many terms are in $taxonomy. WP_Error if $taxonomy does not exist. */ function wp_count_terms( $taxonomy, $args = array() ) { $defaults = array('hide_empty' => false); @@ -1802,6 +1822,9 @@ function wp_delete_term( $term, $taxonomy, $args = array() ) { foreach ( $tax_object->object_type as $object_type ) clean_object_term_cache( $objects, $object_type ); + // Get the object before deletion so we can pass to actions below + $deleted_term = get_term( $term, $taxonomy ); + do_action( 'delete_term_taxonomy', $tt_id ); $wpdb->delete( $wpdb->term_taxonomy, array( 'term_taxonomy_id' => $tt_id ) ); do_action( 'deleted_term_taxonomy', $tt_id ); @@ -1812,8 +1835,8 @@ function wp_delete_term( $term, $taxonomy, $args = array() ) { clean_term_cache($term, $taxonomy); - do_action('delete_term', $term, $tt_id, $taxonomy); - do_action("delete_$taxonomy", $term, $tt_id); + do_action( 'delete_term', $term, $tt_id, $taxonomy, $deleted_term ); + do_action( "delete_$taxonomy", $term, $tt_id, $deleted_term ); return true; } @@ -2211,9 +2234,12 @@ function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) { if ( in_array($tt_id, $final_tt_ids) ) $values[] = $wpdb->prepare( "(%d, %d, %d)", $object_id, $tt_id, ++$term_order); if ( $values ) - $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join(',', $values) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)"); + if ( false === $wpdb->query( "INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)" ) ) + return new WP_Error( 'db_insert_error', __( 'Could not insert term relationship into the database' ), $wpdb->last_error ); } + wp_cache_delete( $object_id, $taxonomy . '_relationships' ); + do_action('set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids); return $tt_ids; } @@ -2540,8 +2566,10 @@ function clean_object_term_cache($object_ids, $object_type) { if ( !is_array($object_ids) ) $object_ids = array($object_ids); + $taxonomies = get_object_taxonomies( $object_type ); + foreach ( $object_ids as $id ) - foreach ( get_object_taxonomies($object_type) as $taxonomy ) + foreach ( $taxonomies as $taxonomy ) wp_cache_delete($id, "{$taxonomy}_relationships"); do_action('clean_object_term_cache', $object_ids, $object_type); @@ -2620,7 +2648,7 @@ function clean_term_cache($ids, $taxonomy = '', $clean_taxonomy = true) { * @param string $taxonomy Taxonomy Name * @return bool|array Empty array if $terms found, but not $taxonomy. False if nothing is in cache for $taxonomy and $id. */ -function &get_object_term_cache($id, $taxonomy) { +function get_object_term_cache($id, $taxonomy) { $cache = wp_cache_get($id, "{$taxonomy}_relationships"); return $cache; } @@ -2766,7 +2794,7 @@ function _get_term_hierarchy($taxonomy) { * @param string $taxonomy The taxonomy which determines the hierarchy of the terms. * @return array The subset of $terms that are descendants of $term_id. */ -function &_get_term_children($term_id, $terms, $taxonomy) { +function _get_term_children($term_id, $terms, $taxonomy) { $empty_array = array(); if ( empty($terms) ) return $empty_array; @@ -2964,9 +2992,9 @@ function get_term_link( $term, $taxonomy = '') { if ( !is_object($term) ) { if ( is_int($term) ) { - $term = &get_term($term, $taxonomy); + $term = get_term($term, $taxonomy); } else { - $term = &get_term_by('slug', $term, $taxonomy); + $term = get_term_by('slug', $term, $taxonomy); } } @@ -3063,10 +3091,7 @@ function the_taxonomies($args = array()) { * @return array */ function get_the_taxonomies($post = 0, $args = array() ) { - if ( is_int($post) ) - $post =& get_post($post); - elseif ( !is_object($post) ) - $post =& $GLOBALS['post']; + $post = get_post( $post ); $args = wp_parse_args( $args, array( 'template' => '%s: %l.', @@ -3088,7 +3113,7 @@ function get_the_taxonomies($post = 0, $args = array() ) { $t['template'] = $template; $terms = get_object_term_cache($post->ID, $taxonomy); - if ( empty($terms) ) + if ( false === $terms ) $terms = wp_get_object_terms($post->ID, $taxonomy, $t['args']); $links = array(); @@ -3112,7 +3137,7 @@ function get_the_taxonomies($post = 0, $args = array() ) { * @return array */ function get_post_taxonomies($post = 0) { - $post =& get_post($post); + $post = get_post( $post ); return get_object_taxonomies($post); } @@ -3138,7 +3163,7 @@ function is_object_in_term( $object_id, $taxonomy, $terms = null ) { return new WP_Error( 'invalid_object', __( 'Invalid object ID' ) ); $object_terms = get_object_term_cache( $object_id, $taxonomy ); - if ( empty( $object_terms ) ) + if ( false === $object_terms ) $object_terms = wp_get_object_terms( $object_id, $taxonomy ); if ( is_wp_error( $object_terms ) ) @@ -3211,16 +3236,8 @@ function get_ancestors($object_id = 0, $object_type = '') { $ancestors[] = (int) $term->parent; $term = get_term($term->parent, $object_type); } - } elseif ( null !== get_post_type_object( $object_type ) ) { - $object = get_post($object_id); - if ( ! is_wp_error( $object ) && isset( $object->ancestors ) && is_array( $object->ancestors ) ) - $ancestors = $object->ancestors; - else { - while ( ! is_wp_error($object) && ! empty( $object->post_parent ) && ! in_array( $object->post_parent, $ancestors ) ) { - $ancestors[] = (int) $object->post_parent; - $object = get_post($object->post_parent); - } - } + } elseif ( post_type_exists( $object_type ) ) { + $ancestors = get_post_ancestors($object_id); } return apply_filters('get_ancestors', $ancestors, $object_id, $object_type); diff --git a/wp-includes/template-loader.php b/wp-includes/template-loader.php index fdf75f15..7051f345 100644 --- a/wp-includes/template-loader.php +++ b/wp-includes/template-loader.php @@ -6,6 +6,10 @@ if ( defined('WP_USE_THEMES') && WP_USE_THEMES ) do_action('template_redirect'); +// Halt template load for HEAD requests. Performance bump. See #14348 +if ( 'HEAD' === $_SERVER['REQUEST_METHOD'] && apply_filters( 'exit_on_http_head', true ) ) + exit(); + // Process feeds and trackbacks even if not using themes. if ( is_robots() ) : do_action('do_robots'); diff --git a/wp-includes/template.php b/wp-includes/template.php index 531b308d..d86a677f 100644 --- a/wp-includes/template.php +++ b/wp-includes/template.php @@ -59,11 +59,11 @@ function get_404_template() { * @return string */ function get_archive_template() { - $post_type = get_query_var( 'post_type' ); + $post_types = get_query_var( 'post_type' ); $templates = array(); - if ( $post_type ) + foreach ( (array) $post_types as $post_type ) $templates[] = "archive-{$post_type}.php"; $templates[] = 'archive.php'; @@ -82,8 +82,10 @@ function get_author_template() { $templates = array(); - $templates[] = "author-{$author->user_nicename}.php"; - $templates[] = "author-{$author->ID}.php"; + if ( $author ) { + $templates[] = "author-{$author->user_nicename}.php"; + $templates[] = "author-{$author->ID}.php"; + } $templates[] = 'author.php'; return get_query_template( 'author', $templates ); @@ -106,8 +108,10 @@ function get_category_template() { $templates = array(); - $templates[] = "category-{$category->slug}.php"; - $templates[] = "category-{$category->term_id}.php"; + if ( $category ) { + $templates[] = "category-{$category->slug}.php"; + $templates[] = "category-{$category->term_id}.php"; + } $templates[] = 'category.php'; return get_query_template( 'category', $templates ); @@ -130,8 +134,10 @@ function get_tag_template() { $templates = array(); - $templates[] = "tag-{$tag->slug}.php"; - $templates[] = "tag-{$tag->term_id}.php"; + if ( $tag ) { + $templates[] = "tag-{$tag->slug}.php"; + $templates[] = "tag-{$tag->term_id}.php"; + } $templates[] = 'tag.php'; return get_query_template( 'tag', $templates ); @@ -156,12 +162,14 @@ function get_tag_template() { */ function get_taxonomy_template() { $term = get_queried_object(); - $taxonomy = $term->taxonomy; $templates = array(); - $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; - $templates[] = "taxonomy-$taxonomy.php"; + if ( $term ) { + $taxonomy = $term->taxonomy; + $templates[] = "taxonomy-$taxonomy-{$term->slug}.php"; + $templates[] = "taxonomy-$taxonomy.php"; + } $templates[] = 'taxonomy.php'; return get_query_template( 'taxonomy', $templates ); @@ -280,7 +288,8 @@ function get_single_template() { $templates = array(); - $templates[] = "single-{$object->post_type}.php"; + if ( $object ) + $templates[] = "single-{$object->post_type}.php"; $templates[] = "single.php"; return get_query_template( 'single', $templates ); @@ -303,15 +312,21 @@ function get_single_template() { */ function get_attachment_template() { global $posts; - $type = explode('/', $posts[0]->post_mime_type); - if ( $template = get_query_template($type[0]) ) - return $template; - elseif ( $template = get_query_template($type[1]) ) - return $template; - elseif ( $template = get_query_template("$type[0]_$type[1]") ) - return $template; - else - return get_query_template('attachment'); + + if ( ! empty( $posts ) && isset( $posts[0]->post_mime_type ) ) { + $type = explode( '/', $posts[0]->post_mime_type ); + + if ( ! empty( $type ) ) { + if ( $template = get_query_template( $type[0] ) ) + return $template; + elseif ( $template = get_query_template( $type[1] ) ) + return $template; + elseif ( $template = get_query_template( "$type[0]_$type[1]" ) ) + return $template; + } + } + + return get_query_template( 'attachment' ); } /** diff --git a/wp-includes/theme-compat/comments-popup.php b/wp-includes/theme-compat/comments-popup.php index de4c1e9e..eb74834c 100644 --- a/wp-includes/theme-compat/comments-popup.php +++ b/wp-includes/theme-compat/comments-popup.php @@ -32,7 +32,7 @@ while( have_posts()) : the_post(); ?>

    -

    RSS feed for comments on this post.'); ?>

    +

    RSS feed for comments on this post.'); ?>

    URL to TrackBack this entry is: %s'), get_trackback_url()); ?>

    @@ -68,7 +68,7 @@ if ( post_password_required($post) ) { // and it doesn't match the cookie -

    %2$s. Log out »'), get_option('siteurl') . '/wp-admin/profile.php', $user_identity, wp_logout_url(get_permalink())); ?>

    +

    %2$s. Log out »'), get_edit_user_link(), $user_identity, wp_logout_url(get_permalink())); ?>

    diff --git a/wp-includes/theme-compat/comments.php b/wp-includes/theme-compat/comments.php index 89a888c7..75a85ed4 100644 --- a/wp-includes/theme-compat/comments.php +++ b/wp-includes/theme-compat/comments.php @@ -69,7 +69,7 @@ _deprecated_file( sprintf( __( 'Theme without %1$s' ), basename(__FILE__) ), '3. -

    %2$s.'), get_option('siteurl') . '/wp-admin/profile.php', $user_identity); ?>

    +

    %2$s.'), get_edit_user_link(), $user_identity); ?>

    diff --git a/wp-includes/theme.php b/wp-includes/theme.php index f449ae50..d8c24197 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -106,6 +106,18 @@ function wp_get_theme( $stylesheet = null, $theme_root = null ) { return new WP_Theme( $stylesheet, $theme_root ); } +/** + * Clears the cache held by get_theme_roots() and WP_Theme. + * + * @since 3.5.0 + */ +function wp_clean_themes_cache() { + delete_site_transient('update_themes'); + search_theme_directories( true ); + foreach ( wp_get_themes( array( 'errors' => null ) ) as $theme ) + $theme->cache_delete(); +} + /** * Whether a child theme is in use. * @@ -638,15 +650,17 @@ function preview_theme_ob_filter_callback( $matches ) { } /** - * Switches current theme to new template and stylesheet names. + * Switches the theme. + * + * Accepts one argument: $stylesheet of the theme. It also accepts an additional function signature + * of two arguments: $template then $stylesheet. This is for backwards compatibility. * * @since 2.5.0 * @uses do_action() Calls 'switch_theme' action, passing the new theme. * - * @param string $template Template name - * @param string $stylesheet Stylesheet name. + * @param string $stylesheet Stylesheet name */ -function switch_theme( $template, $stylesheet ) { +function switch_theme( $stylesheet ) { global $wp_theme_directories, $sidebars_widgets; if ( is_array( $sidebars_widgets ) ) @@ -654,7 +668,13 @@ function switch_theme( $template, $stylesheet ) { $old_theme = wp_get_theme(); $new_theme = wp_get_theme( $stylesheet ); - $new_name = $new_theme->get('Name'); + + if ( func_num_args() > 1 ) { + $template = $stylesheet; + $stylesheet = func_get_arg( 1 ); + } else { + $template = $new_theme->get_template(); + } update_option( 'template', $template ); update_option( 'stylesheet', $stylesheet ); @@ -662,8 +682,13 @@ function switch_theme( $template, $stylesheet ) { if ( count( $wp_theme_directories ) > 1 ) { update_option( 'template_root', get_raw_theme_root( $template, true ) ); update_option( 'stylesheet_root', get_raw_theme_root( $stylesheet, true ) ); + } else { + delete_option( 'template_root' ); + delete_option( 'stylesheet_root' ); } + $new_name = $new_theme->get('Name'); + update_option( 'current_theme', $new_name ); if ( is_admin() && false === get_option( 'theme_mods_' . $stylesheet ) ) { @@ -694,17 +719,17 @@ function validate_current_theme() { return true; if ( get_template() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/index.php') ) { - switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + switch_theme( WP_DEFAULT_THEME ); return false; } if ( get_stylesheet() != WP_DEFAULT_THEME && !file_exists(get_template_directory() . '/style.css') ) { - switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + switch_theme( WP_DEFAULT_THEME ); return false; } if ( is_child_theme() && ! file_exists( get_stylesheet_directory() . '/style.css' ) ) { - switch_theme( WP_DEFAULT_THEME, WP_DEFAULT_THEME ); + switch_theme( WP_DEFAULT_THEME ); return false; } @@ -869,12 +894,7 @@ function get_header_image() { if ( is_random_header_image() ) $url = get_random_header_image(); - if ( is_ssl() ) - $url = str_replace( 'http://', 'https://', $url ); - else - $url = str_replace( 'https://', 'http://', $url ); - - return esc_url_raw( $url ); + return esc_url_raw( set_url_scheme( $url ) ); } /** @@ -1008,7 +1028,30 @@ function get_uploaded_header_images() { * @return object */ function get_custom_header() { - $data = is_random_header_image()? _get_random_header_data() : get_theme_mod( 'header_image_data' ); + global $_wp_default_headers; + + if ( is_random_header_image() ) { + $data = _get_random_header_data(); + } else { + $data = get_theme_mod( 'header_image_data' ); + if ( ! $data && current_theme_supports( 'custom-header', 'default-image' ) ) { + $directory_args = array( get_template_directory_uri(), get_stylesheet_directory_uri() ); + $data = array(); + $data['url'] = $data['thumbnail_url'] = vsprintf( get_theme_support( 'custom-header', 'default-image' ), $directory_args ); + if ( ! empty( $_wp_default_headers ) ) { + foreach ( (array) $_wp_default_headers as $default_header ) { + $url = vsprintf( $default_header['url'], $directory_args ); + if ( $data['url'] == $url ) { + $data = $default_header; + $data['url'] = $url; + $data['thumbnail_url'] = vsprintf( $data['thumbnail_url'], $directory_args ); + break; + } + } + } + } + } + $default = array( 'url' => '', 'thumbnail_url' => '', @@ -1103,7 +1146,7 @@ function background_color() { */ function _custom_background_cb() { // $background is the saved custom image, or the default image. - $background = get_background_image(); + $background = set_url_scheme( get_background_image() ); // $color is the saved custom color. // A default has to be specified in style.css. It will not be printed here. @@ -1446,6 +1489,8 @@ function _remove_theme_support( $feature ) { switch ( $feature ) { case 'custom-header' : + if ( false === did_action( 'wp_loaded', '_custom_header_background_just_in_time' ) ) + break; $support = get_theme_support( 'custom-header' ); if ( $support[0]['wp-head-callback'] ) remove_action( 'wp_head', $support[0]['wp-head-callback'] ); @@ -1454,6 +1499,8 @@ function _remove_theme_support( $feature ) { break; case 'custom-background' : + if ( false === did_action( 'wp_loaded', '_custom_header_background_just_in_time' ) ) + break; $support = get_theme_support( 'custom-background' ); remove_action( 'wp_head', $support[0]['wp-head-callback'] ); remove_action( 'admin_menu', array( $GLOBALS['custom_background'], 'init' ) ); @@ -1669,7 +1716,7 @@ function wp_customize_support_script() { request = true; - b[c] = b[c].replace( rcs, '' ); + b[c] = b[c].replace( rcs, ' ' ); b[c] += ( window.postMessage && request ? ' ' : ' no-' ) + cs; }()); diff --git a/wp-includes/update.php b/wp-includes/update.php index 34573478..b6205063 100644 --- a/wp-includes/update.php +++ b/wp-includes/update.php @@ -155,14 +155,14 @@ function wp_update_plugins() { // Check for update on a different schedule, depending on the page. switch ( current_filter() ) { case 'load-update-core.php' : - $timeout = 60; // 1 min + $timeout = MINUTE_IN_SECONDS; break; case 'load-plugins.php' : case 'load-update.php' : - $timeout = 3600; // 1 hour + $timeout = HOUR_IN_SECONDS; break; default : - $timeout = 43200; // 12 hours + $timeout = 12 * HOUR_IN_SECONDS; } $time_not_changed = isset( $current->last_checked ) && $timeout > ( time() - $current->last_checked ); @@ -264,14 +264,14 @@ function wp_update_themes() { // Check for update on a different schedule, depending on the page. switch ( current_filter() ) { case 'load-update-core.php' : - $timeout = 60; // 1 min + $timeout = MINUTE_IN_SECONDS; break; case 'load-themes.php' : case 'load-update.php' : - $timeout = 3600; // 1 hour + $timeout = HOUR_IN_SECONDS; break; default : - $timeout = 43200; // 12 hours + $timeout = 12 * HOUR_IN_SECONDS; } $time_not_changed = isset( $last_update->last_checked ) && $timeout > ( time( ) - $last_update->last_checked ); @@ -279,8 +279,6 @@ function wp_update_themes() { if ( $time_not_changed ) { $theme_changed = false; foreach ( $checked as $slug => $v ) { - $update_request->checked[ $slug ] = $v; - if ( !isset( $last_update->checked[ $slug ] ) || strval($last_update->checked[ $slug ]) !== strval($v) ) $theme_changed = true; } @@ -354,17 +352,17 @@ function wp_get_update_data() { } $counts['total'] = $counts['plugins'] + $counts['themes'] + $counts['wordpress']; - $update_title = array(); + $titles = array(); if ( $counts['wordpress'] ) - $update_title[] = sprintf(__('%d WordPress Update'), $counts['wordpress']); + $titles['wordpress'] = sprintf( __( '%d WordPress Update'), $counts['wordpress'] ); if ( $counts['plugins'] ) - $update_title[] = sprintf(_n('%d Plugin Update', '%d Plugin Updates', $counts['plugins']), $counts['plugins']); + $titles['plugins'] = sprintf( _n( '%d Plugin Update', '%d Plugin Updates', $counts['plugins'] ), $counts['plugins'] ); if ( $counts['themes'] ) - $update_title[] = sprintf(_n('%d Theme Update', '%d Theme Updates', $counts['themes']), $counts['themes']); + $titles['themes'] = sprintf( _n( '%d Theme Update', '%d Theme Updates', $counts['themes'] ), $counts['themes'] ); - $update_title = ! empty( $update_title ) ? esc_attr( implode( ', ', $update_title ) ) : ''; + $update_title = $titles ? esc_attr( implode( ', ', $titles ) ) : ''; - return array( 'counts' => $counts, 'title' => $update_title ); + return apply_filters( 'wp_get_update_data', array( 'counts' => $counts, 'title' => $update_title ), $titles ); } function _maybe_update_core() { @@ -373,7 +371,7 @@ function _maybe_update_core() { $current = get_site_transient( 'update_core' ); if ( isset( $current->last_checked ) && - 43200 > ( time() - $current->last_checked ) && + 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) && isset( $current->version_checked ) && $current->version_checked == $wp_version ) return; @@ -392,7 +390,7 @@ function _maybe_update_core() { */ function _maybe_update_plugins() { $current = get_site_transient( 'update_plugins' ); - if ( isset( $current->last_checked ) && 43200 > ( time() - $current->last_checked ) ) + if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time() - $current->last_checked ) ) return; wp_update_plugins(); } @@ -408,7 +406,7 @@ function _maybe_update_plugins() { */ function _maybe_update_themes( ) { $current = get_site_transient( 'update_themes' ); - if ( isset( $current->last_checked ) && 43200 > ( time( ) - $current->last_checked ) ) + if ( isset( $current->last_checked ) && 12 * HOUR_IN_SECONDS > ( time( ) - $current->last_checked ) ) return; wp_update_themes(); diff --git a/wp-includes/user.php b/wp-includes/user.php index 6b342c85..7bdc37cc 100644 --- a/wp-includes/user.php +++ b/wp-includes/user.php @@ -84,33 +84,32 @@ function wp_authenticate_username_password($user, $username, $password) { return $error; } - $userdata = get_user_by('login', $username); + $user = get_user_by('login', $username); - if ( !$userdata ) + if ( !$user ) return new WP_Error('invalid_username', sprintf(__('ERROR: Invalid username. Lost your password?'), wp_lostpassword_url())); if ( is_multisite() ) { // Is user marked as spam? - if ( 1 == $userdata->spam) + if ( 1 == $user->spam) return new WP_Error('invalid_username', __('ERROR: Your account has been marked as a spammer.')); // Is a user's blog marked as spam? - if ( !is_super_admin( $userdata->ID ) && isset($userdata->primary_blog) ) { - $details = get_blog_details( $userdata->primary_blog ); + if ( !is_super_admin( $user->ID ) && isset($user->primary_blog) ) { + $details = get_blog_details( $user->primary_blog ); if ( is_object( $details ) && $details->spam == 1 ) return new WP_Error('blog_suspended', __('Site Suspended.')); } } - $userdata = apply_filters('wp_authenticate_user', $userdata, $password); - if ( is_wp_error($userdata) ) - return $userdata; + $user = apply_filters('wp_authenticate_user', $user, $password); + if ( is_wp_error($user) ) + return $user; - if ( !wp_check_password($password, $userdata->user_pass, $userdata->ID) ) + if ( !wp_check_password($password, $user->user_pass, $user->ID) ) return new WP_Error( 'incorrect_password', sprintf( __( 'ERROR: The password you entered for the username %1$s is incorrect. Lost your password?' ), $username, wp_lostpassword_url() ) ); - $user = new WP_User($userdata->ID); return $user; } @@ -166,10 +165,11 @@ function count_user_posts($userid) { * @since 3.0.0 * * @param array $users Array of user IDs. - * @param string|array $post_type Optional. Post type to check. Defaults to post. + * @param string $post_type Optional. Post type to check. Defaults to post. + * @param bool $public_only Optional. Only return counts for public posts. Defaults to false. * @return array Amount of posts each user has written. */ -function count_many_users_posts( $users, $post_type = 'post' ) { +function count_many_users_posts( $users, $post_type = 'post', $public_only = false ) { global $wpdb; $count = array(); @@ -177,7 +177,7 @@ function count_many_users_posts( $users, $post_type = 'post' ) { return $count; $userlist = implode( ',', array_map( 'absint', $users ) ); - $where = get_posts_by_author_sql( $post_type ); + $where = get_posts_by_author_sql( $post_type, true, null, $public_only ); $result = $wpdb->get_results( "SELECT post_author, COUNT(*) FROM $wpdb->posts $where AND post_author IN ($userlist) GROUP BY post_author", ARRAY_N ); foreach ( $result as $row ) { @@ -192,24 +192,6 @@ function count_many_users_posts( $users, $post_type = 'post' ) { return $count; } -/** - * Check that the user login name and password is correct. - * - * @since 0.71 - * @todo xmlrpc only. Maybe move to xmlrpc.php. - * - * @param string $user_login User name. - * @param string $user_pass User password. - * @return bool False if does not authenticate, true if username and password authenticates. - */ -function user_pass_ok($user_login, $user_pass) { - $user = wp_authenticate($user_login, $user_pass); - if ( is_wp_error($user) ) - return false; - - return true; -} - // // User option functions // @@ -255,11 +237,9 @@ function get_user_option( $option, $user = 0, $deprecated = '' ) { _deprecated_argument( __FUNCTION__, '3.0' ); if ( empty( $user ) ) - $user = wp_get_current_user(); - else - $user = new WP_User( $user ); + $user = get_current_user_id(); - if ( ! $user->exists() ) + if ( ! $user = get_userdata( $user ) ) return false; if ( $user->has_prop( $wpdb->prefix . $option ) ) // Blog specific @@ -334,6 +314,15 @@ function delete_user_option( $user_id, $option_name, $global = false ) { */ class WP_User_Query { + /** + * Query vars, after parsing + * + * @since 3.5.0 + * @access public + * @var array + */ + var $query_vars = array(); + /** * List of found user ids * @@ -402,7 +391,7 @@ class WP_User_Query { function prepare_query() { global $wpdb; - $qv = &$this->query_vars; + $qv =& $this->query_vars; if ( is_array( $qv['fields'] ) ) { $qv['fields'] = array_unique( $qv['fields'] ); @@ -417,7 +406,7 @@ class WP_User_Query { $this->query_fields = "$wpdb->users.ID"; } - if ( $this->query_vars['count_total'] ) + if ( $qv['count_total'] ) $this->query_fields = 'SQL_CALC_FOUND_ROWS ' . $this->query_fields; $this->query_from = "FROM $wpdb->users"; @@ -549,29 +538,64 @@ class WP_User_Query { function query() { global $wpdb; - if ( is_array( $this->query_vars['fields'] ) || 'all' == $this->query_vars['fields'] ) { + $qv =& $this->query_vars; + + if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) { $this->results = $wpdb->get_results("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); } else { $this->results = $wpdb->get_col("SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit"); } - if ( $this->query_vars['count_total'] ) + if ( $qv['count_total'] ) $this->total_users = $wpdb->get_var( apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()' ) ); if ( !$this->results ) return; - if ( 'all_with_meta' == $this->query_vars['fields'] ) { + if ( 'all_with_meta' == $qv['fields'] ) { cache_users( $this->results ); $r = array(); foreach ( $this->results as $userid ) - $r[ $userid ] = new WP_User( $userid, '', $this->query_vars['blog_id'] ); + $r[ $userid ] = new WP_User( $userid, '', $qv['blog_id'] ); $this->results = $r; + } elseif ( 'all' == $qv['fields'] ) { + foreach ( $this->results as $key => $user ) { + $this->results[ $key ] = new WP_User( $user ); + } } } + /** + * Retrieve query variable. + * + * @since 3.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @return mixed + */ + function get( $query_var ) { + if ( isset( $this->query_vars[$query_var] ) ) + return $this->query_vars[$query_var]; + + return null; + } + + /** + * Set query variable. + * + * @since 3.5.0 + * @access public + * + * @param string $query_var Query variable key. + * @param mixed $value Query variable value. + */ + function set( $query_var, $value ) { + $this->query_vars[$query_var] = $value; + } + /* * Used internally to generate an SQL string for searching across multiple columns * @@ -676,6 +700,9 @@ function get_blogs_of_user( $user_id, $all = false ) { $blogs[ $blog_id ]->path = ''; $blogs[ $blog_id ]->site_id = 1; $blogs[ $blog_id ]->siteurl = get_option('siteurl'); + $blogs[ $blog_id ]->archived = 0; + $blogs[ $blog_id ]->spam = 0; + $blogs[ $blog_id ]->deleted = 0; return $blogs; } @@ -691,6 +718,9 @@ function get_blogs_of_user( $user_id, $all = false ) { 'path' => $blog->path, 'site_id' => $blog->site_id, 'siteurl' => $blog->siteurl, + 'archived' => 0, + 'spam' => 0, + 'deleted' => 0 ); } unset( $keys[ $wpdb->base_prefix . 'capabilities' ] ); @@ -717,6 +747,9 @@ function get_blogs_of_user( $user_id, $all = false ) { 'path' => $blog->path, 'site_id' => $blog->site_id, 'siteurl' => $blog->siteurl, + 'archived' => 0, + 'spam' => 0, + 'deleted' => 0 ); } } @@ -920,33 +953,31 @@ function count_users($strategy = 'time') { * @global int $user_ID The ID of the user * @global string $user_email The email address of the user * @global string $user_url The url in the user's profile - * @global string $user_pass_md5 MD5 of the user's password * @global string $user_identity The display name of the user * * @param int $for_user_id Optional. User ID to set up global data. */ function setup_userdata($for_user_id = '') { - global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_pass_md5, $user_identity; + global $user_login, $userdata, $user_level, $user_ID, $user_email, $user_url, $user_identity; if ( '' == $for_user_id ) - $user = wp_get_current_user(); - else - $user = new WP_User($for_user_id); - - $userdata = null; - $user_ID = (int) $user->ID; - $user_level = (int) isset($user->user_level) ? $user->user_level : 0; - - if ( ! $user->exists() ) { - $user_login = $user_email = $user_url = $user_pass_md5 = $user_identity = ''; + $for_user_id = get_current_user_id(); + $user = get_userdata( $for_user_id ); + + if ( ! $user ) { + $user_ID = 0; + $user_level = 0; + $userdata = null; + $user_login = $user_email = $user_url = $user_identity = ''; return; } + $user_ID = (int) $user->ID; + $user_level = (int) $user->user_level; $userdata = $user; $user_login = $user->user_login; $user_email = $user->user_email; $user_url = $user->user_url; - $user_pass_md5 = md5( $user->user_pass ); $user_identity = $user->display_name; } @@ -1221,7 +1252,7 @@ function validate_username( $username ) { * 'ID' - An integer that will be used for updating an existing user. * 'user_pass' - A string that contains the plain text password for the user. * 'user_login' - A string that contains the user's username for logging in. - * 'user_nicename' - A string that contains a nicer looking name for the user. + * 'user_nicename' - A string that contains a URL-friendly name for the user. * The default is the user's username. * 'user_url' - A string containing the user's URL for the user's web site. * 'user_email' - A string containing the user's email address. @@ -1245,13 +1276,18 @@ function validate_username( $username ) { * @uses do_action() Calls 'profile_update' hook when updating giving the user's ID * @uses do_action() Calls 'user_register' hook when creating a new user giving the user's ID * - * @param array $userdata An array of user data. + * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. * @return int|WP_Error The newly created user's ID or a WP_Error object if the user could not be created. */ -function wp_insert_user($userdata) { +function wp_insert_user( $userdata ) { global $wpdb; - extract($userdata, EXTR_SKIP); + if ( is_a( $userdata, 'stdClass' ) ) + $userdata = get_object_vars( $userdata ); + elseif ( is_a( $userdata, 'WP_User' ) ) + $userdata = $userdata->to_array(); + + extract( $userdata, EXTR_SKIP ); // Are we updating or creating? if ( !empty($ID) ) { @@ -1274,7 +1310,7 @@ function wp_insert_user($userdata) { return new WP_Error('empty_user_login', __('Cannot create a user with an empty login name.') ); if ( !$update && username_exists( $user_login ) ) - return new WP_Error('existing_user_login', __('This username is already registered.') ); + return new WP_Error( 'existing_user_login', __( 'Sorry, that username already exists!' ) ); if ( empty($user_nicename) ) $user_nicename = sanitize_title( $user_login ); @@ -1289,11 +1325,7 @@ function wp_insert_user($userdata) { $user_email = apply_filters('pre_user_email', $user_email); if ( !$update && ! defined( 'WP_IMPORTING' ) && email_exists($user_email) ) - return new WP_Error('existing_user_email', __('This email address is already registered.') ); - - if ( empty($display_name) ) - $display_name = $user_login; - $display_name = apply_filters('pre_user_display_name', $display_name); + return new WP_Error( 'existing_user_email', __( 'Sorry, that email address is already used!' ) ); if ( empty($nickname) ) $nickname = $user_login; @@ -1307,6 +1339,21 @@ function wp_insert_user($userdata) { $last_name = ''; $last_name = apply_filters('pre_user_last_name', $last_name); + if ( empty( $display_name ) ) { + if ( $update ) + $display_name = $user_login; + elseif ( $first_name && $last_name ) + /* translators: 1: first name, 2: last name */ + $display_name = sprintf( _x( '%1$s %2$s', 'Display name based on first name and last name' ), $first_name, $last_name ); + elseif ( $first_name ) + $display_name = $first_name; + elseif ( $last_name ) + $display_name = $last_name; + else + $display_name = $user_login; + } + $display_name = apply_filters( 'pre_user_display_name', $display_name ); + if ( empty($description) ) $description = ''; $description = apply_filters('pre_user_description', $description); @@ -1392,16 +1439,21 @@ function wp_insert_user($userdata) { * @see wp_insert_user() For what fields can be set in $userdata * @uses wp_insert_user() Used to update existing user or add new one if user doesn't exist already * - * @param array $userdata An array of user data. - * @return int The updated user's ID. + * @param mixed $userdata An array of user data or a user object of type stdClass or WP_User. + * @return int|WP_Error The updated user's ID or a WP_Error object if the user could not be updated. */ function wp_update_user($userdata) { + if ( is_a( $userdata, 'stdClass' ) ) + $userdata = get_object_vars( $userdata ); + elseif ( is_a( $userdata, 'WP_User' ) ) + $userdata = $userdata->to_array(); + $ID = (int) $userdata['ID']; // First, get all of the original fields $user_obj = get_userdata( $ID ); - $user = get_object_vars( $user_obj->data ); + $user = $user_obj->to_array(); // Add additional custom fields foreach ( _get_additional_user_keys( $user_obj ) as $key ) { @@ -1461,10 +1513,10 @@ function wp_create_user($username, $password, $email = '') { /** * Return a list of meta keys that wp_insert_user() is supposed to set. * - * @access private * @since 3.3.0 + * @access private * - * @param object $user WP_User instance + * @param object $user WP_User instance. * @return array */ function _get_additional_user_keys( $user ) { @@ -1473,12 +1525,12 @@ function _get_additional_user_keys( $user ) { } /** - * Set up the default contact methods + * Set up the default contact methods. * + * @since 2.9.0 * @access private - * @since * - * @param object $user User data object (optional) + * @param object $user User data object (optional). * @return array $user_contactmethods Array of contact methods and their labels. */ function _wp_get_user_contactmethods( $user = null ) { diff --git a/wp-includes/vars.php b/wp-includes/vars.php index 7585793d..23e0e580 100644 --- a/wp-includes/vars.php +++ b/wp-includes/vars.php @@ -116,7 +116,8 @@ function wp_is_mobile() { || strpos($_SERVER['HTTP_USER_AGENT'], 'Silk/') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Kindle') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'BlackBerry') !== false - || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false ) { + || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mini') !== false + || strpos($_SERVER['HTTP_USER_AGENT'], 'Opera Mobi') !== false ) { $is_mobile = true; } else { $is_mobile = false; diff --git a/wp-includes/version.php b/wp-includes/version.php index c7c9e8c9..8e751886 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,28 +4,21 @@ * * @global string $wp_version */ -$wp_version = '3.4.2'; +$wp_version = '3.5'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * * @global int $wp_db_version */ -$wp_db_version = 21707; +$wp_db_version = 22441; /** * Holds the TinyMCE version * * @global string $tinymce_version */ -$tinymce_version = '349-21274'; - -/** - * Holds the cache manifest version - * - * @global string $manifest_version - */ -$manifest_version = '20111113'; +$tinymce_version = '358-23156'; /** * Holds the required PHP version diff --git a/wp-includes/widgets.php b/wp-includes/widgets.php index 765bbffc..2277fad1 100644 --- a/wp-includes/widgets.php +++ b/wp-includes/widgets.php @@ -152,15 +152,15 @@ class WP_Widget { } function _get_display_callback() { - return array(&$this, 'display_callback'); + return array($this, 'display_callback'); } function _get_update_callback() { - return array(&$this, 'update_callback'); + return array($this, 'update_callback'); } function _get_form_callback() { - return array(&$this, 'form_callback'); + return array($this, 'form_callback'); } /** Generate the actual widget content. @@ -317,7 +317,7 @@ class WP_Widget_Factory { var $widgets = array(); function WP_Widget_Factory() { - add_action( 'widgets_init', array( &$this, '_register_widgets' ), 100 ); + add_action( 'widgets_init', array( $this, '_register_widgets' ), 100 ); } function register($widget_class) { diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php index f4187459..391cfa4d 100644 --- a/wp-includes/wp-db.php +++ b/wp-includes/wp-db.php @@ -88,7 +88,7 @@ class wpdb { /** * Count of rows returned by previous query * - * @since 1.2.0 + * @since 0.71 * @access private * @var int */ @@ -113,9 +113,9 @@ class wpdb { var $insert_id = 0; /** - * Saved result of the last query made + * Last query made * - * @since 1.2.0 + * @since 0.71 * @access private * @var array */ @@ -124,20 +124,29 @@ class wpdb { /** * Results of the last query made * - * @since 1.0.0 + * @since 0.71 * @access private * @var array|null */ var $last_result; + /** + * MySQL result, which is either a resource or boolean. + * + * @since 0.71 + * @access protected + * @var mixed + */ + protected $result; + /** * Saved info on the table column * - * @since 1.2.0 - * @access private + * @since 0.71 + * @access protected * @var array */ - var $col_info; + protected $col_info; /** * Saved queries that were executed @@ -155,7 +164,7 @@ class wpdb { * in a single database. The second reason is for possible * security precautions. * - * @since 0.71 + * @since 2.5.0 * @access private * @var string */ @@ -164,7 +173,7 @@ class wpdb { /** * Whether the database queries are ready to start executing. * - * @since 2.5.0 + * @since 2.3.2 * @access private * @var bool */ @@ -445,10 +454,46 @@ class wpdb { * Database Username * * @since 2.9.0 - * @access private + * @access protected + * @var string + */ + protected $dbuser; + + /** + * Database Password + * + * @since 3.1.0 + * @access protected * @var string */ - var $dbuser; + protected $dbpassword; + + /** + * Database Name + * + * @since 3.1.0 + * @access protected + * @var string + */ + protected $dbname; + + /** + * Database Host + * + * @since 3.1.0 + * @access protected + * @var string + */ + protected $dbhost; + + /** + * Database Handle + * + * @since 0.71 + * @access protected + * @var string + */ + protected $dbh; /** * A textual description of the last query/get_row/get_var call @@ -489,7 +534,7 @@ class wpdb { * @param string $dbhost MySQL database host */ function __construct( $dbuser, $dbpassword, $dbname, $dbhost ) { - register_shutdown_function( array( &$this, '__destruct' ) ); + register_shutdown_function( array( $this, '__destruct' ) ); if ( WP_DEBUG ) $this->show_errors(); @@ -515,6 +560,57 @@ class wpdb { return true; } + /** + * PHP5 style magic getter, used to lazy-load expensive data. + * + * @since 3.5.0 + * + * @param string $name The private member to get, and optionally process + * @return mixed The private member + */ + function __get( $name ) { + if ( 'col_info' == $name ) + $this->load_col_info(); + + return $this->$name; + } + + /** + * Magic function, for backwards compatibility + * + * @since 3.5.0 + * + * @param string $name The private member to set + * @param mixed $value The value to set + */ + function __set( $name, $value ) { + $this->$name = $value; + } + + /** + * Magic function, for backwards compatibility + * + * @since 3.5.0 + * + * @param string $name The private member to check + * + * @return bool If the member is set or not + */ + function __isset( $name ) { + return isset( $this->$name ); + } + + /** + * Magic function, for backwards compatibility + * + * @since 3.5.0 + * + * @param string $name The private member to unset + */ + function __unset( $name ) { + unset( $this->$name ); + } + /** * Set $this->charset and $this->collate * @@ -850,7 +946,8 @@ class wpdb { * @return void */ function escape_by_ref( &$string ) { - $string = $this->_real_escape( $string ); + if ( ! is_float( $string ) ) + $string = $this->_real_escape( $string ); } /** @@ -890,7 +987,7 @@ class wpdb { * @return null|false|string Sanitized query string, null if there is no query, false if there is an error and string * if there was something to prepare */ - function prepare( $query = null ) { // ( $query, *$args ) + function prepare( $query, $args ) { if ( is_null( $query ) ) return; @@ -901,8 +998,9 @@ class wpdb { $args = $args[0]; $query = str_replace( "'%s'", '%s', $query ); // in case someone mistakenly already singlequoted it $query = str_replace( '"%s"', '%s', $query ); // doublequote unquoting + $query = preg_replace( '|(?last_query ); - if ( function_exists( 'error_log' ) - && ( $log_file = @ini_get( 'error_log' ) ) - && ( 'syslog' == $log_file || @is_writable( $log_file ) ) - ) - @error_log( $error_str ); + error_log( $error_str ); // Are we showing errors? if ( ! $this->show_errors ) @@ -1023,6 +1117,9 @@ class wpdb { $this->last_result = array(); $this->col_info = null; $this->last_query = null; + + if ( is_resource( $this->result ) ) + mysql_free_result( $this->result ); } /** @@ -1034,10 +1131,13 @@ class wpdb { $this->is_mysql = true; + $new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true; + $client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0; + if ( WP_DEBUG ) { - $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true ); + $this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags ); } else { - $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, true ); + $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags ); } if ( !$this->dbh ) { @@ -1104,30 +1204,23 @@ class wpdb { return false; } - if ( preg_match( '/^\s*(create|alter|truncate|drop) /i', $query ) ) { + if ( preg_match( '/^\s*(create|alter|truncate|drop)\s/i', $query ) ) { $return_val = $this->result; - } elseif ( preg_match( '/^\s*(insert|delete|update|replace) /i', $query ) ) { + } elseif ( preg_match( '/^\s*(insert|delete|update|replace)\s/i', $query ) ) { $this->rows_affected = mysql_affected_rows( $this->dbh ); // Take note of the insert_id - if ( preg_match( '/^\s*(insert|replace) /i', $query ) ) { + if ( preg_match( '/^\s*(insert|replace)\s/i', $query ) ) { $this->insert_id = mysql_insert_id($this->dbh); } // Return number of rows affected $return_val = $this->rows_affected; } else { - $i = 0; - while ( $i < @mysql_num_fields( $this->result ) ) { - $this->col_info[$i] = @mysql_fetch_field( $this->result ); - $i++; - } $num_rows = 0; while ( $row = @mysql_fetch_object( $this->result ) ) { $this->last_result[$num_rows] = $row; $num_rows++; } - @mysql_free_result( $this->result ); - // Log number of rows the query returned // and return number of rows selected $this->num_rows = $num_rows; @@ -1455,6 +1548,22 @@ class wpdb { return null; } + /** + * Load the column metadata from the last query. + * + * @since 3.5.0 + * + * @access protected + */ + protected function load_col_info() { + if ( $this->col_info ) + return; + + for ( $i = 0; $i < @mysql_num_fields( $this->result ); $i++ ) { + $this->col_info[ $i ] = @mysql_fetch_field( $this->result, $i ); + } + } + /** * Retrieve column metadata from the last query. * @@ -1465,6 +1574,8 @@ class wpdb { * @return mixed Column Results */ function get_col_info( $info_type = 'name', $col_offset = -1 ) { + $this->load_col_info(); + if ( $this->col_info ) { if ( $col_offset == -1 ) { $i = 0; @@ -1506,7 +1617,7 @@ class wpdb { /** * Wraps errors in a nice header and footer and dies. * - * Will not die if wpdb::$show_errors is true + * Will not die if wpdb::$show_errors is false. * * @since 1.5.0 * @@ -1547,13 +1658,34 @@ class wpdb { * Called when WordPress is generating the table scheme. * * @since 2.5.0 + * @deprecated 3.5.0 + * @deprecated Use wpdb::has_cap( 'collation' ) * * @return bool True if collation is supported, false if version does not */ function supports_collation() { + _deprecated_function( __FUNCTION__, '3.5', 'wpdb::has_cap( \'collation\' )' ); return $this->has_cap( 'collation' ); } + /** + * The database character collate. + * + * @since 3.5.0 + * + * @return string The database character collate. + */ + public function get_charset_collate() { + $charset_collate = ''; + + if ( ! empty( $this->charset ) ) + $charset_collate = "DEFAULT CHARACTER SET $this->charset"; + if ( ! empty( $this->collate ) ) + $charset_collate .= " COLLATE $this->collate"; + + return $charset_collate; + } + /** * Determine if a database supports a particular feature * diff --git a/wp-includes/wp-diff.php b/wp-includes/wp-diff.php index 052bf133..65dd0074 100644 --- a/wp-includes/wp-diff.php +++ b/wp-includes/wp-diff.php @@ -422,7 +422,7 @@ class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer { $chars2 = count_chars($string2); // L1-norm of difference vector. - $difference = array_sum( array_map( array(&$this, 'difference'), $chars1, $chars2 ) ); + $difference = array_sum( array_map( array($this, 'difference'), $chars1, $chars2 ) ); // $string1 has zero length? Odd. Give huge penalty by not dividing. if ( !$string1 ) diff --git a/wp-load.php b/wp-load.php index 1372688f..983558ab 100644 --- a/wp-load.php +++ b/wp-load.php @@ -57,7 +57,7 @@ if ( file_exists( ABSPATH . 'wp-config.php') ) { $die = __( "There doesn't seem to be a wp-config.php file. I need this before we can get started." ) . '

    '; $die .= '

    ' . __( "Need more help? We got it." ) . '

    '; $die .= '

    ' . __( "You can create a wp-config.php file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file." ) . '

    '; - $die .= '

    ' . __( "Create a Configuration File" ) . ''; + $die .= '

    ' . __( "Create a Configuration File" ) . ''; wp_die( $die, __( 'WordPress › Error' ) ); } diff --git a/wp-login.php b/wp-login.php index 50088db9..239e4a9c 100644 --- a/wp-login.php +++ b/wp-login.php @@ -12,12 +12,12 @@ require( dirname(__FILE__) . '/wp-load.php' ); // Redirect to https login if forced to use SSL -if ( force_ssl_admin() && !is_ssl() ) { +if ( force_ssl_admin() && ! is_ssl() ) { if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) { - wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); + wp_redirect( set_url_scheme( $_SERVER['REQUEST_URI'], 'https' ) ); exit(); } else { - wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); + wp_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); exit(); } } @@ -39,7 +39,7 @@ if ( force_ssl_admin() && !is_ssl() ) { * @param WP_Error $wp_error Optional. WordPress Error Object */ function login_header($title = 'Log In', $message = '', $wp_error = '') { - global $error, $interim_login, $current_site; + global $error, $interim_login, $current_site, $action; // Don't index any of these forms add_action( 'login_head', 'wp_no_robots' ); @@ -86,9 +86,15 @@ function login_header($title = 'Log In', $message = '', $wp_error = '') { if ( $interim_login ) $login_header_url = '#'; + $classes = array( 'login-action-' . $action, 'wp-core-ui' ); + if ( wp_is_mobile() ) + $classes[] = 'mobile'; + if ( is_rtl() ) + $classes[] = 'rtl'; + $classes = apply_filters( 'login_body_class', $classes, $action ); ?> - +

    add( 'invalid_username', __( 'ERROR: This username is invalid because it uses illegal characters. Please enter a valid username.' ) ); $sanitized_user_login = ''; } elseif ( username_exists( $sanitized_user_login ) ) { - $errors->add( 'username_exists', __( 'ERROR: This username is already registered, please choose another one.' ) ); + $errors->add( 'username_exists', __( 'ERROR: This username is already registered. Please choose another one.' ) ); } // Check the e-mail address @@ -361,13 +367,13 @@ nocache_headers(); header('Content-Type: '.get_bloginfo('html_type').'; charset='.get_bloginfo('charset')); -if ( defined('RELOCATE') ) { // Move flag is set +if ( defined( 'RELOCATE' ) && RELOCATE ) { // Move flag is set if ( isset( $_SERVER['PATH_INFO'] ) && ($_SERVER['PATH_INFO'] != $_SERVER['PHP_SELF']) ) $_SERVER['PHP_SELF'] = str_replace( $_SERVER['PATH_INFO'], '', $_SERVER['PHP_SELF'] ); - $schema = is_ssl() ? 'https://' : 'http://'; - if ( dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) != get_option('siteurl') ) - update_option('siteurl', dirname($schema . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']) ); + $url = dirname( set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] ) ); + if ( $url != get_option( 'siteurl' ) ) + update_option( 'siteurl', $url ); } //Set a cookie now to see if they are supported by the browser. @@ -390,7 +396,7 @@ case 'postpass' : } // 10 days - setcookie( 'wp-postpass_' . COOKIEHASH, $wp_hasher->HashPassword( stripslashes( $_POST['post_password'] ) ), time() + 864000, COOKIEPATH ); + setcookie( 'wp-postpass_' . COOKIEHASH, $wp_hasher->HashPassword( stripslashes( $_POST['post_password'] ) ), time() + 10 * DAY_IN_SECONDS, COOKIEPATH ); wp_safe_redirect( wp_get_referer() ); exit(); @@ -432,11 +438,11 @@ case 'retrievepassword' :

    +

    -

    +

    ' . __( 'Your password has been reset.' ) . ' ' . __( 'Log in' ) . '

    ' ); login_footer(); @@ -492,7 +501,7 @@ case 'rp' :


    -

    +

    +

    +


    -

    +

    +

    +

    -

    +

    - + diff --git a/wp-mail.php b/wp-mail.php index 7fc3967b..5685b3ac 100644 --- a/wp-mail.php +++ b/wp-mail.php @@ -30,7 +30,7 @@ if ( $last_checked ) set_transient('mailserver_last_checked', true, WP_MAIL_INTERVAL); -$time_difference = get_option('gmt_offset') * 3600; +$time_difference = get_option('gmt_offset') * HOUR_IN_SECONDS; $phone_delim = '::'; diff --git a/wp-settings.php b/wp-settings.php index cb950184..65485a84 100644 --- a/wp-settings.php +++ b/wp-settings.php @@ -32,16 +32,12 @@ wp_check_php_mysql_versions(); @ini_set( 'magic_quotes_runtime', 0 ); @ini_set( 'magic_quotes_sybase', 0 ); -// Set default timezone in PHP 5. -if ( function_exists( 'date_default_timezone_set' ) ) - date_default_timezone_set( 'UTC' ); +// WordPress calculates offsets from UTC. +date_default_timezone_set( 'UTC' ); // Turn register_globals off. wp_unregister_GLOBALS(); -// Ensure these global variables do not exist so they do not interfere with WordPress. -unset( $wp_filter, $cache_lastcommentmodified ); - // Standardize $_SERVER variables across setups. wp_fix_server_vars(); @@ -138,6 +134,7 @@ require( ABSPATH . WPINC . '/taxonomy.php' ); require( ABSPATH . WPINC . '/update.php' ); require( ABSPATH . WPINC . '/canonical.php' ); require( ABSPATH . WPINC . '/shortcodes.php' ); +require( ABSPATH . WPINC . '/class-wp-embed.php' ); require( ABSPATH . WPINC . '/media.php' ); require( ABSPATH . WPINC . '/http.php' ); require( ABSPATH . WPINC . '/class-http.php' ); @@ -232,7 +229,7 @@ $wp_the_query = new WP_Query(); * @global object $wp_query * @since 1.5.0 */ -$wp_query =& $wp_the_query; +$wp_query = $wp_the_query; /** * Holds the WordPress Rewrite object for creating pretty URLs @@ -255,6 +252,13 @@ $wp = new WP(); */ $GLOBALS['wp_widget_factory'] = new WP_Widget_Factory(); +/** + * WordPress User Roles + * @global object $wp_roles + * @since 2.0.0 + */ +$GLOBALS['wp_roles'] = new WP_Roles(); + do_action( 'setup_theme' ); // Define the template related constants. diff --git a/wp-signup.php b/wp-signup.php index 2cd93c82..7d35d865 100644 --- a/wp-signup.php +++ b/wp-signup.php @@ -23,7 +23,7 @@ if ( !is_multisite() ) { } if ( !is_main_site() ) { - wp_redirect( network_home_url( 'wp-signup.php' ) ); + wp_redirect( network_site_url( 'wp-signup.php' ) ); die(); } @@ -390,11 +390,7 @@ $current_user = wp_get_current_user(); if ( $active_signup == 'none' ) { _e( 'Registration has been disabled.' ); } elseif ( $active_signup == 'blog' && !is_user_logged_in() ) { - if ( is_ssl() ) - $proto = 'https://'; - else - $proto = 'http://'; - $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode($proto . $_SERVER['HTTP_HOST'] . '/wp-signup.php' )); + $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode( network_site_url( 'wp-signup.php' ) ) ); echo sprintf( __( 'You must first log in, and then you can create a new site.' ), $login_url ); } else { $stage = isset( $_POST['stage'] ) ? $_POST['stage'] : 'default'; diff --git a/xmlrpc.php b/xmlrpc.php index 2d3822ca..1998e4a8 100644 --- a/xmlrpc.php +++ b/xmlrpc.php @@ -42,7 +42,7 @@ header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true); - + -- 2.45.0