From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- resources/src/es5-skip.js | 18 + resources/src/jquery.json-deprecate.js | 8 + resources/src/jquery.tipsy/images/tipsy.png | Bin 0 -> 133 bytes resources/src/jquery.tipsy/jquery.tipsy.css | 73 + resources/src/jquery.tipsy/jquery.tipsy.js | 259 +++ .../images/jquery.arrowSteps.divider-ltr.png | Bin 0 -> 126 bytes .../images/jquery.arrowSteps.divider-rtl.png | Bin 0 -> 127 bytes .../jquery/images/jquery.arrowSteps.head-ltr.png | Bin 0 -> 303 bytes .../jquery/images/jquery.arrowSteps.head-rtl.png | Bin 0 -> 311 bytes .../jquery/images/jquery.arrowSteps.tail-ltr.png | Bin 0 -> 222 bytes .../jquery/images/jquery.arrowSteps.tail-rtl.png | Bin 0 -> 219 bytes resources/src/jquery/images/marker.png | Bin 0 -> 472 bytes resources/src/jquery/images/mask.png | Bin 0 -> 1795 bytes resources/src/jquery/images/sort_both.gif | Bin 0 -> 1184 bytes resources/src/jquery/images/sort_down.gif | Bin 0 -> 1174 bytes resources/src/jquery/images/sort_none.gif | Bin 0 -> 462 bytes resources/src/jquery/images/sort_up.gif | Bin 0 -> 1174 bytes resources/src/jquery/images/spinner-large.gif | Bin 0 -> 1788 bytes resources/src/jquery/images/spinner.gif | Bin 0 -> 1819 bytes resources/src/jquery/images/wheel.png | Bin 0 -> 11505 bytes resources/src/jquery/jquery.accessKeyLabel.js | 200 ++ resources/src/jquery/jquery.arrowSteps.css | 45 + resources/src/jquery/jquery.arrowSteps.js | 98 + resources/src/jquery/jquery.autoEllipsis.js | 168 ++ resources/src/jquery/jquery.badge.css | 36 + resources/src/jquery/jquery.badge.js | 88 + resources/src/jquery/jquery.byteLength.js | 40 + resources/src/jquery/jquery.byteLimit.js | 235 ++ resources/src/jquery/jquery.checkboxShiftClick.js | 43 + resources/src/jquery/jquery.client.js | 301 +++ resources/src/jquery/jquery.color.js | 55 + resources/src/jquery/jquery.colorUtil.js | 262 +++ resources/src/jquery/jquery.confirmable.css | 28 + resources/src/jquery/jquery.confirmable.js | 170 ++ .../src/jquery/jquery.confirmable.mediawiki.js | 14 + resources/src/jquery/jquery.expandableField.js | 140 ++ resources/src/jquery/jquery.farbtastic.css | 54 + resources/src/jquery/jquery.farbtastic.js | 286 +++ resources/src/jquery/jquery.footHovzer.css | 6 + resources/src/jquery/jquery.footHovzer.js | 66 + resources/src/jquery/jquery.getAttrs.js | 42 + resources/src/jquery/jquery.hidpi.js | 129 ++ resources/src/jquery/jquery.highlightText.js | 73 + resources/src/jquery/jquery.localize.js | 170 ++ resources/src/jquery/jquery.makeCollapsible.css | 27 + resources/src/jquery/jquery.makeCollapsible.js | 404 ++++ resources/src/jquery/jquery.mw-jump.js | 15 + resources/src/jquery/jquery.mwExtension.js | 122 + resources/src/jquery/jquery.placeholder.js | 229 ++ .../src/jquery/jquery.qunit.completenessTest.js | 305 +++ resources/src/jquery/jquery.spinner.css | 40 + resources/src/jquery/jquery.spinner.js | 112 + resources/src/jquery/jquery.suggestions.css | 76 + resources/src/jquery/jquery.suggestions.js | 684 ++++++ resources/src/jquery/jquery.tabIndex.js | 57 + resources/src/jquery/jquery.tablesorter.css | 17 + resources/src/jquery/jquery.tablesorter.js | 1161 ++++++++++ resources/src/jquery/jquery.textSelection.js | 572 +++++ resources/src/json-skip.js | 4 + .../mediawiki.action/images/green-checkmark.png | Bin 0 -> 681 bytes .../mediawiki.action/images/nextredirect-ltr.png | Bin 0 -> 121 bytes .../mediawiki.action/images/nextredirect-rtl.png | Bin 0 -> 121 bytes .../src/mediawiki.action/images/redirect-ltr.png | Bin 0 -> 128 bytes .../src/mediawiki.action/images/redirect-rtl.png | Bin 0 -> 132 bytes .../mediawiki.action.edit.collapsibleFooter.css | 17 + .../mediawiki.action.edit.collapsibleFooter.js | 54 + .../src/mediawiki.action/mediawiki.action.edit.css | 18 + .../mediawiki.action.edit.editWarning.js | 59 + .../src/mediawiki.action/mediawiki.action.edit.js | 217 ++ .../mediawiki.action.edit.preview.js | 165 ++ .../mediawiki.action.edit.styles.css | 44 + .../images/ar/button_bold.png | Bin 0 -> 533 bytes .../images/ar/button_headline.png | Bin 0 -> 484 bytes .../images/ar/button_italic.png | Bin 0 -> 532 bytes .../images/ar/button_link.png | Bin 0 -> 557 bytes .../images/ar/button_nowiki.png | Bin 0 -> 874 bytes .../images/be-tarask/button_bold.png | Bin 0 -> 550 bytes .../images/be-tarask/button_italic.png | Bin 0 -> 539 bytes .../images/be-tarask/button_link.png | Bin 0 -> 419 bytes .../images/de/button_bold.png | Bin 0 -> 255 bytes .../images/de/button_italic.png | Bin 0 -> 260 bytes .../images/en/button_bold.png | Bin 0 -> 250 bytes .../images/en/button_extlink.png | Bin 0 -> 435 bytes .../images/en/button_headline.png | Bin 0 -> 440 bytes .../images/en/button_hr.png | Bin 0 -> 200 bytes .../images/en/button_image.png | Bin 0 -> 483 bytes .../images/en/button_italic.png | Bin 0 -> 250 bytes .../images/en/button_link.png | Bin 0 -> 280 bytes .../images/en/button_media.png | Bin 0 -> 728 bytes .../images/en/button_nowiki.png | Bin 0 -> 322 bytes .../images/en/button_sig.png | Bin 0 -> 920 bytes .../images/fa/button_bold.png | Bin 0 -> 459 bytes .../images/fa/button_headline.png | Bin 0 -> 392 bytes .../images/fa/button_italic.png | Bin 0 -> 512 bytes .../images/fa/button_link.png | Bin 0 -> 485 bytes .../images/fa/button_nowiki.png | Bin 0 -> 874 bytes .../images/ksh/LICENSE | 7 + .../images/ksh/button_italic.png | Bin 0 -> 368 bytes .../images/ru/LICENSE | 17 + .../images/ru/button_bold.png | Bin 0 -> 254 bytes .../images/ru/button_italic.png | Bin 0 -> 423 bytes .../images/ru/button_link.png | Bin 0 -> 278 bytes .../mediawiki.action.edit.toolbar.less | 42 + .../mediawiki.action/mediawiki.action.history.css | 4 + .../mediawiki.action.history.diff.css | 96 + .../mediawiki.action/mediawiki.action.history.js | 111 + .../mediawiki.action.view.dblClickEdit.js | 12 + .../mediawiki.action.view.metadata.css | 6 + .../mediawiki.action.view.metadata.js | 45 + .../mediawiki.action.view.postEdit.css | 76 + .../mediawiki.action.view.postEdit.js | 86 + .../mediawiki.action.view.redirect.js | 65 + .../mediawiki.action.view.redirectPage.css | 53 + .../mediawiki.action.view.rightClickEdit.js | 26 + .../src/mediawiki.api/mediawiki.api.category.js | 146 ++ resources/src/mediawiki.api/mediawiki.api.edit.js | 87 + resources/src/mediawiki.api/mediawiki.api.js | 397 ++++ resources/src/mediawiki.api/mediawiki.api.login.js | 54 + resources/src/mediawiki.api/mediawiki.api.parse.js | 45 + resources/src/mediawiki.api/mediawiki.api.watch.js | 79 + resources/src/mediawiki.hidpi-skip.js | 4 + resources/src/mediawiki.language/languages/bs.js | 19 + resources/src/mediawiki.language/languages/dsb.js | 19 + resources/src/mediawiki.language/languages/fi.js | 47 + resources/src/mediawiki.language/languages/ga.js | 38 + resources/src/mediawiki.language/languages/he.js | 29 + resources/src/mediawiki.language/languages/hsb.js | 19 + resources/src/mediawiki.language/languages/hu.js | 23 + resources/src/mediawiki.language/languages/hy.js | 29 + resources/src/mediawiki.language/languages/la.js | 50 + resources/src/mediawiki.language/languages/os.js | 69 + resources/src/mediawiki.language/languages/ru.js | 57 + resources/src/mediawiki.language/languages/sl.js | 19 + resources/src/mediawiki.language/languages/uk.js | 37 + resources/src/mediawiki.language/mediawiki.cldr.js | 32 + .../mediawiki.language.fallback.js | 35 + .../mediawiki.language/mediawiki.language.init.js | 81 + .../src/mediawiki.language/mediawiki.language.js | 171 ++ .../mediawiki.language.months.js | 56 + .../mediawiki.language.numbers.js | 258 +++ resources/src/mediawiki.legacy/ajax.js | 194 ++ resources/src/mediawiki.legacy/commonPrint.css | 435 ++++ .../src/mediawiki.legacy/images/ajax-loader.gif | Bin 0 -> 1788 bytes resources/src/mediawiki.legacy/images/checker.png | Bin 0 -> 81 bytes .../src/mediawiki.legacy/images/feed-icon.png | Bin 0 -> 542 bytes .../src/mediawiki.legacy/images/feed-icon.svg | 1 + .../images/help-question-hover.gif | Bin 0 -> 1246 bytes .../src/mediawiki.legacy/images/help-question.gif | Bin 0 -> 126 bytes resources/src/mediawiki.legacy/images/question.png | Bin 0 -> 316 bytes resources/src/mediawiki.legacy/images/question.svg | 1 + resources/src/mediawiki.legacy/images/spinner.gif | Bin 0 -> 1819 bytes resources/src/mediawiki.legacy/oldshared.css | 489 ++++ resources/src/mediawiki.legacy/protect.js | 240 ++ resources/src/mediawiki.legacy/shared.css | 1167 ++++++++++ resources/src/mediawiki.legacy/wikibits.js | 204 ++ .../mediawiki.less/mediawiki.mixins.animation.less | 12 + resources/src/mediawiki.less/mediawiki.mixins.less | 61 + .../mediawiki.less/mediawiki.mixins.rotation.less | 33 + .../src/mediawiki.less/mediawiki.ui/mixins.less | 122 + .../src/mediawiki.less/mediawiki.ui/variables.less | 62 + .../src/mediawiki.libs/CLDRPluralRuleParser.js | 475 ++++ .../src/mediawiki.libs/mediawiki.libs.jpegmeta.js | 737 ++++++ .../src/mediawiki.page/mediawiki.page.gallery.js | 212 ++ .../mediawiki.page.image.pagination.js | 101 + .../mediawiki.page/mediawiki.page.patrol.ajax.js | 65 + .../src/mediawiki.page/mediawiki.page.ready.js | 64 + .../src/mediawiki.page/mediawiki.page.startup.js | 33 + .../mediawiki.page/mediawiki.page.watch.ajax.js | 178 ++ resources/src/mediawiki.skinning/content.css | 227 ++ .../mediawiki.skinning/content.externallinks.css | 102 + .../src/mediawiki.skinning/content.parsoid.less | 131 ++ resources/src/mediawiki.skinning/elements.css | 273 +++ .../src/mediawiki.skinning/images/audio-ltr.png | Bin 0 -> 401 bytes .../src/mediawiki.skinning/images/audio-ltr.svg | 8 + .../src/mediawiki.skinning/images/audio-rtl.png | Bin 0 -> 417 bytes .../src/mediawiki.skinning/images/audio-rtl.svg | 8 + .../src/mediawiki.skinning/images/chat-ltr.png | Bin 0 -> 304 bytes .../src/mediawiki.skinning/images/chat-ltr.svg | 6 + .../src/mediawiki.skinning/images/chat-rtl.png | Bin 0 -> 297 bytes .../src/mediawiki.skinning/images/chat-rtl.svg | 6 + .../src/mediawiki.skinning/images/document-ltr.png | Bin 0 -> 275 bytes .../src/mediawiki.skinning/images/document-ltr.svg | 5 + .../src/mediawiki.skinning/images/document-rtl.png | Bin 0 -> 264 bytes .../src/mediawiki.skinning/images/document-rtl.svg | 5 + .../images/external link icons.svg | 697 ++++++ .../src/mediawiki.skinning/images/external-ltr.png | Bin 0 -> 403 bytes .../src/mediawiki.skinning/images/external-ltr.svg | 8 + .../src/mediawiki.skinning/images/external-rtl.png | Bin 0 -> 411 bytes .../src/mediawiki.skinning/images/external-rtl.svg | 8 + .../src/mediawiki.skinning/images/ftp-ltr.png | Bin 0 -> 356 bytes .../src/mediawiki.skinning/images/ftp-ltr.svg | 9 + .../src/mediawiki.skinning/images/ftp-rtl.png | Bin 0 -> 334 bytes .../src/mediawiki.skinning/images/ftp-rtl.svg | 9 + .../mediawiki.skinning/images/magnify-clip-ltr.png | Bin 0 -> 204 bytes .../mediawiki.skinning/images/magnify-clip-rtl.png | Bin 0 -> 149 bytes resources/src/mediawiki.skinning/images/mail.png | Bin 0 -> 334 bytes resources/src/mediawiki.skinning/images/mail.svg | 7 + resources/src/mediawiki.skinning/images/video.png | Bin 0 -> 358 bytes resources/src/mediawiki.skinning/images/video.svg | 14 + resources/src/mediawiki.skinning/interface.css | 68 + .../images/glyph-people-large.png | Bin 0 -> 1663 bytes .../mediawiki.special/images/icon-contributors.png | Bin 0 -> 1169 bytes .../src/mediawiki.special/images/icon-edits.png | Bin 0 -> 780 bytes .../src/mediawiki.special/images/icon-lock.png | Bin 0 -> 172 bytes .../src/mediawiki.special/images/icon-pages.png | Bin 0 -> 528 bytes .../mediawiki.special/mediawiki.special.block.css | 11 + .../mediawiki.special/mediawiki.special.block.js | 45 + .../mediawiki.special.changeemail.css | 19 + .../mediawiki.special.changeemail.js | 52 + .../mediawiki.special.changeslist.css | 7 + .../mediawiki.special.changeslist.enhanced.css | 61 + .../mediawiki.special.changeslist.legend.css | 29 + .../mediawiki.special.changeslist.legend.js | 25 + .../src/mediawiki.special/mediawiki.special.css | 120 + .../mediawiki.special/mediawiki.special.import.js | 35 + .../mediawiki.special.javaScriptTest.js | 36 + .../src/mediawiki.special/mediawiki.special.js | 9 + .../mediawiki.special.movePage.js | 6 + .../mediawiki.special.pageLanguage.js | 9 + .../mediawiki.special.pagesWithProp.css | 4 + .../mediawiki.special.preferences.css | 21 + .../mediawiki.special.preferences.js | 305 +++ .../mediawiki.special.recentchanges.js | 39 + .../mediawiki.special/mediawiki.special.search.css | 173 ++ .../mediawiki.special/mediawiki.special.search.js | 58 + .../mediawiki.special.undelete.js | 11 + .../mediawiki.special.unwatchedPages.css | 9 + .../mediawiki.special.unwatchedPages.js | 52 + .../mediawiki.special/mediawiki.special.upload.js | 565 +++++ .../mediawiki.special.userlogin.common.css | 66 + .../mediawiki.special.userlogin.common.js | 72 + .../mediawiki.special.userlogin.login.css | 22 + .../mediawiki.special.userlogin.signup.css | 66 + .../mediawiki.special.userlogin.signup.js | 140 ++ .../mediawiki.special.version.css | 14 + resources/src/mediawiki.ui/components/anchors.less | 77 + resources/src/mediawiki.ui/components/buttons.less | 276 +++ .../src/mediawiki.ui/components/checkbox.less | 100 + resources/src/mediawiki.ui/components/forms.less | 166 ++ .../src/mediawiki.ui/components/images/checked.png | Bin 0 -> 327 bytes .../src/mediawiki.ui/components/images/checked.svg | 1 + resources/src/mediawiki.ui/components/inputs.less | 126 + .../src/mediawiki.ui/components/utilities.less | 47 + resources/src/mediawiki.ui/default.less | 5 + resources/src/mediawiki.ui/styleguide.md | 11 + .../src/mediawiki/images/arrow-collapsed-ltr.png | Bin 0 -> 133 bytes .../src/mediawiki/images/arrow-collapsed-ltr.svg | 1 + .../src/mediawiki/images/arrow-collapsed-rtl.png | Bin 0 -> 136 bytes .../src/mediawiki/images/arrow-collapsed-rtl.svg | 1 + resources/src/mediawiki/images/arrow-expanded.png | Bin 0 -> 134 bytes resources/src/mediawiki/images/arrow-expanded.svg | 1 + .../src/mediawiki/images/arrow-sort-ascending.png | Bin 0 -> 244 bytes .../src/mediawiki/images/arrow-sort-ascending.svg | 1 + .../src/mediawiki/images/arrow-sort-descending.png | Bin 0 -> 245 bytes .../src/mediawiki/images/arrow-sort-descending.svg | 1 + .../pager-arrow-disabled-fastforward-ltr.png | Bin 0 -> 323 bytes .../pager-arrow-disabled-fastforward-rtl.png | Bin 0 -> 318 bytes .../images/pager-arrow-disabled-forward-ltr.png | Bin 0 -> 307 bytes .../images/pager-arrow-disabled-forward-rtl.png | Bin 0 -> 301 bytes .../images/pager-arrow-fastforward-ltr.png | Bin 0 -> 342 bytes .../images/pager-arrow-fastforward-rtl.png | Bin 0 -> 352 bytes .../mediawiki/images/pager-arrow-forward-ltr.png | Bin 0 -> 337 bytes .../mediawiki/images/pager-arrow-forward-rtl.png | Bin 0 -> 330 bytes resources/src/mediawiki/mediawiki.Title.js | 939 ++++++++ resources/src/mediawiki/mediawiki.Uri.js | 403 ++++ resources/src/mediawiki/mediawiki.content.json.css | 53 + resources/src/mediawiki/mediawiki.cookie.js | 126 + resources/src/mediawiki/mediawiki.debug.init.js | 3 + resources/src/mediawiki/mediawiki.debug.js | 391 ++++ resources/src/mediawiki/mediawiki.debug.less | 189 ++ .../src/mediawiki/mediawiki.debug.profile.css | 45 + resources/src/mediawiki/mediawiki.debug.profile.js | 556 +++++ resources/src/mediawiki/mediawiki.feedback.css | 9 + resources/src/mediawiki/mediawiki.feedback.js | 320 +++ .../src/mediawiki/mediawiki.feedback.spinner.gif | Bin 0 -> 1108 bytes resources/src/mediawiki/mediawiki.hidpi.js | 5 + resources/src/mediawiki/mediawiki.hlist.css | 78 + resources/src/mediawiki/mediawiki.hlist.js | 31 + resources/src/mediawiki/mediawiki.htmlform.js | 408 ++++ resources/src/mediawiki/mediawiki.icon.less | 19 + resources/src/mediawiki/mediawiki.inspect.js | 284 +++ resources/src/mediawiki/mediawiki.jqueryMsg.js | 1251 ++++++++++ resources/src/mediawiki/mediawiki.jqueryMsg.peg | 85 + resources/src/mediawiki/mediawiki.js | 2399 ++++++++++++++++++++ resources/src/mediawiki/mediawiki.log.js | 84 + resources/src/mediawiki/mediawiki.notification.css | 27 + .../mediawiki.notification.hideForPrint.css | 3 + resources/src/mediawiki/mediawiki.notification.js | 523 +++++ resources/src/mediawiki/mediawiki.notify.js | 27 + .../src/mediawiki/mediawiki.pager.tablePager.less | 84 + .../src/mediawiki/mediawiki.searchSuggest.css | 24 + resources/src/mediawiki/mediawiki.searchSuggest.js | 199 ++ resources/src/mediawiki/mediawiki.toc.js | 60 + resources/src/mediawiki/mediawiki.user.js | 258 +++ resources/src/mediawiki/mediawiki.util.js | 531 +++++ resources/src/polyfill-object-create.js | 62 + resources/src/startup.js | 62 + 297 files changed, 28962 insertions(+) create mode 100644 resources/src/es5-skip.js create mode 100644 resources/src/jquery.json-deprecate.js create mode 100644 resources/src/jquery.tipsy/images/tipsy.png create mode 100644 resources/src/jquery.tipsy/jquery.tipsy.css create mode 100644 resources/src/jquery.tipsy/jquery.tipsy.js create mode 100644 resources/src/jquery/images/jquery.arrowSteps.divider-ltr.png create mode 100644 resources/src/jquery/images/jquery.arrowSteps.divider-rtl.png create mode 100644 resources/src/jquery/images/jquery.arrowSteps.head-ltr.png create mode 100644 resources/src/jquery/images/jquery.arrowSteps.head-rtl.png create mode 100644 resources/src/jquery/images/jquery.arrowSteps.tail-ltr.png create mode 100644 resources/src/jquery/images/jquery.arrowSteps.tail-rtl.png create mode 100644 resources/src/jquery/images/marker.png create mode 100644 resources/src/jquery/images/mask.png create mode 100644 resources/src/jquery/images/sort_both.gif create mode 100644 resources/src/jquery/images/sort_down.gif create mode 100644 resources/src/jquery/images/sort_none.gif create mode 100644 resources/src/jquery/images/sort_up.gif create mode 100644 resources/src/jquery/images/spinner-large.gif create mode 100644 resources/src/jquery/images/spinner.gif create mode 100644 resources/src/jquery/images/wheel.png create mode 100644 resources/src/jquery/jquery.accessKeyLabel.js create mode 100644 resources/src/jquery/jquery.arrowSteps.css create mode 100644 resources/src/jquery/jquery.arrowSteps.js create mode 100644 resources/src/jquery/jquery.autoEllipsis.js create mode 100644 resources/src/jquery/jquery.badge.css create mode 100644 resources/src/jquery/jquery.badge.js create mode 100644 resources/src/jquery/jquery.byteLength.js create mode 100644 resources/src/jquery/jquery.byteLimit.js create mode 100644 resources/src/jquery/jquery.checkboxShiftClick.js create mode 100644 resources/src/jquery/jquery.client.js create mode 100644 resources/src/jquery/jquery.color.js create mode 100644 resources/src/jquery/jquery.colorUtil.js create mode 100644 resources/src/jquery/jquery.confirmable.css create mode 100644 resources/src/jquery/jquery.confirmable.js create mode 100644 resources/src/jquery/jquery.confirmable.mediawiki.js create mode 100644 resources/src/jquery/jquery.expandableField.js create mode 100644 resources/src/jquery/jquery.farbtastic.css create mode 100644 resources/src/jquery/jquery.farbtastic.js create mode 100644 resources/src/jquery/jquery.footHovzer.css create mode 100644 resources/src/jquery/jquery.footHovzer.js create mode 100644 resources/src/jquery/jquery.getAttrs.js create mode 100644 resources/src/jquery/jquery.hidpi.js create mode 100644 resources/src/jquery/jquery.highlightText.js create mode 100644 resources/src/jquery/jquery.localize.js create mode 100644 resources/src/jquery/jquery.makeCollapsible.css create mode 100644 resources/src/jquery/jquery.makeCollapsible.js create mode 100644 resources/src/jquery/jquery.mw-jump.js create mode 100644 resources/src/jquery/jquery.mwExtension.js create mode 100644 resources/src/jquery/jquery.placeholder.js create mode 100644 resources/src/jquery/jquery.qunit.completenessTest.js create mode 100644 resources/src/jquery/jquery.spinner.css create mode 100644 resources/src/jquery/jquery.spinner.js create mode 100644 resources/src/jquery/jquery.suggestions.css create mode 100644 resources/src/jquery/jquery.suggestions.js create mode 100644 resources/src/jquery/jquery.tabIndex.js create mode 100644 resources/src/jquery/jquery.tablesorter.css create mode 100644 resources/src/jquery/jquery.tablesorter.js create mode 100644 resources/src/jquery/jquery.textSelection.js create mode 100644 resources/src/json-skip.js create mode 100644 resources/src/mediawiki.action/images/green-checkmark.png create mode 100644 resources/src/mediawiki.action/images/nextredirect-ltr.png create mode 100644 resources/src/mediawiki.action/images/nextredirect-rtl.png create mode 100644 resources/src/mediawiki.action/images/redirect-ltr.png create mode 100644 resources/src/mediawiki.action/images/redirect-rtl.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.collapsibleFooter.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.editWarning.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.preview.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.styles.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_headline.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_link.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ar/button_nowiki.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/be-tarask/button_link.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/de/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_extlink.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_headline.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_hr.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_image.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_link.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_media.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_nowiki.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/en/button_sig.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_headline.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_link.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/fa/button_nowiki.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/LICENSE create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ksh/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/LICENSE create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_bold.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_italic.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/images/ru/button_link.png create mode 100644 resources/src/mediawiki.action/mediawiki.action.edit.toolbar/mediawiki.action.edit.toolbar.less create mode 100644 resources/src/mediawiki.action/mediawiki.action.history.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.history.diff.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.history.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.dblClickEdit.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.metadata.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.metadata.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.postEdit.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.postEdit.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.redirect.js create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.redirectPage.css create mode 100644 resources/src/mediawiki.action/mediawiki.action.view.rightClickEdit.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.category.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.edit.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.login.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.parse.js create mode 100644 resources/src/mediawiki.api/mediawiki.api.watch.js create mode 100644 resources/src/mediawiki.hidpi-skip.js create mode 100644 resources/src/mediawiki.language/languages/bs.js create mode 100644 resources/src/mediawiki.language/languages/dsb.js create mode 100644 resources/src/mediawiki.language/languages/fi.js create mode 100644 resources/src/mediawiki.language/languages/ga.js create mode 100644 resources/src/mediawiki.language/languages/he.js create mode 100644 resources/src/mediawiki.language/languages/hsb.js create mode 100644 resources/src/mediawiki.language/languages/hu.js create mode 100644 resources/src/mediawiki.language/languages/hy.js create mode 100644 resources/src/mediawiki.language/languages/la.js create mode 100644 resources/src/mediawiki.language/languages/os.js create mode 100644 resources/src/mediawiki.language/languages/ru.js create mode 100644 resources/src/mediawiki.language/languages/sl.js create mode 100644 resources/src/mediawiki.language/languages/uk.js create mode 100644 resources/src/mediawiki.language/mediawiki.cldr.js create mode 100644 resources/src/mediawiki.language/mediawiki.language.fallback.js create mode 100644 resources/src/mediawiki.language/mediawiki.language.init.js create mode 100644 resources/src/mediawiki.language/mediawiki.language.js create mode 100644 resources/src/mediawiki.language/mediawiki.language.months.js create mode 100644 resources/src/mediawiki.language/mediawiki.language.numbers.js create mode 100644 resources/src/mediawiki.legacy/ajax.js create mode 100644 resources/src/mediawiki.legacy/commonPrint.css create mode 100644 resources/src/mediawiki.legacy/images/ajax-loader.gif create mode 100644 resources/src/mediawiki.legacy/images/checker.png create mode 100644 resources/src/mediawiki.legacy/images/feed-icon.png create mode 100644 resources/src/mediawiki.legacy/images/feed-icon.svg create mode 100644 resources/src/mediawiki.legacy/images/help-question-hover.gif create mode 100644 resources/src/mediawiki.legacy/images/help-question.gif create mode 100644 resources/src/mediawiki.legacy/images/question.png create mode 100644 resources/src/mediawiki.legacy/images/question.svg create mode 100644 resources/src/mediawiki.legacy/images/spinner.gif create mode 100644 resources/src/mediawiki.legacy/oldshared.css create mode 100644 resources/src/mediawiki.legacy/protect.js create mode 100644 resources/src/mediawiki.legacy/shared.css create mode 100644 resources/src/mediawiki.legacy/wikibits.js create mode 100644 resources/src/mediawiki.less/mediawiki.mixins.animation.less create mode 100644 resources/src/mediawiki.less/mediawiki.mixins.less create mode 100644 resources/src/mediawiki.less/mediawiki.mixins.rotation.less create mode 100644 resources/src/mediawiki.less/mediawiki.ui/mixins.less create mode 100644 resources/src/mediawiki.less/mediawiki.ui/variables.less create mode 100644 resources/src/mediawiki.libs/CLDRPluralRuleParser.js create mode 100644 resources/src/mediawiki.libs/mediawiki.libs.jpegmeta.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.gallery.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.image.pagination.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.patrol.ajax.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.ready.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.startup.js create mode 100644 resources/src/mediawiki.page/mediawiki.page.watch.ajax.js create mode 100644 resources/src/mediawiki.skinning/content.css create mode 100644 resources/src/mediawiki.skinning/content.externallinks.css create mode 100644 resources/src/mediawiki.skinning/content.parsoid.less create mode 100644 resources/src/mediawiki.skinning/elements.css create mode 100644 resources/src/mediawiki.skinning/images/audio-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/audio-ltr.svg create mode 100644 resources/src/mediawiki.skinning/images/audio-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/audio-rtl.svg create mode 100644 resources/src/mediawiki.skinning/images/chat-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/chat-ltr.svg create mode 100644 resources/src/mediawiki.skinning/images/chat-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/chat-rtl.svg create mode 100644 resources/src/mediawiki.skinning/images/document-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/document-ltr.svg create mode 100644 resources/src/mediawiki.skinning/images/document-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/document-rtl.svg create mode 100644 resources/src/mediawiki.skinning/images/external link icons.svg create mode 100644 resources/src/mediawiki.skinning/images/external-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/external-ltr.svg create mode 100644 resources/src/mediawiki.skinning/images/external-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/external-rtl.svg create mode 100644 resources/src/mediawiki.skinning/images/ftp-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/ftp-ltr.svg create mode 100644 resources/src/mediawiki.skinning/images/ftp-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/ftp-rtl.svg create mode 100644 resources/src/mediawiki.skinning/images/magnify-clip-ltr.png create mode 100644 resources/src/mediawiki.skinning/images/magnify-clip-rtl.png create mode 100644 resources/src/mediawiki.skinning/images/mail.png create mode 100644 resources/src/mediawiki.skinning/images/mail.svg create mode 100644 resources/src/mediawiki.skinning/images/video.png create mode 100644 resources/src/mediawiki.skinning/images/video.svg create mode 100644 resources/src/mediawiki.skinning/interface.css create mode 100644 resources/src/mediawiki.special/images/glyph-people-large.png create mode 100644 resources/src/mediawiki.special/images/icon-contributors.png create mode 100644 resources/src/mediawiki.special/images/icon-edits.png create mode 100644 resources/src/mediawiki.special/images/icon-lock.png create mode 100644 resources/src/mediawiki.special/images/icon-pages.png create mode 100644 resources/src/mediawiki.special/mediawiki.special.block.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.block.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeemail.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeemail.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.import.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.movePage.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.pageLanguage.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.preferences.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.preferences.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.recentchanges.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.search.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.search.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.undelete.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.upload.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.common.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.common.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.login.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.version.css create mode 100644 resources/src/mediawiki.ui/components/anchors.less create mode 100644 resources/src/mediawiki.ui/components/buttons.less create mode 100644 resources/src/mediawiki.ui/components/checkbox.less create mode 100644 resources/src/mediawiki.ui/components/forms.less create mode 100644 resources/src/mediawiki.ui/components/images/checked.png create mode 100644 resources/src/mediawiki.ui/components/images/checked.svg create mode 100644 resources/src/mediawiki.ui/components/inputs.less create mode 100644 resources/src/mediawiki.ui/components/utilities.less create mode 100644 resources/src/mediawiki.ui/default.less create mode 100644 resources/src/mediawiki.ui/styleguide.md create mode 100644 resources/src/mediawiki/images/arrow-collapsed-ltr.png create mode 100644 resources/src/mediawiki/images/arrow-collapsed-ltr.svg create mode 100644 resources/src/mediawiki/images/arrow-collapsed-rtl.png create mode 100644 resources/src/mediawiki/images/arrow-collapsed-rtl.svg create mode 100644 resources/src/mediawiki/images/arrow-expanded.png create mode 100644 resources/src/mediawiki/images/arrow-expanded.svg create mode 100644 resources/src/mediawiki/images/arrow-sort-ascending.png create mode 100644 resources/src/mediawiki/images/arrow-sort-ascending.svg create mode 100644 resources/src/mediawiki/images/arrow-sort-descending.png create mode 100644 resources/src/mediawiki/images/arrow-sort-descending.svg create mode 100644 resources/src/mediawiki/images/pager-arrow-disabled-fastforward-ltr.png create mode 100644 resources/src/mediawiki/images/pager-arrow-disabled-fastforward-rtl.png create mode 100644 resources/src/mediawiki/images/pager-arrow-disabled-forward-ltr.png create mode 100644 resources/src/mediawiki/images/pager-arrow-disabled-forward-rtl.png create mode 100644 resources/src/mediawiki/images/pager-arrow-fastforward-ltr.png create mode 100644 resources/src/mediawiki/images/pager-arrow-fastforward-rtl.png create mode 100644 resources/src/mediawiki/images/pager-arrow-forward-ltr.png create mode 100644 resources/src/mediawiki/images/pager-arrow-forward-rtl.png create mode 100644 resources/src/mediawiki/mediawiki.Title.js create mode 100644 resources/src/mediawiki/mediawiki.Uri.js create mode 100644 resources/src/mediawiki/mediawiki.content.json.css create mode 100644 resources/src/mediawiki/mediawiki.cookie.js create mode 100644 resources/src/mediawiki/mediawiki.debug.init.js create mode 100644 resources/src/mediawiki/mediawiki.debug.js create mode 100644 resources/src/mediawiki/mediawiki.debug.less create mode 100644 resources/src/mediawiki/mediawiki.debug.profile.css create mode 100644 resources/src/mediawiki/mediawiki.debug.profile.js create mode 100644 resources/src/mediawiki/mediawiki.feedback.css create mode 100644 resources/src/mediawiki/mediawiki.feedback.js create mode 100644 resources/src/mediawiki/mediawiki.feedback.spinner.gif create mode 100644 resources/src/mediawiki/mediawiki.hidpi.js create mode 100644 resources/src/mediawiki/mediawiki.hlist.css create mode 100644 resources/src/mediawiki/mediawiki.hlist.js create mode 100644 resources/src/mediawiki/mediawiki.htmlform.js create mode 100644 resources/src/mediawiki/mediawiki.icon.less create mode 100644 resources/src/mediawiki/mediawiki.inspect.js create mode 100644 resources/src/mediawiki/mediawiki.jqueryMsg.js create mode 100644 resources/src/mediawiki/mediawiki.jqueryMsg.peg create mode 100644 resources/src/mediawiki/mediawiki.js create mode 100644 resources/src/mediawiki/mediawiki.log.js create mode 100644 resources/src/mediawiki/mediawiki.notification.css create mode 100644 resources/src/mediawiki/mediawiki.notification.hideForPrint.css create mode 100644 resources/src/mediawiki/mediawiki.notification.js create mode 100644 resources/src/mediawiki/mediawiki.notify.js create mode 100644 resources/src/mediawiki/mediawiki.pager.tablePager.less create mode 100644 resources/src/mediawiki/mediawiki.searchSuggest.css create mode 100644 resources/src/mediawiki/mediawiki.searchSuggest.js create mode 100644 resources/src/mediawiki/mediawiki.toc.js create mode 100644 resources/src/mediawiki/mediawiki.user.js create mode 100644 resources/src/mediawiki/mediawiki.util.js create mode 100644 resources/src/polyfill-object-create.js create mode 100644 resources/src/startup.js (limited to 'resources/src') diff --git a/resources/src/es5-skip.js b/resources/src/es5-skip.js new file mode 100644 index 00000000..a4039d89 --- /dev/null +++ b/resources/src/es5-skip.js @@ -0,0 +1,18 @@ +/*! + * Skip function for es5-shim module. + * + * Test for strict mode as a proxy for full ES5 function support (but not syntax) + * Per http://kangax.github.io/compat-table/es5/ this is a reasonable shortcut + * that still allows this to be as short as possible (there are no browsers we + * support that have strict mode, but lack other features). + * + * Do explicitly test for Function#bind because of PhantomJS (which implements + * strict mode, but lacks Function#bind). + * + * IE9 supports all features except strict mode, so loading es5-shim should be close to + * a no-op but does increase page payload). + */ +return ( function () { + 'use strict'; + return !this && !!Function.prototype.bind; +}() ); diff --git a/resources/src/jquery.json-deprecate.js b/resources/src/jquery.json-deprecate.js new file mode 100644 index 00000000..f38decd9 --- /dev/null +++ b/resources/src/jquery.json-deprecate.js @@ -0,0 +1,8 @@ +( function ( mw, $ ) { + // @deprecated since 1.24. The 'jquery.json' module will be removed in MW 1.25. Use the 'json' module. + + mw.log.deprecate( $, 'toJSON', $.toJSON, 'Use JSON.stringify instead (module "json" for polyfill).' ); + mw.log.deprecate( $, 'evalJSON', $.evalJSON, 'Use JSON.parse instead (module "json" for polyfill).' ); + mw.log.deprecate( $, 'secureEvalJSON', $.secureEvalJSON, 'Use JSON.parse instead (module "json" for polyfill).' ); + mw.log.deprecate( $, 'quoteString', $.quoteString, 'Use JSON.stringify instead (module "json" for polyfill).' ); +}( mediaWiki, jQuery ) ); diff --git a/resources/src/jquery.tipsy/images/tipsy.png b/resources/src/jquery.tipsy/images/tipsy.png new file mode 100644 index 00000000..ef17cc32 Binary files /dev/null and b/resources/src/jquery.tipsy/images/tipsy.png differ diff --git a/resources/src/jquery.tipsy/jquery.tipsy.css b/resources/src/jquery.tipsy/jquery.tipsy.css new file mode 100644 index 00000000..6471516d --- /dev/null +++ b/resources/src/jquery.tipsy/jquery.tipsy.css @@ -0,0 +1,73 @@ +.tipsy { + padding: 5px; + position: absolute; + z-index: 100000; + cursor: default; +} +.tipsy-inner { + padding: 5px 8px 4px 8px; + /*background-color: #e8f2f8;*/ + background-color: #ffffff; + border: solid 1px #a7d7f9; + color: black; + max-width: 15em; + border-radius: 4px; + /* + -moz-box-shadow: 0px 2px 8px #cccccc; + -webkit-box-shadow: 0px 2px 8px #cccccc; + box-shadow: 0px 2px 8px #cccccc; + -ms-filter: "progid:DXImageTransform.Microsoft.DropShadow(OffX=0, OffY=2, Strength=6, Direction=90, Color='#cccccc')"; + filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=0, OffY=2, Strength=6, Direction=90, Color='#cccccc'); + */ +} +.tipsy-arrow { + position: absolute; + /* @embed */ + background: url('images/tipsy.png') no-repeat top left; + width: 11px; + height: 6px; +} +/* @noflip */ .tipsy-n .tipsy-arrow { + top: 0px; + left: 50%; + margin-left: -5px; +} +/* @noflip */ .tipsy-nw .tipsy-arrow { + top: 1px; + left: 10px; +} +/* @noflip */ .tipsy-ne .tipsy-arrow { + top: 1px; + right: 10px; +} +/* @noflip */ .tipsy-s .tipsy-arrow { + bottom: 0px; + left: 50%; + margin-left: -5px; + background-position: bottom left; +} +/* @noflip */ .tipsy-sw .tipsy-arrow { + bottom: 0px; + left: 10px; + background-position: bottom left; +} +/* @noflip */ .tipsy-se .tipsy-arrow { + bottom: 0px; + right: 10px; + background-position: bottom left; +} +/* @noflip */ .tipsy-e .tipsy-arrow { + top: 50%; + margin-top: -5px; + right: 1px; + width: 5px; + height: 11px; + background-position: top right; +} +/* @noflip */ .tipsy-w .tipsy-arrow { + top: 50%; + margin-top: -5px; + left: 0px; + width: 6px; + height: 11px; +} diff --git a/resources/src/jquery.tipsy/jquery.tipsy.js b/resources/src/jquery.tipsy/jquery.tipsy.js new file mode 100644 index 00000000..58a99a59 --- /dev/null +++ b/resources/src/jquery.tipsy/jquery.tipsy.js @@ -0,0 +1,259 @@ +// tipsy, facebook style tooltips for jquery +// version 1.0.0a* +// (c) 2008-2010 jason frame [jason@onehackoranother.com] +// released under the MIT license + +// * This installation of tipsy includes several local modifications to both Javascript and CSS. +// Please be careful when upgrading. + +(function($) { + + function maybeCall(thing, ctx) { + return (typeof thing == 'function') ? (thing.call(ctx)) : thing; + } + + function Tipsy(element, options) { + this.$element = $(element); + this.options = options; + this.enabled = true; + this.fixTitle(); + } + + Tipsy.prototype = { + show: function() { + var title = this.getTitle(); + if (title && this.enabled) { + var $tip = this.tip(); + + $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); + $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity + if (this.options.className) { + $tip.addClass(maybeCall(this.options.className, this.$element[0])); + } + $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body); + + var pos = $.extend({}, this.$element.offset(), { + width: this.$element[0].offsetWidth, + height: this.$element[0].offsetHeight + }); + + var gravity = (typeof this.options.gravity == 'function') + ? this.options.gravity.call(this.$element[0]) + : this.options.gravity; + + // Attach css classes before checking height/width so they + // can be applied. + $tip.addClass('tipsy-' + gravity); + if (this.options.className) { + $tip.addClass(maybeCall(this.options.className, this.$element[0])); + } + + var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight; + var tp; + switch (gravity.charAt(0)) { + case 'n': + tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; + break; + case 's': + tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; + break; + case 'e': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; + break; + case 'w': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; + break; + } + + if (gravity.length == 2) { + if (gravity.charAt(1) == 'w') { + if (this.options.center) { + tp.left = pos.left + pos.width / 2 - 15; + } else { + tp.left = pos.left; + } + } else { + if (this.options.center) { + tp.left = pos.left + pos.width / 2 - actualWidth + 15; + } else { + tp.left = pos.left + pos.width; + } + } + } + $tip.css(tp); + + if (this.options.fade) { + $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}, 100); + } else { + $tip.css({visibility: 'visible', opacity: this.options.opacity}); + } + } + }, + + hide: function() { + if (this.options.fade) { + this.tip().stop().fadeOut(100, function() { $(this).remove(); }); + } else { + this.tip().remove(); + } + }, + + + fixTitle: function() { + var $e = this.$element; + if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { + $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); + } + }, + + getTitle: function() { + var title, $e = this.$element, o = this.options; + this.fixTitle(); + if (typeof o.title == 'string') { + title = $e.attr(o.title == 'title' ? 'original-title' : o.title); + } else if (typeof o.title == 'function') { + title = o.title.call($e[0]); + } + title = ('' + title).replace(/(^\s*|\s*$)/, ""); + return title || o.fallback; + }, + + tip: function() { + if (!this.$tip) { + this.$tip = $('
').html('
'); + } + return this.$tip; + }, + + validate: function() { + if (!this.$element[0].parentNode) { + this.hide(); + this.$element = null; + this.options = null; + } + }, + + enable: function() { this.enabled = true; }, + disable: function() { this.enabled = false; }, + toggleEnabled: function() { this.enabled = !this.enabled; } + }; + + $.fn.tipsy = function(options) { + + if (options === true) { + return this.data('tipsy'); + } else if (typeof options == 'string') { + var tipsy = this.data('tipsy'); + if (tipsy) tipsy[options](); + return this; + } + + options = $.extend({}, $.fn.tipsy.defaults, options); + + function get(ele) { + var tipsy = $.data(ele, 'tipsy'); + if (!tipsy) { + tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); + $.data(ele, 'tipsy', tipsy); + } + return tipsy; + } + + function enter() { + var tipsy = get(this); + tipsy.hoverState = 'in'; + if (options.delayIn == 0) { + tipsy.show(); + } else { + tipsy.fixTitle(); + setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); + } + }; + + function leave() { + var tipsy = get(this); + tipsy.hoverState = 'out'; + if (options.delayOut == 0) { + tipsy.hide(); + } else { + setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); + } + }; + + if (!options.live) this.each(function() { get(this); }); + + if (options.trigger != 'manual') { + var binder = options.live ? 'live' : 'bind', + eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', + eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; + this[binder](eventIn, enter)[binder](eventOut, leave); + } + + return this; + + }; + + $.fn.tipsy.defaults = { + className: null, + delayIn: 0, + delayOut: 0, + fade: true, + fallback: '', + gravity: 'n', + center: true, + html: false, + live: false, + offset: 0, + opacity: 1.0, + title: 'title', + trigger: 'hover' + }; + + // Overwrite this method to provide options on a per-element basis. + // For example, you could store the gravity in a 'tipsy-gravity' attribute: + // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); + // (remember - do not modify 'options' in place!) + $.fn.tipsy.elementOptions = function(ele, options) { + return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; + }; + + $.fn.tipsy.autoNS = function() { + return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; + }; + + $.fn.tipsy.autoWE = function() { + return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; + }; + + /** + * yields a closure of the supplied parameters, producing a function that takes + * no arguments and is suitable for use as an autogravity function like so: + * + * @param margin (int) - distance from the viewable region edge that an + * element should be before setting its tooltip's gravity to be away + * from that edge. + * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer + * if there are no viewable region edges effecting the tooltip's + * gravity. It will try to vary from this minimally, for example, + * if 'sw' is preferred and an element is near the right viewable + * region edge, but not the top edge, it will set the gravity for + * that element's tooltip to be 'se', preserving the southern + * component. + */ + $.fn.tipsy.autoBounds = function(margin, prefer) { + return function() { + var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, + boundTop = $(document).scrollTop() + margin, + boundLeft = $(document).scrollLeft() + margin, + $this = $(this); + + if ($this.offset().top < boundTop) dir.ns = 'n'; + if ($this.offset().left < boundLeft) dir.ew = 'w'; + if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; + if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; + + return dir.ns + (dir.ew ? dir.ew : ''); + } + }; + +})(jQuery); diff --git a/resources/src/jquery/images/jquery.arrowSteps.divider-ltr.png b/resources/src/jquery/images/jquery.arrowSteps.divider-ltr.png new file mode 100644 index 00000000..84ed2a2d Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.divider-ltr.png differ diff --git a/resources/src/jquery/images/jquery.arrowSteps.divider-rtl.png b/resources/src/jquery/images/jquery.arrowSteps.divider-rtl.png new file mode 100644 index 00000000..7cfbfeba Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.divider-rtl.png differ diff --git a/resources/src/jquery/images/jquery.arrowSteps.head-ltr.png b/resources/src/jquery/images/jquery.arrowSteps.head-ltr.png new file mode 100644 index 00000000..eb070280 Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.head-ltr.png differ diff --git a/resources/src/jquery/images/jquery.arrowSteps.head-rtl.png b/resources/src/jquery/images/jquery.arrowSteps.head-rtl.png new file mode 100644 index 00000000..7ea2fdb5 Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.head-rtl.png differ diff --git a/resources/src/jquery/images/jquery.arrowSteps.tail-ltr.png b/resources/src/jquery/images/jquery.arrowSteps.tail-ltr.png new file mode 100644 index 00000000..3ad990b6 Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.tail-ltr.png differ diff --git a/resources/src/jquery/images/jquery.arrowSteps.tail-rtl.png b/resources/src/jquery/images/jquery.arrowSteps.tail-rtl.png new file mode 100644 index 00000000..1d3048ef Binary files /dev/null and b/resources/src/jquery/images/jquery.arrowSteps.tail-rtl.png differ diff --git a/resources/src/jquery/images/marker.png b/resources/src/jquery/images/marker.png new file mode 100644 index 00000000..19efb6ce Binary files /dev/null and b/resources/src/jquery/images/marker.png differ diff --git a/resources/src/jquery/images/mask.png b/resources/src/jquery/images/mask.png new file mode 100644 index 00000000..fe08de0e Binary files /dev/null and b/resources/src/jquery/images/mask.png differ diff --git a/resources/src/jquery/images/sort_both.gif b/resources/src/jquery/images/sort_both.gif new file mode 100644 index 00000000..50ad15a0 Binary files /dev/null and b/resources/src/jquery/images/sort_both.gif differ diff --git a/resources/src/jquery/images/sort_down.gif b/resources/src/jquery/images/sort_down.gif new file mode 100644 index 00000000..ec4f41b0 Binary files /dev/null and b/resources/src/jquery/images/sort_down.gif differ diff --git a/resources/src/jquery/images/sort_none.gif b/resources/src/jquery/images/sort_none.gif new file mode 100644 index 00000000..edd07e58 Binary files /dev/null and b/resources/src/jquery/images/sort_none.gif differ diff --git a/resources/src/jquery/images/sort_up.gif b/resources/src/jquery/images/sort_up.gif new file mode 100644 index 00000000..80189185 Binary files /dev/null and b/resources/src/jquery/images/sort_up.gif differ diff --git a/resources/src/jquery/images/spinner-large.gif b/resources/src/jquery/images/spinner-large.gif new file mode 100644 index 00000000..72203fdd Binary files /dev/null and b/resources/src/jquery/images/spinner-large.gif differ diff --git a/resources/src/jquery/images/spinner.gif b/resources/src/jquery/images/spinner.gif new file mode 100644 index 00000000..6146be4e Binary files /dev/null and b/resources/src/jquery/images/spinner.gif differ diff --git a/resources/src/jquery/images/wheel.png b/resources/src/jquery/images/wheel.png new file mode 100644 index 00000000..7e53103e Binary files /dev/null and b/resources/src/jquery/images/wheel.png differ diff --git a/resources/src/jquery/jquery.accessKeyLabel.js b/resources/src/jquery/jquery.accessKeyLabel.js new file mode 100644 index 00000000..7b49cb2d --- /dev/null +++ b/resources/src/jquery/jquery.accessKeyLabel.js @@ -0,0 +1,200 @@ +/** + * jQuery plugin to update the tooltip to show the correct access key + * + * @class jQuery.plugin.accessKeyLabel + */ +( function ( $, mw ) { + +// Cached access key prefix for used browser +var cachedAccessKeyPrefix, + + // Wether to use 'test-' instead of correct prefix (used for testing) + useTestPrefix = false, + + // tag names which can have a label tag + // https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_categories#Form-associated_content + labelable = 'button, input, textarea, keygen, meter, output, progress, select'; + +/** + * Get the prefix for the access key for browsers that don't support accessKeyLabel. + * + * For browsers that support accessKeyLabel, #getAccessKeyLabel never calls here. + * + * @private + * @param {Object} [ua] An object with a 'userAgent' and 'platform' property. + * @return {string} Access key prefix + */ +function getAccessKeyPrefix( ua ) { + // use cached prefix if possible + if ( !ua && cachedAccessKeyPrefix ) { + return cachedAccessKeyPrefix; + } + + var profile = $.client.profile( ua ), + accessKeyPrefix = 'alt-'; + + // Opera on any platform + if ( profile.name === 'opera' ) { + accessKeyPrefix = 'shift-esc-'; + + // Chrome on any platform + } else if ( profile.name === 'chrome' ) { + accessKeyPrefix = ( + profile.platform === 'mac' + // Chrome on Mac + ? 'ctrl-option-' + // Chrome on Windows or Linux + // (both alt- and alt-shift work, but alt with E, D, F etc does not + // work since they are browser shortcuts) + : 'alt-shift-' + ); + + // Non-Windows Safari with webkit_version > 526 + } else if ( profile.platform !== 'win' + && profile.name === 'safari' + && profile.layoutVersion > 526 + ) { + accessKeyPrefix = 'ctrl-alt-'; + + // Safari/Konqueror on any platform, or any browser on Mac + // (but not Safari on Windows) + } else if ( !( profile.platform === 'win' && profile.name === 'safari' ) + && ( profile.name === 'safari' + || profile.platform === 'mac' + || profile.name === 'konqueror' ) + ) { + accessKeyPrefix = 'ctrl-'; + + // Firefox/Iceweasel 2.x and later + } else if ( ( profile.name === 'firefox' || profile.name === 'iceweasel' ) + && profile.versionBase > '1' + ) { + accessKeyPrefix = 'alt-shift-'; + } + + // cache prefix + if ( !ua ) { + cachedAccessKeyPrefix = accessKeyPrefix; + } + return accessKeyPrefix; +} + +/** + * Get the access key label for an element. + * + * Will use native accessKeyLabel if available (currently only in Firefox 8+), + * falls back to #getAccessKeyPrefix. + * + * @private + * @param {HTMLElement} element Element to get the label for + * @return {string} Access key label + */ +function getAccessKeyLabel( element ) { + // abort early if no access key + if ( !element.accessKey ) { + return ''; + } + // use accessKeyLabel if possible + // http://www.whatwg.org/specs/web-apps/current-work/multipage/editing.html#dom-accesskeylabel + if ( !useTestPrefix && element.accessKeyLabel ) { + return element.accessKeyLabel; + } + return ( useTestPrefix ? 'test-' : getAccessKeyPrefix() ) + element.accessKey; +} + +/** + * Update the title for an element (on the element with the access key or it's label) to show + * the correct access key label. + * + * @private + * @param {HTMLElement} element Element with the accesskey + * @param {HTMLElement} titleElement Element with the title to update (may be the same as `element`) + */ +function updateTooltipOnElement( element, titleElement ) { + var array = ( mw.msg( 'word-separator' ) + mw.msg( 'brackets' ) ).split( '$1' ), + regexp = new RegExp( $.map( array, $.escapeRE ).join( '.*?' ) + '$' ), + oldTitle = titleElement.title, + rawTitle = oldTitle.replace( regexp, '' ), + newTitle = rawTitle, + accessKeyLabel = getAccessKeyLabel( element ); + + // don't add a title if the element didn't have one before + if ( !oldTitle ) { + return; + } + + if ( accessKeyLabel ) { + // Should be build the same as in Linker::titleAttrib + newTitle += mw.msg( 'word-separator' ) + mw.msg( 'brackets', accessKeyLabel ); + } + if ( oldTitle !== newTitle ) { + titleElement.title = newTitle; + } +} + +/** + * Update the title for an element to show the correct access key label. + * + * @private + * @param {HTMLElement} element Element with the accesskey + */ +function updateTooltip( element ) { + var id, $element, $label, $labelParent; + updateTooltipOnElement( element, element ); + + // update associated label if there is one + $element = $( element ); + if ( $element.is( labelable ) ) { + // Search it using 'for' attribute + id = element.id.replace( /"/g, '\\"' ); + if ( id ) { + $label = $( 'label[for="' + id + '"]' ); + if ( $label.length === 1 ) { + updateTooltipOnElement( element, $label[0] ); + } + } + + // Search it as parent, because the form control can also be inside the label element itself + $labelParent = $element.parents( 'label' ); + if ( $labelParent.length === 1 ) { + updateTooltipOnElement( element, $labelParent[0] ); + } + } +} + +/** + * Update the titles for all elements in a jQuery selection. + * + * @return {jQuery} + * @chainable + */ +$.fn.updateTooltipAccessKeys = function () { + return this.each( function () { + updateTooltip( this ); + } ); +}; + +/** + * Exposed for testing. + * + * @method updateTooltipAccessKeys_getAccessKeyPrefix + * @inheritdoc #getAccessKeyPrefix + */ +$.fn.updateTooltipAccessKeys.getAccessKeyPrefix = getAccessKeyPrefix; + +/** + * Switch test mode on and off. + * + * @method updateTooltipAccessKeys_setTestMode + * @param {boolean} mode New mode + */ +$.fn.updateTooltipAccessKeys.setTestMode = function ( mode ) { + useTestPrefix = mode; +}; + +/** + * @class jQuery + * @mixins jQuery.plugin.accessKeyLabel + */ + +}( jQuery, mediaWiki ) ); diff --git a/resources/src/jquery/jquery.arrowSteps.css b/resources/src/jquery/jquery.arrowSteps.css new file mode 100644 index 00000000..f8f6e951 --- /dev/null +++ b/resources/src/jquery/jquery.arrowSteps.css @@ -0,0 +1,45 @@ +.arrowSteps { + list-style-type: none; + list-style-image: none; + border: 1px solid #666666; + position: relative; +} + +.arrowSteps li { + float: left; + padding: 0px; + margin: 0px; + border: 0 none; +} + +.arrowSteps li div { + padding: 0.5em; + text-align: center; + white-space: nowrap; + overflow: hidden; +} + +.arrowSteps li.arrow div { + /* @embed */ + background: url(images/jquery.arrowSteps.divider-ltr.png) no-repeat right center; +} + +/* applied to the element preceding the highlighted step */ +.arrowSteps li.arrow.tail div { + /* @embed */ + background: url(images/jquery.arrowSteps.tail-ltr.png) no-repeat right center; +} + +/* this applies to all highlighted, including the last */ +.arrowSteps li.head div { + /* @embed */ + background: url(images/jquery.arrowSteps.head-ltr.png) no-repeat left center; + font-weight: bold; +} + +/* this applies to all highlighted arrows except the last */ +.arrowSteps li.arrow.head div { + /* TODO: eliminate duplication of jquery.arrowSteps.head.png embedding */ + /* @embed */ + background: url(images/jquery.arrowSteps.head-ltr.png) no-repeat right center; +} diff --git a/resources/src/jquery/jquery.arrowSteps.js b/resources/src/jquery/jquery.arrowSteps.js new file mode 100644 index 00000000..f8641e10 --- /dev/null +++ b/resources/src/jquery/jquery.arrowSteps.js @@ -0,0 +1,98 @@ +/*! + * jQuery arrowSteps plugin + * Copyright Neil Kandalgaonkar, 2010 + * + * This work is licensed under the terms of the GNU General Public License, + * version 2 or later. + * (see http://www.fsf.org/licensing/licenses/gpl.html). + * Derivative works and later versions of the code must be free software + * licensed under the same or a compatible license. + */ + +/** + * @class jQuery.plugin.arrowSteps + */ +( function ( $ ) { + /** + * Show users their progress through a series of steps, via a row of items that fit + * together like arrows. One item can be highlighted at a time. + * + * + * + * + * + * @return {jQuery} + * @chainable + */ + $.fn.arrowSteps = function () { + var $steps, width, arrowWidth, $stepDiv, + $el = this, + paddingSide = $( 'body' ).hasClass( 'rtl' ) ? 'padding-left' : 'padding-right'; + + $el.addClass( 'arrowSteps' ); + $steps = $el.find( 'li' ); + + width = parseInt( 100 / $steps.length, 10 ); + $steps.css( 'width', width + '%' ); + + // Every step except the last one has an arrow pointing forward: + // at the right hand side in LTR languages, and at the left hand side in RTL. + // Also add in the padding for the calculated arrow width. + $stepDiv = $steps.filter( ':not(:last-child)' ).addClass( 'arrow' ).find( 'div' ); + + // Execute when complete page is fully loaded, including all frames, objects and images + $( window ).load( function () { + arrowWidth = parseInt( $el.outerHeight(), 10 ); + $stepDiv.css( paddingSide, arrowWidth.toString() + 'px' ); + } ); + + $el.data( 'arrowSteps', $steps ); + + return this; + }; + + /** + * Highlights the element selected by the selector. + * + * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#guard' ); + * // 'Guard!' is highlighted. + * + * // ... user completes the 'guard' step ... + * + * $( '#robin-hood-daffy' ).arrowStepsHighlight( '#turn' ); + * // 'Turn!' is highlighted. + * + * @param {string} selector + */ + $.fn.arrowStepsHighlight = function ( selector ) { + var $previous, + $steps = this.data( 'arrowSteps' ); + $.each( $steps, function ( i, step ) { + var $step = $( step ); + if ( $step.is( selector ) ) { + if ($previous) { + $previous.addClass( 'tail' ); + } + $step.addClass( 'head' ); + } else { + $step.removeClass( 'head tail lasthead' ); + } + $previous = $step; + } ); + }; + + /** + * @class jQuery + * @mixins jQuery.plugin.arrowSteps + */ +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.autoEllipsis.js b/resources/src/jquery/jquery.autoEllipsis.js new file mode 100644 index 00000000..9a196b5d --- /dev/null +++ b/resources/src/jquery/jquery.autoEllipsis.js @@ -0,0 +1,168 @@ +/** + * @class jQuery.plugin.autoEllipsis + */ +( function ( $ ) { + +var + // Cache ellipsed substrings for every string-width-position combination + cache = {}, + + // Use a separate cache when match highlighting is enabled + matchTextCache = {}; + +/** + * Automatically truncate the plain text contents of an element and add an ellipsis + * + * @param {Object} options + * @param {'center'|'left'|'right'} [options.position='center'] Where to remove text. + * @param {boolean} [options.tooltip=false] Whether to show a tooltip with the remainder + * of the text. + * @param {boolean} [options.restoreText=false] Whether to save the text for restoring + * later. + * @param {boolean} [options.hasSpan=false] Whether the element is already a container, + * or if the library should create a new container for it. + * @param {string|null} [options.matchText=null] Text to highlight, e.g. search terms. + * @return {jQuery} + * @chainable + */ +$.fn.autoEllipsis = function ( options ) { + options = $.extend( { + position: 'center', + tooltip: false, + restoreText: false, + hasSpan: false, + matchText: null + }, options ); + + return this.each( function () { + var $trimmableText, + text, trimmableText, w, pw, + l, r, i, side, m, + // container element - used for measuring against + $container = $( this ); + + if ( options.restoreText ) { + if ( !$container.data( 'autoEllipsis.originalText' ) ) { + $container.data( 'autoEllipsis.originalText', $container.text() ); + } else { + $container.text( $container.data( 'autoEllipsis.originalText' ) ); + } + } + + // trimmable text element - only the text within this element will be trimmed + if ( options.hasSpan ) { + $trimmableText = $container.children( options.selector ); + } else { + $trimmableText = $( '' ) + .css( 'whiteSpace', 'nowrap' ) + .text( $container.text() ); + $container + .empty() + .append( $trimmableText ); + } + + text = $container.text(); + trimmableText = $trimmableText.text(); + w = $container.width(); + pw = 0; + + // Try cache + if ( options.matchText ) { + if ( !( text in matchTextCache ) ) { + matchTextCache[text] = {}; + } + if ( !( options.matchText in matchTextCache[text] ) ) { + matchTextCache[text][options.matchText] = {}; + } + if ( !( w in matchTextCache[text][options.matchText] ) ) { + matchTextCache[text][options.matchText][w] = {}; + } + if ( options.position in matchTextCache[text][options.matchText][w] ) { + $container.html( matchTextCache[text][options.matchText][w][options.position] ); + if ( options.tooltip ) { + $container.attr( 'title', text ); + } + return; + } + } else { + if ( !( text in cache ) ) { + cache[text] = {}; + } + if ( !( w in cache[text] ) ) { + cache[text][w] = {}; + } + if ( options.position in cache[text][w] ) { + $container.html( cache[text][w][options.position] ); + if ( options.tooltip ) { + $container.attr( 'title', text ); + } + return; + } + } + + if ( $trimmableText.width() + pw > w ) { + switch ( options.position ) { + case 'right': + // Use binary search-like technique for efficiency + l = 0; + r = trimmableText.length; + do { + m = Math.ceil( ( l + r ) / 2 ); + $trimmableText.text( trimmableText.slice( 0, m ) + '...' ); + if ( $trimmableText.width() + pw > w ) { + // Text is too long + r = m - 1; + } else { + l = m; + } + } while ( l < r ); + $trimmableText.text( trimmableText.slice( 0, l ) + '...' ); + break; + case 'center': + // TODO: Use binary search like for 'right' + i = [Math.round( trimmableText.length / 2 ), Math.round( trimmableText.length / 2 )]; + // Begin with making the end shorter + side = 1; + while ( $trimmableText.outerWidth() + pw > w && i[0] > 0 ) { + $trimmableText.text( trimmableText.slice( 0, i[0] ) + '...' + trimmableText.slice( i[1] ) ); + // Alternate between trimming the end and begining + if ( side === 0 ) { + // Make the begining shorter + i[0]--; + side = 1; + } else { + // Make the end shorter + i[1]++; + side = 0; + } + } + break; + case 'left': + // TODO: Use binary search like for 'right' + r = 0; + while ( $trimmableText.outerWidth() + pw > w && r < trimmableText.length ) { + $trimmableText.text( '...' + trimmableText.slice( r ) ); + r++; + } + break; + } + } + if ( options.tooltip ) { + $container.attr( 'title', text ); + } + if ( options.matchText ) { + $container.highlightText( options.matchText ); + matchTextCache[text][options.matchText][w][options.position] = $container.html(); + } else { + cache[text][w][options.position] = $container.html(); + } + + } ); +}; + +/** + * @class jQuery + * @mixins jQuery.plugin.autoEllipsis + */ + +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.badge.css b/resources/src/jquery/jquery.badge.css new file mode 100644 index 00000000..fa7ea702 --- /dev/null +++ b/resources/src/jquery/jquery.badge.css @@ -0,0 +1,36 @@ +.mw-badge { + min-width: 7px; + border-radius: 2px; + padding: 1px 4px; + text-align: center; + font-size: 12px; + line-height: 12px; + background-color: #d2d2d2; + cursor: pointer; +} + +.mw-badge-content { + font-weight: bold; + color: white; + vertical-align: baseline; + text-shadow: 0 1px rgba(0, 0, 0, 0.4); +} + +.mw-badge-inline { + margin-left: 3px; + display: inline-block; + /* Hack for IE6 and IE7 (bug 47926) */ + zoom: 1; + *display: inline; + +} +.mw-badge-overlay { + position: absolute; + bottom: -1px; + right: -3px; + z-index: 50; +} + +.mw-badge-important { + background-color: #cc0000; +} diff --git a/resources/src/jquery/jquery.badge.js b/resources/src/jquery/jquery.badge.js new file mode 100644 index 00000000..023b6e28 --- /dev/null +++ b/resources/src/jquery/jquery.badge.js @@ -0,0 +1,88 @@ +/*! + * jQuery Badge plugin + * + * @license MIT + * + * @author Ryan Kaldari , 2012 + * @author Andrew Garrett , 2012 + * @author Marius Hoch , 2012 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * This program is distributed WITHOUT ANY WARRANTY. + */ + +/** + * @class jQuery.plugin.badge + */ +( function ( $, mw ) { + /** + * Put a badge on an item on the page. The badge container will be appended to the selected element(s). + * + * $element.badge( text ); + * $element.badge( 5 ); + * $element.badge( '100+' ); + * $element.badge( text, inline ); + * $element.badge( 'New', true ); + * + * @param {number|string} text The value to display in the badge. If the value is falsey (0, + * null, false, '', etc.), any existing badge will be removed. + * @param {boolean} [inline=true] True if the badge should be displayed inline, false + * if the badge should overlay the parent element. + * @param {boolean} [displayZero=false] True if the number zero should be displayed, + * false if the number zero should result in the badge being hidden + * @return {jQuery} + * @chainable + */ + $.fn.badge = function ( text, inline, displayZero ) { + var $badge = this.find( '.mw-badge' ), + badgeStyleClass = 'mw-badge-' + ( inline ? 'inline' : 'overlay' ), + isImportant = true, displayBadge = true; + + // If we're displaying zero, ensure style to be non-important + if ( mw.language.convertNumber( text, true ) === 0 ) { + isImportant = false; + if ( !displayZero ) { + displayBadge = false; + } + // If text is falsey (besides 0), hide the badge + } else if ( !text ) { + displayBadge = false; + } + + if ( displayBadge ) { + // If a badge already exists, reuse it + if ( $badge.length ) { + $badge + .toggleClass( 'mw-badge-important', isImportant ) + .find( '.mw-badge-content' ) + .text( text ); + } else { + // Otherwise, create a new badge with the specified text and style + $badge = $( '
' ) + .addClass( badgeStyleClass ) + .toggleClass( 'mw-badge-important', isImportant ) + .append( + $( '' ).text( text ) + ) + .appendTo( this ); + } + } else { + $badge.remove(); + } + return this; + }; + + /** + * @class jQuery + * @mixins jQuery.plugin.badge + */ +}( jQuery, mediaWiki ) ); diff --git a/resources/src/jquery/jquery.byteLength.js b/resources/src/jquery/jquery.byteLength.js new file mode 100644 index 00000000..7fe25ee3 --- /dev/null +++ b/resources/src/jquery/jquery.byteLength.js @@ -0,0 +1,40 @@ +/** + * @class jQuery.plugin.byteLength + * @author Jan Paul Posma, 2011 + * @author Timo Tijhof, 2012 + * @author David Chan, 2013 + */ + +/** + * Calculate the byte length of a string (accounting for UTF-8). + * + * @static + * @inheritable + * @param {string} str + * @return {string} + */ +jQuery.byteLength = function ( str ) { + // This basically figures out how many bytes a UTF-16 string (which is what js sees) + // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that. + // Note, surrogate (\uD800-\uDFFF) characters are counted as 2 bytes, since there's two of them + // and the actual character takes 4 bytes in UTF-8 (2*2=4). Might not work perfectly in + // edge cases such as illegal sequences, but that should never happen. + + // https://en.wikipedia.org/wiki/UTF-8#Description + // The mapping from UTF-16 code units to UTF-8 bytes is as follows: + // > Range 0000-007F: codepoints that become 1 byte of UTF-8 + // > Range 0080-07FF: codepoints that become 2 bytes of UTF-8 + // > Range 0800-D7FF: codepoints that become 3 bytes of UTF-8 + // > Range D800-DFFF: Surrogates (each pair becomes 4 bytes of UTF-8) + // > Range E000-FFFF: codepoints that become 3 bytes of UTF-8 (continued) + + return str + .replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' ) + .replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' ) + .length; +}; + +/** + * @class jQuery + * @mixins jQuery.plugin.byteLength + */ diff --git a/resources/src/jquery/jquery.byteLimit.js b/resources/src/jquery/jquery.byteLimit.js new file mode 100644 index 00000000..5551232a --- /dev/null +++ b/resources/src/jquery/jquery.byteLimit.js @@ -0,0 +1,235 @@ +/** + * @class jQuery.plugin.byteLimit + */ +( function ( $ ) { + + /** + * Utility function to trim down a string, based on byteLimit + * and given a safe start position. It supports insertion anywhere + * in the string, so "foo" to "fobaro" if limit is 4 will result in + * "fobo", not "foba". Basically emulating the native maxlength by + * reconstructing where the insertion occurred. + * + * @private + * @param {string} safeVal Known value that was previously returned by this + * function, if none, pass empty string. + * @param {string} newVal New value that may have to be trimmed down. + * @param {number} byteLimit Number of bytes the value may be in size. + * @param {Function} [fn] See jQuery.byteLimit. + * @return {Object} + * @return {string} return.newVal + * @return {boolean} return.trimmed + */ + function trimValForByteLength( safeVal, newVal, byteLimit, fn ) { + var startMatches, endMatches, matchesLen, inpParts, + oldVal = safeVal; + + // Run the hook if one was provided, but only on the length + // assessment. The value itself is not to be affected by the hook. + if ( $.byteLength( fn ? fn( newVal ) : newVal ) <= byteLimit ) { + // Limit was not reached, just remember the new value + // and let the user continue. + return { + newVal: newVal, + trimmed: false + }; + } + + // Current input is longer than the active limit. + // Figure out what was added and limit the addition. + startMatches = 0; + endMatches = 0; + + // It is important that we keep the search within the range of + // the shortest string's length. + // Imagine a user adds text that matches the end of the old value + // (e.g. "foo" -> "foofoo"). startMatches would be 3, but without + // limiting both searches to the shortest length, endMatches would + // also be 3. + matchesLen = Math.min( newVal.length, oldVal.length ); + + // Count same characters from the left, first. + // (if "foo" -> "foofoo", assume addition was at the end). + while ( + startMatches < matchesLen && + oldVal.charAt( startMatches ) === newVal.charAt( startMatches ) + ) { + startMatches += 1; + } + + while ( + endMatches < ( matchesLen - startMatches ) && + oldVal.charAt( oldVal.length - 1 - endMatches ) === newVal.charAt( newVal.length - 1 - endMatches ) + ) { + endMatches += 1; + } + + inpParts = [ + // Same start + newVal.slice( 0, startMatches ), + // Inserted content + newVal.slice( startMatches, newVal.length - endMatches ), + // Same end + newVal.slice( newVal.length - endMatches ) + ]; + + // Chop off characters from the end of the "inserted content" string + // until the limit is statisfied. + if ( fn ) { + // stop, when there is nothing to slice - bug 41450 + while ( $.byteLength( fn( inpParts.join( '' ) ) ) > byteLimit && inpParts[1].length > 0 ) { + inpParts[1] = inpParts[1].slice( 0, -1 ); + } + } else { + while ( $.byteLength( inpParts.join( '' ) ) > byteLimit ) { + inpParts[1] = inpParts[1].slice( 0, -1 ); + } + } + + newVal = inpParts.join( '' ); + + return { + newVal: newVal, + trimmed: true + }; + } + + var eventKeys = [ + 'keyup.byteLimit', + 'keydown.byteLimit', + 'change.byteLimit', + 'mouseup.byteLimit', + 'cut.byteLimit', + 'paste.byteLimit', + 'focus.byteLimit', + 'blur.byteLimit' + ].join( ' ' ); + + /** + * Enforces a byte limit on an input field, so that UTF-8 entries are counted as well, + * when, for example, a database field has a byte limit rather than a character limit. + * Plugin rationale: Browser has native maxlength for number of characters, this plugin + * exists to limit number of bytes instead. + * + * Can be called with a custom limit (to use that limit instead of the maxlength attribute + * value), a filter function (in case the limit should apply to something other than the + * exact input value), or both. Order of parameters is important! + * + * @param {number} [limit] Limit to enforce, fallsback to maxLength-attribute, + * called with fetched value as argument. + * @param {Function} [fn] Function to call on the string before assessing the length. + * @return {jQuery} + * @chainable + */ + $.fn.byteLimit = function ( limit, fn ) { + // If the first argument is the function, + // set fn to the first argument's value and ignore the second argument. + if ( $.isFunction( limit ) ) { + fn = limit; + limit = undefined; + // Either way, verify it is a function so we don't have to call + // isFunction again after this. + } else if ( !fn || !$.isFunction( fn ) ) { + fn = undefined; + } + + // The following is specific to each element in the collection. + return this.each( function ( i, el ) { + var $el, elLimit, prevSafeVal; + + $el = $( el ); + + // If no limit was passed to byteLimit(), use the maxlength value. + // Can't re-use 'limit' variable because it's in the higher scope + // that would affect the next each() iteration as well. + // Note that we use attribute to read the value instead of property, + // because in Chrome the maxLength property by default returns the + // highest supported value (no indication that it is being enforced + // by choice). We don't want to bind all of this for some ridiculously + // high default number, unless it was explicitly set in the HTML. + // Also cast to a (primitive) number (most commonly because the maxlength + // attribute contains a string, but theoretically the limit parameter + // could be something else as well). + elLimit = Number( limit === undefined ? $el.attr( 'maxlength' ) : limit ); + + // If there is no (valid) limit passed or found in the property, + // skip this. The < 0 check is required for Firefox, which returns + // -1 (instead of undefined) for maxLength if it is not set. + if ( !elLimit || elLimit < 0 ) { + return; + } + + if ( fn ) { + // Save function for reference + $el.data( 'byteLimit.callback', fn ); + } + + // Remove old event handlers (if there are any) + $el.off( '.byteLimit' ); + + if ( fn ) { + // Disable the native maxLength (if there is any), because it interferes + // with the (differently calculated) byte limit. + // Aside from being differently calculated (average chars with byteLimit + // is lower), we also support a callback which can make it to allow longer + // values (e.g. count "Foo" from "User:Foo"). + // maxLength is a strange property. Removing or setting the property to + // undefined directly doesn't work. Instead, it can only be unset internally + // by the browser when removing the associated attribute (Firefox/Chrome). + // http://code.google.com/p/chromium/issues/detail?id=136004 + $el.removeAttr( 'maxlength' ); + + } else { + // If we don't have a callback the bytelimit can only be lower than the charlimit + // (that is, there are no characters less than 1 byte in size). So lets (re-)enforce + // the native limit for efficiency when possible (it will make the while-loop below + // faster by there being less left to interate over). + $el.attr( 'maxlength', elLimit ); + } + + // Safe base value, used to determine the path between the previous state + // and the state that triggered the event handler below - and enforce the + // limit approppiately (e.g. don't chop from the end if text was inserted + // at the beginning of the string). + prevSafeVal = ''; + + // We need to listen to after the change has already happened because we've + // learned that trying to guess the new value and canceling the event + // accordingly doesn't work because the new value is not always as simple as: + // oldValue + String.fromCharCode( e.which ); because of cut, paste, select-drag + // replacements, and custom input methods and what not. + // Even though we only trim input after it was changed (never prevent it), we do + // listen on events that input text, because there are cases where the text has + // changed while text is being entered and keyup/change will not be fired yet + // (such as holding down a single key, fires keydown, and after each keydown, + // we can trim the previous one). + // See http://www.w3.org/TR/DOM-Level-3-Events/#events-keyboard-event-order for + // the order and characteristics of the key events. + $el.on( eventKeys, function () { + var res = trimValForByteLength( + prevSafeVal, + this.value, + elLimit, + fn + ); + + // Only set value property if it was trimmed, because whenever the + // value property is set, the browser needs to re-initiate the text context, + // which moves the cursor at the end the input, moving it away from wherever it was. + // This is a side-effect of limiting after the fact. + if ( res.trimmed === true ) { + this.value = res.newVal; + } + // Always adjust prevSafeVal to reflect the input value. Not doing this could cause + // trimValForByteLength to compare the new value to an empty string instead of the + // old value, resulting in trimming always from the end (bug 40850). + prevSafeVal = res.newVal; + } ); + } ); + }; + + /** + * @class jQuery + * @mixins jQuery.plugin.byteLimit + */ +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.checkboxShiftClick.js b/resources/src/jquery/jquery.checkboxShiftClick.js new file mode 100644 index 00000000..d99e9f0a --- /dev/null +++ b/resources/src/jquery/jquery.checkboxShiftClick.js @@ -0,0 +1,43 @@ +/** + * @class jQuery.plugin.checkboxShiftClick + */ +( function ( $ ) { + + /** + * Enable checkboxes to be checked or unchecked in a row by clicking one, + * holding shift and clicking another one. + * + * @return {jQuery} + * @chainable + */ + $.fn.checkboxShiftClick = function () { + var prevCheckbox = null, + $box = this; + // When our boxes are clicked.. + $box.click( function ( e ) { + // And one has been clicked before... + if ( prevCheckbox !== null && e.shiftKey ) { + // Check or uncheck this one and all in-between checkboxes, + // except for disabled ones + $box + .slice( + Math.min( $box.index( prevCheckbox ), $box.index( e.target ) ), + Math.max( $box.index( prevCheckbox ), $box.index( e.target ) ) + 1 + ) + .filter( function () { + return !this.disabled; + } ) + .prop( 'checked', !!e.target.checked ); + } + // Either way, update the prevCheckbox variable to the one clicked now + prevCheckbox = e.target; + } ); + return $box; + }; + + /** + * @class jQuery + * @mixins jQuery.plugin.checkboxShiftClick + */ + +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.client.js b/resources/src/jquery/jquery.client.js new file mode 100644 index 00000000..662a6887 --- /dev/null +++ b/resources/src/jquery/jquery.client.js @@ -0,0 +1,301 @@ +/** + * User-agent detection + * + * @class jQuery.client + * @singleton + */ +( function ( $ ) { + + /** + * @private + * @property {Object} profileCache Keyed by userAgent string, + * value is the parsed $.client.profile object for that user agent. + */ + var profileCache = {}; + + $.client = { + + /** + * Get an object containing information about the client. + * + * @param {Object} [nav] An object with a 'userAgent' and 'platform' property. + * Defaults to the global `navigator` object. + * @return {Object} The resulting client object will be in the following format: + * + * { + * 'name': 'firefox', + * 'layout': 'gecko', + * 'layoutVersion': 20101026, + * 'platform': 'linux' + * 'version': '3.5.1', + * 'versionBase': '3', + * 'versionNumber': 3.5, + * } + */ + profile: function ( nav ) { + /*jshint boss: true */ + + if ( nav === undefined ) { + nav = window.navigator; + } + + // Use the cached version if possible + if ( profileCache[ nav.userAgent + '|' + nav.platform ] !== undefined ) { + return profileCache[ nav.userAgent + '|' + nav.platform ]; + } + + var + versionNumber, + key = nav.userAgent + '|' + nav.platform, + + // Configuration + + // Name of browsers or layout engines we don't recognize + uk = 'unknown', + // Generic version digit + x = 'x', + // Strings found in user agent strings that need to be conformed + wildUserAgents = ['Opera', 'Navigator', 'Minefield', 'KHTML', 'Chrome', 'PLAYSTATION 3', 'Iceweasel'], + // Translations for conforming user agent strings + userAgentTranslations = [ + // Tons of browsers lie about being something they are not + [/(Firefox|MSIE|KHTML,?\slike\sGecko|Konqueror)/, ''], + // Chrome lives in the shadow of Safari still + ['Chrome Safari', 'Chrome'], + // KHTML is the layout engine not the browser - LIES! + ['KHTML', 'Konqueror'], + // Firefox nightly builds + ['Minefield', 'Firefox'], + // This helps keep different versions consistent + ['Navigator', 'Netscape'], + // This prevents version extraction issues, otherwise translation would happen later + ['PLAYSTATION 3', 'PS3'] + ], + // Strings which precede a version number in a user agent string - combined and used as + // match 1 in version detection + versionPrefixes = [ + 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'netscape6', 'opera', 'version', 'konqueror', + 'lynx', 'msie', 'safari', 'ps3', 'android' + ], + // Used as matches 2, 3 and 4 in version extraction - 3 is used as actual version number + versionSuffix = '(\\/|\\;?\\s|)([a-z0-9\\.\\+]*?)(\\;|dev|rel|\\)|\\s|$)', + // Names of known browsers + names = [ + 'camino', 'chrome', 'firefox', 'iceweasel', 'netscape', 'konqueror', 'lynx', 'msie', 'opera', + 'safari', 'ipod', 'iphone', 'blackberry', 'ps3', 'rekonq', 'android' + ], + // Tanslations for conforming browser names + nameTranslations = [], + // Names of known layout engines + layouts = ['gecko', 'konqueror', 'msie', 'trident', 'opera', 'webkit'], + // Translations for conforming layout names + layoutTranslations = [ ['konqueror', 'khtml'], ['msie', 'trident'], ['opera', 'presto'] ], + // Names of supported layout engines for version number + layoutVersions = ['applewebkit', 'gecko', 'trident'], + // Names of known operating systems + platforms = ['win', 'wow64', 'mac', 'linux', 'sunos', 'solaris', 'iphone'], + // Translations for conforming operating system names + platformTranslations = [ ['sunos', 'solaris'], ['wow64', 'win'] ], + + /** + * Performs multiple replacements on a string + * @ignore + */ + translate = function ( source, translations ) { + var i; + for ( i = 0; i < translations.length; i++ ) { + source = source.replace( translations[i][0], translations[i][1] ); + } + return source; + }, + + // Pre-processing + + ua = nav.userAgent, + match, + name = uk, + layout = uk, + layoutversion = uk, + platform = uk, + version = x; + + if ( match = new RegExp( '(' + wildUserAgents.join( '|' ) + ')' ).exec( ua ) ) { + // Takes a userAgent string and translates given text into something we can more easily work with + ua = translate( ua, userAgentTranslations ); + } + // Everything will be in lowercase from now on + ua = ua.toLowerCase(); + + // Extraction + + if ( match = new RegExp( '(' + names.join( '|' ) + ')' ).exec( ua ) ) { + name = translate( match[1], nameTranslations ); + } + if ( match = new RegExp( '(' + layouts.join( '|' ) + ')' ).exec( ua ) ) { + layout = translate( match[1], layoutTranslations ); + } + if ( match = new RegExp( '(' + layoutVersions.join( '|' ) + ')\\\/(\\d+)').exec( ua ) ) { + layoutversion = parseInt( match[2], 10 ); + } + if ( match = new RegExp( '(' + platforms.join( '|' ) + ')' ).exec( nav.platform.toLowerCase() ) ) { + platform = translate( match[1], platformTranslations ); + } + if ( match = new RegExp( '(' + versionPrefixes.join( '|' ) + ')' + versionSuffix ).exec( ua ) ) { + version = match[3]; + } + + // Edge Cases -- did I mention about how user agent string lie? + + // Decode Safari's crazy 400+ version numbers + if ( name === 'safari' && version > 400 ) { + version = '2.0'; + } + // Expose Opera 10's lies about being Opera 9.8 + if ( name === 'opera' && version >= 9.8 ) { + match = ua.match( /\bversion\/([0-9\.]*)/ ); + if ( match && match[1] ) { + version = match[1]; + } else { + version = '10'; + } + } + // And Opera 15's lies about being Chrome + if ( name === 'chrome' && ( match = ua.match( /\bopr\/([0-9\.]*)/ ) ) ) { + if ( match[1] ) { + name = 'opera'; + version = match[1]; + } + } + // And IE 11's lies about being not being IE + if ( layout === 'trident' && layoutversion >= 7 && ( match = ua.match( /\brv[ :\/]([0-9\.]*)/ ) ) ) { + if ( match[1] ) { + name = 'msie'; + version = match[1]; + } + } + // And Amazon Silk's lies about being Android on mobile or Safari on desktop + if ( match = ua.match( /\bsilk\/([0-9.\-_]*)/ ) ) { + if ( match[1] ) { + name = 'silk'; + version = match[1]; + } + } + + versionNumber = parseFloat( version, 10 ) || 0.0; + + // Caching + + return profileCache[ key ] = { + name: name, + layout: layout, + layoutVersion: layoutversion, + platform: platform, + version: version, + versionBase: ( version !== x ? Math.floor( versionNumber ).toString() : x ), + versionNumber: versionNumber + }; + }, + + /** + * Checks the current browser against a support map object. + * + * Version numbers passed as numeric values will be compared like numbers (1.2 > 1.11). + * Version numbers passed as string values will be compared using a simple component-wise + * algorithm, similar to PHP's version_compare ('1.2' < '1.11'). + * + * A browser map is in the following format: + * + * { + * // Multiple rules with configurable operators + * 'msie': [['>=', 7], ['!=', 9]], + * // Match no versions + * 'iphone': false, + * // Match any version + * 'android': null + * } + * + * It can optionally be split into ltr/rtl sections: + * + * { + * 'ltr': { + * 'android': null, + * 'iphone': false + * }, + * 'rtl': { + * 'android': false, + * // rules are not inherited from ltr + * 'iphone': false + * } + * } + * + * @param {Object} map Browser support map + * @param {Object} [profile] A client-profile object + * @param {boolean} [exactMatchOnly=false] Only return true if the browser is matched, otherwise + * returns true if the browser is not found. + * + * @return {boolean} The current browser is in the support map + */ + test: function ( map, profile, exactMatchOnly ) { + /*jshint evil: true */ + + var conditions, dir, i, op, val, j, pieceVersion, pieceVal, compare; + profile = $.isPlainObject( profile ) ? profile : $.client.profile(); + if ( map.ltr && map.rtl ) { + dir = $( 'body' ).is( '.rtl' ) ? 'rtl' : 'ltr'; + map = map[dir]; + } + // Check over each browser condition to determine if we are running in a compatible client + if ( typeof map !== 'object' || map[profile.name] === undefined ) { + // Not found, return true if exactMatchOnly not set, false otherwise + return !exactMatchOnly; + } + conditions = map[profile.name]; + if ( conditions === false ) { + // Match no versions + return false; + } + if ( conditions === null ) { + // Match all versions + return true; + } + for ( i = 0; i < conditions.length; i++ ) { + op = conditions[i][0]; + val = conditions[i][1]; + if ( typeof val === 'string' ) { + // Perform a component-wise comparison of versions, similar to PHP's version_compare + // but simpler. '1.11' is larger than '1.2'. + pieceVersion = profile.version.toString().split( '.' ); + pieceVal = val.split( '.' ); + // Extend with zeroes to equal length + while ( pieceVersion.length < pieceVal.length ) { + pieceVersion.push( '0' ); + } + while ( pieceVal.length < pieceVersion.length ) { + pieceVal.push( '0' ); + } + // Compare components + compare = 0; + for ( j = 0; j < pieceVersion.length; j++ ) { + if ( Number( pieceVersion[j] ) < Number( pieceVal[j] ) ) { + compare = -1; + break; + } else if ( Number( pieceVersion[j] ) > Number( pieceVal[j] ) ) { + compare = 1; + break; + } + } + // compare will be -1, 0 or 1, depending on comparison result + if ( !( eval( '' + compare + op + '0' ) ) ) { + return false; + } + } else if ( typeof val === 'number' ) { + if ( !( eval( 'profile.versionNumber' + op + val ) ) ) { + return false; + } + } + } + + return true; + } + }; +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.color.js b/resources/src/jquery/jquery.color.js new file mode 100644 index 00000000..04f8047b --- /dev/null +++ b/resources/src/jquery/jquery.color.js @@ -0,0 +1,55 @@ +/** + * jQuery Color Animations + * + * @author John Resig, 2007 + * @author Krinkle, 2011 + * Released under the MIT and GPL licenses. + * + * - 2011-01-05: Forked for MediaWiki. See also jQuery.colorUtil plugin + */ +( function ( $ ) { + + function getColor( elem, attr ) { + /*jshint boss:true */ + var color; + + do { + color = $.css( elem, attr ); + + // Keep going until we find an element that has color, or we hit the body + if ( color !== '' && color !== 'transparent' || $.nodeName( elem, 'body' ) ) { + break; + } + + attr = 'backgroundColor'; + } while ( elem = elem.parentNode ); + + return $.colorUtil.getRGB( color ); + } + + // We override the animation for all of these color styles + $.each([ + 'backgroundColor', + 'borderBottomColor', + 'borderLeftColor', + 'borderRightColor', + 'borderTopColor', + 'color', + 'outlineColor' + ], function ( i, attr ) { + $.fx.step[attr] = function ( fx ) { + if ( !fx.colorInit ) { + fx.start = getColor( fx.elem, attr ); + fx.end = $.colorUtil.getRGB( fx.end ); + fx.colorInit = true; + } + + fx.elem.style[attr] = 'rgb(' + [ + Math.max( Math.min( parseInt( (fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( (fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10 ), 255 ), 0 ), + Math.max( Math.min( parseInt( (fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10 ), 255 ), 0 ) + ].join( ',' ) + ')'; + }; + } ); + +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.colorUtil.js b/resources/src/jquery/jquery.colorUtil.js new file mode 100644 index 00000000..a6ff8bc8 --- /dev/null +++ b/resources/src/jquery/jquery.colorUtil.js @@ -0,0 +1,262 @@ +/*! + * jQuery Color Utilities + * + * Released under the MIT and GPL licenses. + * + * Mostly based on other plugins and functions (linted and optimized a little). + * Sources cited inline. + */ +( function ( $ ) { + /** + * @class jQuery.colorUtil + * @singleton + */ + $.colorUtil = { + + /** + * Parse CSS color strings looking for color tuples + * + * Based on highlightFade by Blair Mitchelmore + * + * + * @param {Array|string} color + * @return {Array} + */ + getRGB: function ( color ) { + /*jshint boss:true */ + var result; + + // Check if we're already dealing with an array of colors + if ( color && $.isArray( color ) && color.length === 3 ) { + return color; + } + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) { + return [ + parseInt( result[1], 10 ), + parseInt( result[2], 10 ), + parseInt( result[3], 10 ) + ]; + } + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) { + return [ + parseFloat( result[1] ) * 2.55, + parseFloat( result[2] ) * 2.55, + parseFloat( result[3] ) * 2.55 + ]; + } + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) { + return [ + parseInt( result[1], 16 ), + parseInt( result[2], 16 ), + parseInt( result[3], 16 ) + ]; + } + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) { + return [ + parseInt( result[1] + result[1], 16 ), + parseInt( result[2] + result[2], 16 ), + parseInt( result[3] + result[3], 16) + ]; + } + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) { + return $.colorUtil.colors.transparent; + } + + // Otherwise, we're most likely dealing with a named color + return $.colorUtil.colors[$.trim(color).toLowerCase()]; + }, + + /** + * Named color map + * + * Based on Interface by Stefan Petre + * + * + * @property {Object} + */ + colors: { + aqua: [0, 255, 255], + azure: [240, 255, 255], + beige: [245, 245, 220], + black: [0, 0, 0], + blue: [0, 0, 255], + brown: [165, 42, 42], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgrey: [169, 169, 169], + darkgreen: [0, 100, 0], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkviolet: [148, 0, 211], + fuchsia: [255, 0, 255], + gold: [255, 215, 0], + green: [0, 128, 0], + indigo: [75, 0, 130], + khaki: [240, 230, 140], + lightblue: [173, 216, 230], + lightcyan: [224, 255, 255], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + navy: [0, 0, 128], + olive: [128, 128, 0], + orange: [255, 165, 0], + pink: [255, 192, 203], + purple: [128, 0, 128], + violet: [128, 0, 128], + red: [255, 0, 0], + silver: [192, 192, 192], + white: [255, 255, 255], + yellow: [255, 255, 0], + transparent: [255, 255, 255] + }, + + /** + * Convert an RGB color value to HSL. + * + * Conversion formula based on + * + * + * Adapted from . + * + * Assumes `r`, `g`, and `b` are contained in the set `[0, 255]` and + * returns `h`, `s`, and `l` in the set `[0, 1]`. + * + * @param {number} r The red color value + * @param {number} g The green color value + * @param {number} b The blue color value + * @return {number[]} The HSL representation + */ + rgbToHsl: function ( r, g, b ) { + r = r / 255; + g = g / 255; + b = b / 255; + + var d, + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + h, + s, + l = (max + min) / 2; + + if ( max === min ) { + // achromatic + h = s = 0; + } else { + d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch ( max ) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [h, s, l]; + }, + + /** + * Convert an HSL color value to RGB. + * + * Conversion formula based on + * + * + * Adapted from . + * + * Assumes `h`, `s`, and `l` are contained in the set `[0, 1]` and + * returns `r`, `g`, and `b` in the set `[0, 255]`. + * + * @param {number} h The hue + * @param {number} s The saturation + * @param {number} l The lightness + * @return {number[]} The RGB representation + */ + hslToRgb: function ( h, s, l ) { + var r, g, b, hue2rgb, q, p; + + if ( s === 0 ) { + r = g = b = l; // achromatic + } else { + hue2rgb = function ( p, q, t ) { + if ( t < 0 ) { + t += 1; + } + if ( t > 1 ) { + t -= 1; + } + if ( t < 1 / 6 ) { + return p + (q - p) * 6 * t; + } + if ( t < 1 / 2 ) { + return q; + } + if ( t < 2 / 3 ) { + return p + (q - p) * (2 / 3 - t) * 6; + } + return p; + }; + + q = l < 0.5 ? l * (1 + s) : l + s - l * s; + p = 2 * l - q; + r = hue2rgb( p, q, h + 1 / 3 ); + g = hue2rgb( p, q, h ); + b = hue2rgb( p, q, h - 1 / 3 ); + } + + return [r * 255, g * 255, b * 255]; + }, + + /** + * Get a brighter or darker rgb() value string. + * + * Usage: + * + * $.colorUtil.getColorBrightness( 'red', +0.1 ); + * // > "rgb(255,50,50)" + * $.colorUtil.getColorBrightness( 'rgb(200,50,50)', -0.2 ); + * // > "rgb(118,29,29)" + * + * @param {Mixed} currentColor Current value in css + * @param {number} mod Wanted brightness modification between -1 and 1 + * @return {string} Like `'rgb(r,g,b)'` + */ + getColorBrightness: function ( currentColor, mod ) { + var rgbArr = $.colorUtil.getRGB( currentColor ), + hslArr = $.colorUtil.rgbToHsl(rgbArr[0], rgbArr[1], rgbArr[2] ); + rgbArr = $.colorUtil.hslToRgb(hslArr[0], hslArr[1], hslArr[2] + mod); + + return 'rgb(' + + [parseInt( rgbArr[0], 10), parseInt( rgbArr[1], 10 ), parseInt( rgbArr[2], 10 )].join( ',' ) + + ')'; + } + + }; + +}( jQuery ) ); diff --git a/resources/src/jquery/jquery.confirmable.css b/resources/src/jquery/jquery.confirmable.css new file mode 100644 index 00000000..de690726 --- /dev/null +++ b/resources/src/jquery/jquery.confirmable.css @@ -0,0 +1,28 @@ +.jquery-confirmable-button { + /* Automatically flipped */ + margin-left: 1ex; +} + +.jquery-confirmable-wrapper { + /* Line breaks within the interface text are unpleasant */ + white-space: nowrap; + /* Hiding the original text when it slides to the left */ + overflow: hidden; +} + +.jquery-confirmable-wrapper, +.jquery-confirmable-element, +.jquery-confirmable-interface { + /* We need inline-block to be able to size the elements and calculate their dimensions */ + display: inline-block; + /* inline-block elements in this context align to baseline by default */ + vertical-align: bottom; +} + +.jquery-confirmable-element { + transition: margin 250ms cubic-bezier(0.2, 0.8, 0.2, 0.8); +} + +.jquery-confirmable-interface { + transition: width 250ms cubic-bezier(0.2, 0.8, 0.2, 0.8); +} diff --git a/resources/src/jquery/jquery.confirmable.js b/resources/src/jquery/jquery.confirmable.js new file mode 100644 index 00000000..339e65a4 --- /dev/null +++ b/resources/src/jquery/jquery.confirmable.js @@ -0,0 +1,170 @@ +/** + * jQuery confirmable plugin + * + * Released under the MIT License. + * + * @author Bartosz Dziewoński + * + * @class jQuery.plugin.confirmable + */ +( function ( $ ) { + var identity = function ( data ) { + return data; + }; + + /** + * Enable inline confirmation for given clickable element (like `` or `