Merge "mediawiki.inspect: Fix exception when calling mw.inspect() a second time"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 27 Jun 2018 07:19:09 +0000 (07:19 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 27 Jun 2018 07:19:09 +0000 (07:19 +0000)
26 files changed:
includes/api/ApiOptions.php
includes/api/i18n/fr.json
includes/changes/ChangesList.php
includes/changes/EnhancedChangesList.php
includes/changes/OldChangesList.php
includes/templates/EnhancedChangesListGroup.mustache
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/es.json
languages/i18n/gcr.json
languages/i18n/got.json
languages/i18n/he.json
languages/i18n/my.json
languages/i18n/sr-ec.json
languages/i18n/yi.json
resources/Resources.php
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.mixins.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ChangesListWrapperWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterTagMultiselectWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js [new file with mode: 0644]
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.ItemMenuOptionWidget.js
resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MenuSelectWidget.js

index f30b44c..fe7d10d 100644 (file)
@@ -29,11 +29,15 @@ use MediaWiki\MediaWikiServices;
  * @ingroup API
  */
 class ApiOptions extends ApiBase {
+       /** @var User User account to modify */
+       private $userForUpdates;
+
        /**
         * Changes preferences of the current user.
         */
        public function execute() {
-               if ( $this->getUser()->isAnon() ) {
+               $user = $this->getUserForUpdates();
+               if ( !$user || $user->isAnon() ) {
                        $this->dieWithError(
                                [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin'
                        );
@@ -48,16 +52,8 @@ class ApiOptions extends ApiBase {
                        $this->dieWithError( [ 'apierror-missingparam', 'optionname' ] );
                }
 
-               // Load the user from the master to reduce CAS errors on double post (T95839)
-               $user = $this->getUser()->getInstanceForUpdate();
-               if ( !$user ) {
-                       $this->dieWithError(
-                               [ 'apierror-mustbeloggedin', $this->msg( 'action-editmyoptions' ) ], 'notloggedin'
-                       );
-               }
-
                if ( $params['reset'] ) {
-                       $user->resetOptions( $params['resetkinds'], $this->getContext() );
+                       $this->resetPreferences( $params['resetkinds'] );
                        $changed = true;
                }
 
@@ -76,8 +72,7 @@ class ApiOptions extends ApiBase {
                        $this->dieWithError( 'apierror-nochanges' );
                }
 
-               $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
-               $prefs = $preferencesFactory->getFormDescriptor( $user, $this->getContext() );
+               $prefs = $this->getPreferences();
                $prefsKinds = $user->getOptionKinds( $this->getContext(), $changes );
 
                $htmlForm = null;
@@ -117,7 +112,7 @@ class ApiOptions extends ApiBase {
                                        break;
                        }
                        if ( $validation === true ) {
-                               $user->setOption( $key, $value );
+                               $this->setPreference( $key, $value );
                                $changed = true;
                        } else {
                                $this->addWarning( [ 'apiwarn-validationfailed', wfEscapeWikiText( $key ), $validation ] );
@@ -125,13 +120,59 @@ class ApiOptions extends ApiBase {
                }
 
                if ( $changed ) {
-                       // Commit changes
-                       $user->saveSettings();
+                       $this->commitChanges();
                }
 
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
        }
 
+       /**
+        * Load the user from the master to reduce CAS errors on double post (T95839)
+        *
+        * @return null|User
+        */
+       protected function getUserForUpdates() {
+               if ( !$this->userForUpdates ) {
+                       $this->userForUpdates = $this->getUser()->getInstanceForUpdate();
+               }
+
+               return $this->userForUpdates;
+       }
+
+       /**
+        * Returns preferences form descriptor
+        * @return mixed[][]
+        */
+       protected function getPreferences() {
+               $preferencesFactory = MediaWikiServices::getInstance()->getPreferencesFactory();
+               return $preferencesFactory->getFormDescriptor( $this->getUserForUpdates(),
+                       $this->getContext() );
+       }
+
+       /**
+        * @param string[] $kinds One or more types returned by User::listOptionKinds() or 'all'
+        */
+       protected function resetPreferences( array $kinds ) {
+               $this->getUserForUpdates()->resetOptions( $kinds, $this->getContext() );
+       }
+
+       /**
+        * Sets one user preference to be applied by commitChanges()
+        *
+        * @param string $preference
+        * @param mixed $value
+        */
+       protected function setPreference( $preference, $value ) {
+               $this->getUserForUpdates()->setOption( $preference, $value );
+       }
+
+       /**
+        * Applies changes to user preferences
+        */
+       protected function commitChanges() {
+               $this->getUserForUpdates()->saveSettings();
+       }
+
        public function mustBePosted() {
                return true;
        }
index a80ff50..0759e35 100644 (file)
        "apihelp-query+filerepoinfo-param-prop": "Quelles propriétés récupérer du référentiel (les propriétés disponibles peuvent varier sur les autres wikis).",
        "apihelp-query+filerepoinfo-paramvalue-prop-apiurl": "URL vers l’API du dépôt — utile pour obtenir des informations sur l’image depuis l’hôte.",
        "apihelp-query+filerepoinfo-paramvalue-prop-articlepath": "<var>[[mw:Special:MyLanguage/Manual:$wgArticlePath|$wgArticlePath]]</var> du wiki du dépôt, ou équivalent.",
-       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Si les fichiers peuvent être téléchargés sur ce dépôt, par ex. via CORS et l’authentification partagée.",
+       "apihelp-query+filerepoinfo-paramvalue-prop-canUpload": "Si les fichiers peuvent être téléversés sur ce dépôt, par exemple via CORS et l’authentification partagée.",
        "apihelp-query+filerepoinfo-paramvalue-prop-displayname": "Le nom lisible du wiki du dépôt.",
        "apihelp-query+filerepoinfo-paramvalue-prop-favicon": "URL de l'icône favorite du dépôt du wiki, depuis <var>[[mw:Special:MyLanguage/Manual:$wgFavicon|$wgFavicon]]</var>.",
        "apihelp-query+filerepoinfo-paramvalue-prop-fetchDescription": "Si les pages de description de fichier sont récupérées de ce dépôt lors de l’affichage des pages de description de fichier locales.",
index 703acd6..0bf3eb4 100644 (file)
@@ -115,6 +115,31 @@ class ChangesList extends ContextSource {
                throw new RuntimeException( 'recentChangesLine should be implemented' );
        }
 
+       /**
+        * Get the container for highlights that are used in the new StructuredFilters
+        * system
+        *
+        * @return string HTML structure of the highlight container div
+        */
+       protected function getHighlightsContainerDiv() {
+               $highlightColorDivs = '';
+               foreach ( [ 'none', 'c1', 'c2', 'c3', 'c4', 'c5' ] as $color ) {
+                       $highlightColorDivs .= Html::rawElement(
+                               'div',
+                               [
+                                       'class' => 'mw-rcfilters-ui-highlights-color-' . $color,
+                                       'data-color' => $color
+                               ]
+                       );
+               }
+
+               return Html::rawElement(
+                       'div',
+                       [ 'class' => 'mw-rcfilters-ui-highlights' ],
+                       $highlightColorDivs
+               );
+       }
+
        /**
         * Sets the list to use a "<li class='watchlist-(namespace)-(page)'>" tag
         * @param bool $value
index 81eccbc..0c56fdd 100644 (file)
@@ -705,9 +705,14 @@ class EnhancedChangesList extends ChangesList {
                }
 
                $line = Html::openElement( 'table', $attribs ) . Html::openElement( 'tr' );
+               // Highlight block
+               $line .= Html::rawElement( 'td', [],
+                       $this->getHighlightsContainerDiv()
+               );
+
                $line .= Html::rawElement( 'td', [], '<span class="mw-enhancedchanges-arrow-space"></span>' );
                $line .= Html::rawElement( 'td', [ 'class' => 'mw-changeslist-line-prefix' ], $prefix );
-               $line .= '<td class="mw-enhanced-rc">';
+               $line .= '<td class="mw-enhanced-rc" colspan="2">';
 
                if ( isset( $data['recentChangesFlags'] ) ) {
                        $line .= $this->recentChangesFlags( $data['recentChangesFlags'] );
index 88c3c22..51ee481 100644 (file)
@@ -63,6 +63,7 @@ class OldChangesList extends ChangesList {
                $dateheader = ''; // $html now contains only <li>...</li>, for hooks' convenience.
                $this->insertDateHeader( $dateheader, $rc->mAttribs['rc_timestamp'] );
 
+               $html = $this->getHighlightsContainerDiv() . $html;
                $attribs['class'] = implode( ' ', $classes );
 
                return $dateheader . Html::rawElement( 'li', $attribs,  $html ) . "\n";
index 6493df8..24f0613 100644 (file)
@@ -1,10 +1,20 @@
 <table class="{{# tableClasses }}{{ . }} {{/ tableClasses }}" data-mw-ts="{{{ fullTimestamp }}}">
-       <tr>
+       <tr class="mw-rcfilters-ui-highlights-enhanced-toplevel">
+               <td>
+                       <div class="mw-rcfilters-ui-highlights">
+                               <div class="mw-rcfilters-ui-highlights-color-none" data-color="none"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c1" data-color="c1"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c2" data-color="c2"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c3" data-color="c3"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c4" data-color="c4"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c5" data-color="c5"></div>
+                       </div>
+               </td>
                <td>
                        <span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space"></span>
                </td>
                <td class="mw-changeslist-line-prefix">{{{ prefix }}}</td>
-               <td class="mw-enhanced-rc">{{{ collectedRcFlags }}}&#160;{{ timestamp }}&#160;</td>
+               <td class="mw-enhanced-rc" colspan="2">{{{ collectedRcFlags }}}&#160;{{ timestamp }}&#160;</td>
                <td class="mw-changeslist-line-inner">
                        {{# rev-deleted-event }}<span class="history-deleted">{{{ . }}}</span>{{/ rev-deleted-event }}
                        {{{ articleLink }}}{{{ languageDirMark }}}{{{ logText }}}
                </td>
        </tr>
        {{# lines }}
-       <tr class="{{# classes }}{{ . }} {{/ classes }}"{{{ attribs }}}>
+       <tr class="mw-rcfilters-ui-highlights-enhanced-nested {{# classes }}{{ . }} {{/ classes }}"{{{ attribs }}}>
+               <td></td>
                <td></td>
                <td></td>
                <td class="mw-enhanced-rc">{{{ recentChangesFlags }}}&#160;</td>
+               <td>
+                       <div class="mw-rcfilters-ui-highlights mw-enhanced-rc-nested">
+                               <div class="mw-rcfilters-ui-highlights-color-none" data-color="none"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c1" data-color="c1"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c2" data-color="c2"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c3" data-color="c3"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c4" data-color="c4"></div>
+                               <div class="mw-rcfilters-ui-highlights-color-c5" data-color="c5"></div>
+                       </div>
+               </td>
                <td class="mw-enhanced-rc-nested" data-target-page="{{ targetTitle }}">
                        {{# timestampLink }}
                        <span class="mw-enhanced-rc-time">{{{ . }}}</span>
index de9cec0..65c0f7b 100644 (file)
        "largefileserver": "Памер гэтага файлу перавышае максымальна дазволены сэрвэрам.",
        "emptyfile": "Загружаны файл, здаецца, пусты. Магчыма гэта адбылося з-за памылкі ў назьве файлу. Калі ласка, удакладніце, ці вы сапраўды жадаеце загрузіць гэты файл.",
        "windows-nonascii-filename": "Гэтая вікі не падтрымлівае назвы файлаў з спэцыяльнымі сымбалямі.",
-       "fileexists": "Файл з такой назвай ужо існуе. Калі ласка, праверце <strong>[[:$1]]</strong>, калі Вы ня ўпэўненыя, што жадаеце яго замяніць. [[$1|thumb]]",
+       "fileexists": "Файл з такой назвай ужо існуе. Калі ласка, праверце <strong>[[:$1]]</strong>, калі {{GENDER:|вы}} ня ўпэўненыя, што жадаеце яго замяніць.\n[[$1|thumb]]",
        "filepageexists": "Старонка апісаньня для гэтага файла ўжо існуе як <strong>[[:$1]]</strong>, але файла з такой назвай няма.\nАпісаньне якое Вы дадалі ня зьявіцца на старонцы апісаньня.\nКаб яно там зьявілася, Вам трэба рэдагаваць яе самастойна.\n[[$1|thumb]]",
        "fileexists-extension": "Файл з падобнай назвай ужо існуе: [[$2|thumb]]\n* Назва загружанага файла: <strong>[[:$1]]</strong>\n* Назва існуючага файла: <strong>[[:$2]]</strong>\nМагчыма, вы жадаеце выкарыстаць адрозную назву?",
        "fileexists-thumbnail-yes": "Верагодна файл зьяўляецца паменшанай копіяй ''(мініятурай)''. [[$1|thumb]]\nКалі ласка, праверце файл <strong>[[:$1]]</strong>.\nКалі правераны файл зьяўляецца той жа выявай, то загрузка мініятуры ня мае сэнсу.",
index 7585117..1a1084c 100644 (file)
        "cantrollback": "পূর্বের সংস্করণে ফেরত যাওয়া সম্ভব হল না, সর্বশেষ সম্পাদনাকারী এই নিবন্ধটির একমাত্র লেখক।",
        "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) দ্বারা সম্পাদিত [[:$1]]-এর সর্বশেষ সম্পাদনাটি পুনর্বহাল করা যাচ্ছে না;\nঅন্য কোন ব্যবহারকারী এই পাতা ইতিমধ্যে সম্পাদনা বা পুনর্বহাল করেছেন।\n\nএই পাতায় সর্বশেষ সম্পাদনা করেছেন [[User:$3|$3]] ([[User talk:$3|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])।",
        "editcomment": "সম্পাদনা সারাংশ ছিল: \"''$1''\"।",
-       "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]]) এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]] এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে।",
-       "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$1|$1]]}}-এর সর্বশেষ সম্পাদনায় ফেরত যাওয়া হয়েছে",
+       "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]])-এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]]-এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে",
+       "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$1|$1]]}}-এর সর্বশেষ সম্পাদনায় ফেরত যাওয়া হয়েছে",
        "rollback-success": "{{GENDER:$3|$1}}-এর সম্পাদনাগুলি পূর্বাবস্থায় ফিরিয়ে নেওয়া হয়েছে; {{GENDER:$4|$2}}-এর করা শেষ সংস্করণে পাতাটি ফেরত নেওয়া হয়েছে।",
        "rollback-success-notify": "$1-এর সম্পাদনাগুলি বাতিল করা হয়েছে; \n$2-এর করা শেষ সংস্করণে ফেরত নেওয়া হয়েছে। [$3 পরিবর্তন দেখুন]",
        "sessionfailure-title": "সেশন পরিত্যক্ত",
index 95f0955..f261f35 100644 (file)
                        "KATRINE1992",
                        "Athena in Wonderland",
                        "Truebamateo",
-                       "La Mantis"
+                       "La Mantis",
+                       "Amaia"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "converter-manual-rule-error": "Se ha detectado un error en una regla manual de conversión de idioma",
        "undo-success": "Puedes deshacer la edición. Antes de deshacer la edición, comprueba la siguiente comparación para verificar que realmente es lo que quieres hacer, y entonces guarda los cambios para así efectuar la reversión.",
        "undo-failure": "No se ha podido deshacer la edición ya que otro usuario ha realizado una edición intermedia.",
+       "undo-main-slot-only": "Aldaketa ezin da desegin, slot nagusitik kanpoko edukia daukalako.",
        "undo-norev": "No se ha podido deshacer la edición porque no existe o ha sido borrada.",
        "undo-nochange": "Parece que ya se había deshecho la edición.",
        "undo-summary": "Se ha deshecho la revisión $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc.]])",
index d1e6885..cb5ecd6 100644 (file)
@@ -50,7 +50,7 @@
        "tog-prefershttps": "Toujou itilizé roun konèksyon sékirizé lò mo konèkté",
        "underline-always": "Toujou",
        "underline-never": "Janmè",
-       "underline-default": "Valò pa défo di tenm ou di navigatò",
+       "underline-default": "Valò pa défo di tenm oben di navigatò",
        "editfont-style": "Stil di polis di zonn di modifikasyon",
        "editfont-monospace": "Polis ké chas fiks",
        "editfont-sansserif": "Polis sans-serif",
        "booksources-search-legend": "Sasé parmi dé ouvraj di référans",
        "booksources-search": "Sasé",
        "specialloguserlabel": "Otò :",
-       "speciallogtitlelabel": "Sib (tit ou {{ns:user}}:non di itilizatò) :",
+       "speciallogtitlelabel": "Sib (tit oben {{ns:user}}:non di itilizatò) :",
        "log": "Journal d’opérasyon",
        "all-logs-page": "Tout journal piblik",
        "alllogstext": "Afichaj konbiné di tout journal disponib asou {{SITENAME}}.\nZòt pouvé pèrsonalizé afichaj an sélèksyonnan tip di journal, non di itilizatò oben paj-a ki konsèrné (sa Dé dannyé sa sansib à lakas).",
        "sp-contributions-logs": "journal",
        "sp-contributions-talk": "diskité",
        "sp-contributions-search": "Sasé kontribisyon-yan",
-       "sp-contributions-username": "Adrès IP ou non di itilizatò :",
+       "sp-contributions-username": "Adrès IP oben non di itilizatò :",
        "sp-contributions-toponly": "Montré ki kontribisyon-yan ki sa dannyé-ya dé artik",
        "sp-contributions-newonly": "Afiché inikman modifikasyon-yan ki sa dé kréyasyon di paj",
        "sp-contributions-submit": "Sasé",
index 2236e97..53e2ef5 100644 (file)
        "imagepage": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐍆𐌰𐌾𐌻𐌰𐌻𐌰𐌿𐍆",
        "mediawikipage": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐍅𐌰𐌿𐍂𐌳𐌰𐌻𐌰𐌿𐍆",
        "viewhelppage": "𐌰𐌽𐌳𐌷𐌿𐌻𐌴𐌹 𐌷𐌹𐌻𐍀𐌰𐌻𐌰𐌿𐍆",
+       "categorypage": "𐍃𐌰𐌹𐍈 𐌺𐌿𐌽𐌾𐌰𐌻𐌰𐌿𐍆",
        "viewtalkpage": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌾𐌰",
        "otherlanguages": "𐌰𐌽𐌸𐌰𐍂𐌰𐌹𐌼 𐍂𐌰𐌶𐌳𐍉𐌼",
        "redirectedfrom": "(𐌹𐍃 {{GENDER:𐍄𐌹𐌿𐌷𐌰𐌽𐍃|𐍄𐌹𐌿𐌷𐌰𐌽𐌰}} 𐌷𐌹𐌳𐍂𐌴 𐍆𐍂𐌰𐌼 $1)",
        "redirectpagesub": "𐌰𐌻𐌾𐌰𐍂 𐌱𐍂𐌹𐌲𐌲𐌰𐌽𐌳𐍃 𐌻𐌰𐌿𐍆𐍃",
        "lastmodifiedat": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌸𐌰𐍄𐌰 𐌰𐍆𐍄𐌿𐌼𐌹𐍃𐍄 𐌹𐌽𐌼𐌰𐌹𐌳𐌹𐌸𐍃 𐍅𐌰𐍃 $1, 𐌰𐍄 $2.",
+       "viewcount": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐍃 𐌹𐍃𐍄 {{PLURAL:$1|𐌰𐌹𐌽𐌰𐌼𐌼𐌰 𐍃𐌹𐌽𐌸𐌰|$1 𐍃𐌹𐌽𐌸𐌰𐌼}}.",
        "protectedpage": "𐍆𐍂𐌹𐌸𐍉𐌽𐍃 𐌻𐌰𐌿𐍆𐍃",
        "jumpto": "𐌲𐌰𐌲𐌲 𐌳𐌿:",
        "jumptonavigation": "𐌻𐌰𐌿𐌱𐌰𐌲𐌰𐍅𐌹𐍃𐍃𐌴𐌹𐍃",
        "readonly": "𐌳𐌰𐍄𐌰𐌷𐌿𐌶𐌳 𐌻𐌿𐌺𐌰𐌽 𐌹𐍃𐍄",
        "enterlockreason": "𐌲𐌹𐍆 𐍅𐌰𐌹𐌷𐍄 𐌻𐌿𐌺𐌰, 𐌾𐌰𐌷 𐍃𐍅𐌰 𐌻𐌰𐌲𐌲𐌰𐌱𐌰 𐍆𐌰𐌿𐍂𐌸𐌹𐌶𐌴𐌹 𐌻𐌿𐌺 𐌿𐍃𐌼𐌴𐍂𐌽𐌰𐌹",
        "missing-article": "𐌳𐌰𐍄𐌰𐌷𐌿𐌶𐌳 𐌽𐌹 𐌱𐌹𐌲𐌰𐍄 𐌱𐍉𐌺𐍉𐍃 𐌻𐌰𐌿𐌱𐌹𐍃 𐌸𐌹𐌶𐌴𐌹 𐍃𐌺𐌿𐌻𐌳𐌴𐌳𐌹 𐌱𐌹𐌲𐌹𐍄𐌰𐌽, 𐌷𐌰𐌹𐍄𐌰𐌽𐍃 \"$1\" $2. \n\n𐌸𐌰𐍄𐌰 𐌿𐍆𐍄𐌰 𐍅𐌰𐌹𐍂𐌸𐌹𐌸 𐌾𐌰𐌱𐌰𐌹 𐌻𐌰𐌹𐍃𐍄𐌾𐌰𐌳𐌰 𐍆𐌰𐌹𐍂𐌽𐌾𐌰 𐌳𐌹𐍆𐍆 𐌸𐌰𐌿 𐍃𐍀𐌹𐌻𐌻𐌰𐌲𐌰𐍅𐌹𐍃𐍃 𐍃𐌴𐌹 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌹𐌳𐌰 𐌹𐍃𐍄. 𐌾𐌰𐌱𐌰𐌹 𐌽𐌹𐍃𐍄, 𐌼𐌰𐌷𐍄𐍃 𐌹𐍃𐍄 𐌴𐌹 𐌱𐌹𐌲𐌴𐍄𐌴𐌹𐍃 𐌰𐌹𐍂𐌶𐌴𐌹𐌽 𐌹𐌽 𐍃𐌰𐌿𐍆𐍄𐍅𐌰𐌹𐍂𐌰. \n\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌼𐌴𐍂𐌴𐌹 𐌸𐌰𐍄𐌰 𐌳𐌿 [[Special:ListUsers/sysop\n|𐍂𐌴𐌹𐌺]] 𐌲𐌹𐍆𐌿𐌷 𐌲𐌰𐍅𐌹𐍃.",
+       "filedeleteerror": "𐌼𐌰𐌷𐍄𐍃 𐌽𐌹 𐍅𐌰𐍃 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰𐌽 𐍆𐌰𐌾𐌻𐌰 \"$1\".",
+       "formerror": "𐌰𐌹𐍂𐌶𐌴𐌹: 𐍆𐌰𐌿𐍂𐌼𐌰 𐌹𐌽𐍃𐌰𐌽𐌳𐌾𐌰𐌽 𐌽𐌹 𐍅𐌰𐍃 𐌼𐌰𐌷𐍄𐍃.",
        "badarticleerror": "𐌸𐍉 𐍅𐌰𐌹𐌷𐍄 𐌽𐌹 𐌼𐌰𐌲𐍄 𐍄𐌰𐌿𐌾𐌰𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
        "cannotdelete-title": "𐌽𐌹 𐌼𐌰𐌲 𐍆𐍂𐌰𐌵𐌹𐍃𐍄𐌾𐌰𐌽 𐌻𐌰𐌿𐌱𐌰 \"$1\"",
        "badtitle": "𐌿𐌽𐍂𐌰𐌹𐌷𐍄𐌰𐍄𐌰 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹",
        "viewsource-title": "𐌱𐌰𐌽𐌳𐍅𐌴𐌹 𐌱𐍂𐌿𐌽𐌽𐌰𐌽 𐍆𐌰𐌿𐍂 $1",
        "protectedpagetext": "𐍃𐌰 𐌻𐌰𐌿𐍆𐍃 𐌷𐌰𐌱𐌰𐌹𐌸 𐌼𐌿𐌽𐌳, 𐌴𐌹 𐌽𐌹 𐍅𐌰𐌹𐍂𐌸𐌴𐌹𐌽𐌰 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 𐌸𐌰𐌿 𐌰𐌽𐌸𐌰𐍂𐍉𐍃 𐍅𐌰𐌹𐌷𐍄𐍃 𐌹𐌽 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰",
        "viewsourcetext": "𐌼𐌰𐌲𐍄 𐌱𐌰𐌽𐌳𐍅𐌾𐌰𐌽 𐌾𐌰𐌷 𐌺𐌰𐌿𐍀𐌾𐌰 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐌸𐌹𐍃 𐌻𐌰𐌿𐌱𐌹𐍃.",
+       "viewyourtext": "𐌼𐌰𐌲𐍄 𐍃𐌰𐌹𐍈𐌰𐌽 𐌾𐌰𐌷 𐌲𐌰𐌻𐌴𐌹𐌺𐍉𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃 <strong>𐌸𐌴𐌹𐌽𐌰𐌹𐌶𐍉 𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉</strong> 𐌳𐌿 𐌸𐌰𐌼𐌼𐌰 𐌻𐌰𐌿𐌱𐌰.",
+       "namespaceprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌻𐌰𐌿𐌱𐌰𐌽𐍃 𐌹𐌽 <strong>$1</strong> 𐌽𐌰𐌼𐌰𐍂𐌿𐌼𐌰.",
        "mycustomcssprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 CSS 𐌻𐌰𐌿𐍆.",
        "mycustomjsonprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JSON 𐌻𐌰𐌿𐍆.",
        "mycustomjsprotected": "𐌽𐌹 𐌷𐌰𐌱𐌰𐌹𐍃 𐌰𐌽𐌳𐌻𐌴𐍄 𐌳𐌿 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽 𐌸𐌰𐌽𐌰 JavaScript 𐌻𐌰𐌿𐍆.",
        "ns-specialprotected": "𐌿𐍃𐍃𐌹𐌽𐌳𐌰𐌹 𐌻𐌰𐌿𐌱𐍉𐍃 𐌽𐌹 𐌼𐌰𐌲𐌿𐌽 𐌹𐌽𐌼𐌰𐌹𐌳𐌾𐌰𐌽𐌳𐌰.",
        "titleprotected": "𐌸𐌰𐍄𐌰 𐌿𐍆𐌰𐍂𐌼𐌴𐌻𐌹 𐌼𐌿𐌽𐌸 𐌷𐌰𐌱𐌰𐌹𐌸 𐍆𐍂𐌰𐌼 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰 𐍆𐍂𐌰𐌼 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳 [[User:$1|$1]].\n𐌲𐌹𐌱𐌰𐌽𐌰 𐍆𐌰𐌹𐍂𐌹𐌽𐌰 𐌹𐍃𐍄 <em>$2</em>.",
+       "exception-nologin-text": "𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐌰𐍄𐌲𐌰𐌲𐌲 𐌳𐌿 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌹𐌽 𐌸𐌰𐌽𐌰 𐌻𐌰𐌿𐍆 𐌸𐌰𐌿 𐌸𐍉 𐍄𐌰𐌿𐌹.",
        "cannotlogoutnow-title": "𐌰𐍆𐌻𐌴𐌹𐌸𐌰𐌽 𐌽𐌿 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄",
        "cannotlogoutnow-text": "𐌸𐌰𐌽 $1 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰 𐌰𐍆𐌻𐌴𐌹𐌸𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄.",
        "welcomeuser": "𐍅𐌰𐌹𐌻𐌰 𐌰𐌽𐌳𐌰𐌽𐌴𐌼𐍃, $1!",
        "userlogin-yourpassword": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "userlogin-yourpassword-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌸𐌴𐌹𐌽",
        "createacct-yourpassword-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "yourpasswordagain": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌰𐍆𐍄𐍂𐌰:",
        "createacct-yourpasswordagain": "𐌲𐌰𐍃𐌹𐌲𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
        "createacct-yourpasswordagain-ph": "𐌼𐌴𐌻𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳 𐌰𐍆𐍄𐍂𐌰",
        "userlogin-remembermypassword": "𐌲𐌰𐍆𐌰𐍃𐍄 𐌼𐌹𐌺 {{GENDER:𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌽𐌰|𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰}}",
        "userlogin-signwithsecure": "𐌱𐍂𐌿𐌺𐌴𐌹 𐌰𐍂𐌽𐌾𐌰𐌹𐌶𐍉𐍃 𐌲𐌰𐍅𐌹𐍃𐌰𐌹𐍃",
+       "cannotlogin-title": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄",
        "cannotlogin-text": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄.",
        "cannotloginnow-title": "𐌽𐌿 𐌽𐌹 𐌼𐌰𐌲𐍄 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽",
        "cannotloginnow-text": "𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽 𐌼𐌰𐌷𐍄𐍃 𐌽𐌹𐍃𐍄 𐌸𐌰𐌽 $1 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰.",
        "createacct-reason-ph": "𐌳𐌿𐍈𐌴 𐌸𐌿 𐍃𐌺𐌰𐍀𐌾𐌹𐍃 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
        "createacct-submit": "𐍃𐌺𐌰𐍀𐌴𐌹 𐌸𐌴𐌹𐌽𐌰 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
        "createacct-another-submit": "𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽",
+       "createacct-continue-submit": "𐌸𐌰𐌹𐍂𐌷𐍅𐌹𐍃 𐌼𐌹𐌸 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
        "createacct-another-continue-submit": "𐌸𐌰𐌹𐍂𐌷𐍅𐌹𐍃 𐌼𐌹𐌸 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
        "createacct-benefit-heading": "{{SITENAME}} 𐍄𐌰𐍅𐌹𐌸 𐌹𐍃𐍄 𐍆𐍂𐌰𐌼 𐌼𐌰𐌽𐌽𐌰𐌼 𐍃𐍅𐌴 𐌸𐌿𐌺.",
        "createacct-benefit-body1": "{{PLURAL:$1|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍃|𐌹𐌽𐌼𐌰𐌹𐌳𐌴𐌹𐌽𐍉𐍃}}",
        "createacct-benefit-body2": "{{PLURAL:$1|𐌻𐌰𐌿𐍆𐍃|𐌻𐌰𐌿𐌱𐍉𐍃}}",
        "badretype": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐌸𐍉𐌴𐌹 𐌸𐌿 𐌲𐌰𐌼𐌴𐌻𐌹𐌳𐌴𐍃 𐌽𐌹 𐌹𐌽𐌲𐌰𐌻𐌴𐌹𐌺𐍉𐌽𐌳.",
        "usernameinprogress": "𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌹𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐍃 𐌸𐌰𐌼𐌼𐌰 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐌹𐌽 𐌾𐌿 𐍄𐍉𐌾𐌰𐌳𐌰. 𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺 𐌴𐌹 𐌱𐌹𐌳𐌰𐌹𐍃.",
+       "userexists": "𐌲𐌰𐌼𐌴𐌻𐌹𐌸 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉 𐌾𐌿 𐌱𐍂𐌿𐌺𐌾𐌰𐌳𐌰.\n𐌱𐌹𐌳𐌾𐌰𐌼 𐌸𐌿𐌺, 𐍅𐌰𐌻𐌴𐌹 𐌰𐌽𐌸𐌰𐍂 𐌽𐌰𐌼𐍉.",
        "createacct-error": "𐌰𐌹𐍂𐌶𐌴𐌹 𐌹𐌽 𐌲𐌰𐍃𐌺𐌰𐍆𐍄𐌰𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐌰𐌹𐍃",
        "createaccounterror": "𐌼𐌰𐌷𐍄𐍃 𐌽𐌹 𐍅𐌰𐍃 𐌳𐌿 𐍃𐌺𐌰𐍀𐌾𐌰𐌽 𐍂𐌰𐌷𐌽𐌴𐌹𐌽: $1",
        "nocookiesfornew": "𐌱𐍂𐌿𐌺𐌾𐌰𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 𐌽𐌹 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰 𐌿𐌽𐍄𐌴 𐍅𐌴𐌹𐍃 𐌽𐌹 𐌼𐌰𐌷𐍄𐌴𐌳𐌿𐌼 𐌱𐍂𐌿𐌽𐌽𐌰𐌽 𐌲𐌰𐍃𐌹𐌲𐌻𐌾𐌰𐌽. 𐍅𐌹𐍃 𐌰𐍂𐌽𐌹𐌱𐌰 𐌸𐌰𐍄𐌴𐌹 𐌸𐌿 𐌰𐌽𐌳𐌻𐌴𐍄𐌹𐍃 𐌺𐍉𐌺𐍉𐍃, 𐌰𐍆𐍄𐍂𐌰𐌰𐌽𐌰𐌽𐌹𐌿𐌴𐌹 𐌻𐌰𐌿𐍆 𐌾𐌰𐌷 𐍃𐍉𐌺𐌴𐌹 𐌰𐍆𐍄𐍂𐌰.",
        "nosuchuser": "𐌽𐌹𐍃𐍄 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐍃 𐌼𐌹𐌸 𐌽𐌰𐌼𐌹𐌽 \"$1\".\n𐌽𐌰𐌼𐌽𐌰 𐌱𐍂𐌿𐌺𐌾𐌰𐌽𐌳𐌴 𐌼𐌰𐌲𐌿𐌽 𐌷𐌰𐌱𐌰𐌽 𐌷𐌰𐌿𐌱𐌹𐌳𐌹𐍃 𐌱𐍉𐌺𐍉𐍃.\n𐍃𐌰𐌹𐍈 𐌰𐍆𐍄𐍂𐌰 𐌸𐌴𐌹𐌽𐌰 𐌼𐌴𐌻𐌴𐌹𐌽𐍃, 𐌸𐌰𐌿 [[Special:CreateAccount|𐍃𐌺𐌰𐍀𐌴𐌹 𐍂𐌰𐌷𐌽𐌴𐌹𐌽]].",
        "nouserspecified": "𐍃𐌺𐌰𐌻𐍄 𐌲𐌹𐌱𐌰𐌽 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐍉.",
+       "passwordtooshort": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐍃𐌺𐌿𐌻𐌿𐌽 𐌼𐌰𐌹𐍃 𐌸𐌰𐌿 {{PLURAL:$1|•𐌰• 𐌱𐍉𐌺𐌰|$1 𐌱𐍉𐌺𐍉𐍃}} 𐍅𐌹𐍃𐌰𐌽.",
+       "passwordtoolong": "𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌰 𐌽𐌹 𐌼𐌰𐌲𐌿𐌽 𐍅𐌹𐍃𐌰𐌽 𐌻𐌰𐌲𐌲𐌹𐌶𐍉𐌽𐌰 𐌸𐌰𐌿 {{PLURAL:$1|•𐌰• 𐌱𐍉𐌺𐌰|$1 𐌱𐍉𐌺𐍉𐍃}}.",
        "password-login-forbidden": "𐌱𐍂𐌿𐌺𐌴𐌹𐌽𐍃 𐌸𐌹𐍃 𐌰𐍄𐌲𐌰𐌲𐌲𐌰𐌽𐌰𐌼𐌹𐌽𐍃 𐌾𐌰𐌷 𐌸𐌹𐍃 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳𐌹𐍃 𐍆𐌰𐌿𐍂𐌱𐌹𐌿𐌳𐌰𐌽𐌰 𐌹𐍃𐍄.",
        "mailmypassword": "𐌰𐍆𐍄𐍂𐌰 𐍃𐌰𐍄𐌴𐌹 𐌲𐌰𐌼𐍉𐍄𐌰𐍅𐌰𐌿𐍂𐌳",
+       "noemailcreate": "𐍃𐌺𐌰𐌻𐍄 𐍂𐌰𐌹𐌷𐍄𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉𐍃 𐌲𐌹𐌱𐌰𐌽.",
        "emailconfirmlink": "𐌲𐌰𐍃𐌹𐌲𐌻𐌴𐌹 𐌸𐌴𐌹𐌽𐍉𐍃 𐌴-𐌱𐍉𐌺𐍉𐍃",
        "emaildisabled": "𐍃𐌰 𐌽𐌰𐍄𐌾𐌰𐍃𐍄𐌰𐌸𐍃 𐌽𐌹 𐌼𐌰𐌲 𐍃𐌰𐌽𐌳𐌾𐌰𐌽 𐌴-𐌱𐍉𐌺𐍉𐍃.",
        "accountcreatedtext": "𐌱𐍂𐌿𐌺𐌾𐌰𐍂𐌰𐌷𐌽𐌴𐌹𐌽𐍃 [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|𐌲𐌰𐍅𐌰𐌿𐍂𐌳𐌹]]) 𐌲𐌰𐍃𐌺𐌰𐍀𐌰𐌽𐌰 𐌹𐍃𐍄.",
index 3b91696..4d11489 100644 (file)
        "confirm-unwatch-button": "אישור",
        "confirm-unwatch-top": "להסיר את הדף הזה מרשימת המעקב שלך?",
        "confirm-rollback-button": "אישור",
-       "confirm-rollback-top": "×\9cש×\97×\96×\95ר ×\90ת ×\94ש×\99× ×\95×\99×\99×\9d ×\9c×\93×£ ×\94×\96×\94?",
+       "confirm-rollback-top": "לשחזר את השינויים לדף הזה?",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "→ לדף הקודם",
        "imgmultipagenext": "לדף הבא ←",
index f7cd82c..c3fc175 100644 (file)
        "userrights-editusergroup": "{{GENDER:$1|အသုံးပြုသူ}}အုပ်စုများကို တည်းဖြတ်ရန်",
        "saveusergroups": "{{GENDER:$1|အသုံးပြုသူ}}အုပ်စုများကို သိမ်းရန်",
        "userrights-groupsmember": "အဖွဲ့ဝင်",
+       "userrights-groups-help": "ဤအသုံးပြုသူ၏ အုပ်စုများကို အောက်ပါအတိုင်း သင်ပြောင်းလဲနိုင်သည်\n* အမှန်ခြစ်အကွက်သည် ထိုအသုံးပြုသူသည် ယင်းအုပ်စုတွင် ပါဝင်ကြောင်း ဆိုလိုသည်။\n* အမှန်ခြစ်မပါသော အကွက်သည် ထိုအသုံးပြုသူသည် ယင်းအုပ်စုတွင် မပါဝင်ကြောင်း ဆိုလိုသည်။\n* ခရေပွင့် * အမှတ်အသားသည် အုပ်စုတစ်ခုအတွင်းသို့ ထည့်သွင်းပြီးပါက ပြန်လည် ဖယ်ရှားမရနိုင်ကြောင်း (အပြန်အလှန်) ကို ဆိုလိုသည်။\n* သင်္ကေတ # အမှတ်အသားသည် ဤအုပ်စုအဖွဲ့ဝင် သက်တမ်းကို ပြန်လည်ထည့်သွင်းနိုင်ပြီး ရှေ့တိုးပေးရန် မဖြစ်နိုင်ကြောင်း ဖော်ပြသည်။",
        "userrights-reason": "အ​ကြောင်း​ပြ​ချက်:",
        "userrights-changeable-col": "သင်ပြောင်းလဲပေးနိုင်သောအုပ်စုများ",
        "userrights-unchangeable-col": "သင်ပြောင်းလဲမပေးနိုင်သောအုပ်စုများ",
+       "userrights-expiry-none": "သက်တမ်းကုန်ဆုံးခြင်း မရှိ",
        "group": "အုပ်စု -",
        "group-user": "အသုံးပြုသူများ",
        "group-autoconfirmed": "အလိုအလျောက် အတည်ပြုထားသော အသုံးပြုသူများ",
        "logentry-newusers-autocreate": "အသုံးပြုသူအကောင့် $1 ကို အလိုအလျောက် {{GENDER:$2|ဖန်တီးခဲ့သည်}}",
        "logentry-protect-protect": "$1 က  $3 ကို {{GENDER:$2|ကာကွယ်ခဲ့သည်}} $4",
        "logentry-protect-modify": "$3 အတွက် ကာကွယ်မှုအဆင့်ကို $1 {{GENDER:$2|က ပြောင်းလဲခဲ့သည်}} $4",
+       "logentry-rights-rights": "{{GENDER:$6|$3}} အတွက် အုပ်စုအဖွဲ့ဝင် $4 မှ $5 သို့ $1 က {{GENDER:$2|ပြောင်းလဲခဲ့သည်}}",
        "logentry-upload-upload": "$1 သည် $3 ကို {{GENDER:$2|upload တင်ခဲ့သည်}}",
        "logentry-upload-overwrite": "$3 ၏ ဗားရှင်းအသစ်ကို $1 {{GENDER:$2|upload တင်ခဲ့သည်}}",
        "rightsnone": "(ဘာမှမရှိ)",
index fe91686..027ef90 100644 (file)
        "currentrevisionlink": "Тренутна измена",
        "cur": "трен",
        "next": "след",
-       "last": "претх",
+       "last": "разл",
        "page_first": "прва",
        "page_last": "последња",
        "histlegend": "Избор разлика: изаберите кутијице измена за упоређивање и притисните ентер или дугме на дну.<br />\nОбјашњење: <strong>({{int:cur}})</strong> = разлика с тренутном изменом, <strong>({{int:last}})</strong> = разлика с претходном изменом, <strong>{{int:minoreditletter}}</strong> = мања измена",
index fa87948..5f5df18 100644 (file)
        "rcfilters-filter-humans-description": "רעדאקטירונגען געמאכט פון מענטשן רעדאקטארן.",
        "rcfilters-filtergroup-reviewstatus": "רעצענזירונג־סטאטוס",
        "rcfilters-filter-reviewstatus-unpatrolled-label": "אומפאטראלירט",
+       "rcfilters-filter-reviewstatus-auto-label": "אויטאפאַטראלירט",
        "rcfilters-filtergroup-significance": "באדייטונג",
        "rcfilters-filter-minor-label": "מינערדיקע רעדאַקטירונגען",
+       "rcfilters-filter-minor-description": "רעדאקטירונגען וואס דער שרייבער האט מארקירט פֿארמינערט.",
        "rcfilters-filter-watchlist-watched-label": "אויף דער אויפֿפאַסונג ליסטע",
        "rcfilters-filter-watchlist-notwatched-label": "נישט אויף דער אויפֿפאַסונג ליסטע",
        "rcfilters-filtergroup-changetype": "טיפ ענדערונג",
        "rcfilters-filter-previousrevision-label": "נישט די לעצטע ווערסיעס",
        "rcfilters-filter-excluded": "אויסגעשלאסן",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:נישט</strong> $1",
+       "rcfilters-exclude-button-off": "אויסשליסן געוויילטע",
        "rcfilters-view-tags": "מאַרקירטע רעדאַקטירונגען",
        "rcfilters-liveupdates-button": "לעבעדיקע דערהיינטיקונגען",
        "rcfilters-target-page-placeholder": "אײַנגעבן א בלאטנאמען (אדער קאטעגאריע)",
        "apisandbox-retry": "פרובירן נאכאמאל",
        "apisandbox-helpurls": "הילף לינקען",
        "apisandbox-examples": "ביישפילן",
+       "apisandbox-dynamic-parameters-add-label": "צולייגן פאראמעטער:",
+       "apisandbox-dynamic-parameters-add-placeholder": "פאראמעטער נאמען",
+       "apisandbox-dynamic-error-exists": "ס׳איז שוין פֿאראן א פאראמעטער מיטן נאמען \"$1.",
+       "apisandbox-deprecated-parameters": "פֿארעלטערטע פאראמעטערס",
+       "apisandbox-add-multi": "צולייגן",
+       "apisandbox-submit-invalid-fields-title": "טייל פֿעלדער זענען אומגילטיק",
        "apisandbox-results": "רעזולטאטן",
+       "apisandbox-continue": "פֿארזעצן",
+       "apisandbox-continue-clear": "רייניקן",
+       "apisandbox-multivalue-all-namespaces": "$1 (אלע נאמענטיילן)",
+       "apisandbox-multivalue-all-values": "$1 (אלע ווערטן)",
        "booksources": "דרויסנדיגע ליטעראַטור ISBN",
        "booksources-search-legend": "זוכן פאר דרויסנדע ביכער מקורות",
        "booksources-search": "זוכן",
        "logempty": "נישטא קיין פאַסנדיקע זאכן אין לאג.",
        "log-title-wildcard": "זוכן טיטלען וואס הייבן אָן מיט דעם טעקסט",
        "showhideselectedlogentries": "ווײַזן/באַהאַלטן געקליבענע לאגבוך אקציעס",
+       "checkbox-select": "אויסוויילן: $1",
        "checkbox-all": "אַלע",
        "checkbox-none": "קיינע",
        "checkbox-invert": "אומקערן",
        "unblocked-id": "בלאק $1 איז געווארן אַראָפגענומען.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] איז געווארן אויפבלאקירט.",
        "blocklist": "בלאקירטע באַניצער",
+       "autoblocklist-submit": "זוכן",
        "ipblocklist": "בלאקירטע באַניצער",
        "ipblocklist-legend": "געפֿינען א בלאקירטן באניצער",
        "blocklist-userblocks": "באהאלטן קאנטע בלאקן",
        "unlockdbsuccesssub": "דאטנבאזע שלאס אראפגענומען",
        "lockdbsuccesstext": "די דאטנבאזע איז געשלאסן .<br />\nגעדענקט [[Special:UnlockDB|אוועקנעמען דעם שלאס ]] ווען אייער אויפהאלטונד איז געענדיקט.",
        "unlockdbsuccesstext": "די דאַטנבאַזע איז געווארן אויפֿגעשלאסן",
+       "databaselocked": "די דאַטנבאַזע איז שוין פֿאַרשלאסן.",
        "databasenotlocked": "די דאַטנבאַזע איז נישט פֿאַרשלאסן.",
        "lockedbyandtime": "(דורך $1 אום $2 בײַ $3)",
        "move-page": "באַוועגן $1",
        "cant-move-to-user-page": "איר זענט נישט דערלויבט צו באַוועגן א בלאַט צו א באַניצער בלאַט (אַחוץ צו א באַניצער אונטערבלאַט).",
        "cant-move-category-page": "איר זענט נישט דערלויבט צו באוועגן קאטעגאריע בלעטער.",
        "cant-move-to-category-page": "איר זענט נישט ערלויבט צו באוועגן א בלאט צו קאטעגאריע־בלאט.",
+       "cant-move-subpages": "איר זענט נישט דערלויבט צו באוועגן אונטערבלעטער.",
+       "namespace-nosubpages": "נאמענטייל \"$1\" ערלויבט נישט קיין אונטערבלעטער.",
        "newtitle": "נייע קעפל:",
        "move-watch": "אויפֿפאַסן אויף דעם בלאַט",
        "movepagebtn": "באַוועגן בלאַט",
        "pageinfo-language": "בלאט אינהאלט שפראך",
        "pageinfo-language-change": "ענדערן",
        "pageinfo-content-model": "בלאט אינהאלט מאדעל",
+       "pageinfo-content-model-change": "טוישן",
        "pageinfo-robot-policy": "אינדעקסירן דורך ראבאטן",
        "pageinfo-robot-index": "דערלויבט",
        "pageinfo-robot-noindex": "נישט דערלויבט",
        "markedaspatrollednotify": "די ענדערונג צו $1 איז געווארן מארקירט ווי קאנטראלירט.",
        "markedaspatrollederrornotify": "מארקירן ווי קאנטראלירט דורכגעפאלן.",
        "patrol-log-page": "פאטראלירן לאג-בוך",
-       "patrol-log-header": "דאס איז א לאג-בוך פון פאַטראליטע רעוויזיעס.",
+       "patrol-log-header": "×\93×\90ס ×\90×\99×\96 ×\90 ×\9c×\90×\92\91×\95×\9a ×¤×\95×\9f ×¤×\90Ö·×\98ר×\90×\9c×\99ר×\98×¢ ×¨×¢×\95×\95×\99×\96×\99עס.",
        "log-show-hide-patrol": "$1 פאַטראלירן לאג-בוך",
        "log-show-hide-tag": "$1 טאג־לאגבוך",
+       "confirm-markpatrolled-button": "יאָ",
        "confirm-markpatrolled-top": "מארקירן $3 פון $2 ווי קאנטראלירט?",
        "deletedrevision": "אויסגעמעקט אלטע ווערסיע $1.",
        "filedeleteerror-short": "גרייז ביים אויסמעקן טעקע: $1",
        "newimages-legend": "פֿילטער",
        "newimages-label": "טעקע נאָמען (אדער אַ טײל דערפֿון):",
        "newimages-showbots": "ווײַזן ארויפלאדן פון באטן",
+       "newimages-mediatype": "מעדיע־טיפ:",
        "noimages": "נישטא קיין בילדער.",
        "ilsubmit": "זוכן",
        "bydate": "לויטן דאטום",
index 44b028d..dea9293 100644 (file)
@@ -1835,6 +1835,7 @@ return [
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FormWrapperWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.FilterItemHighlightButton.js',
+                       'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightColorPickerWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.LiveUpdateButtonWidget.js',
                        'resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.MarkSeenButtonWidget.js',
index 790e015..daa7a91 100644 (file)
 // so it is before the rest of the rule; we need the li& to be in
 // between the wrapper scope and the color-cX class, which doesn't
 // work if the rules are inside the above widget LESS scope
-.highlight-changesListWrapperWidget( @bgcolor ) {
+.highlight-results( @bgcolor ) {
        .mw-rcfilters-ui-changesListWrapperWidget li&,
        .mw-rcfilters-ui-changesListWrapperWidget & tr:first-child,
-       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+2 ) ),
-       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+4 ) ) {
+       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-highlights-enhanced-toplevel:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+2 ) ),
+       .mw-rcfilters-ui-changesListWrapperWidget tr&.mw-rcfilters-ui-highlights-enhanced-nested:not( .mw-rcfilters-ui-changesListWrapperWidget-enhanced-grey ) td:not( :nth-child( -n+4 ) ) {
                background-color: @bgcolor;
        }
 }
 
        // Two colors
        @{highlight-color-class-var} when ( @color3 = false ) and ( @color4 = false ) and not ( @color1 = false ), ( @color2 = false ) {
-               .highlight-changesListWrapperWidget( tint( average( @@c1var, @@c2var ), 50% ) );
+               .highlight-results( tint( average( @@c1var, @@c2var ), 50% ) );
        }
        // Three colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3} when ( @color4 = false ) and not ( @color3 = false ) {
                @c3var: ~'highlight-@{color3}';
-               .highlight-changesListWrapperWidget( tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% ) );
+               .highlight-results( tint( mix( @@c1var, average( @@c2var, @@c3var ), 33% ), 30% ) );
        }
 
        // Four colors
        @{highlight-color-class-var}.mw-rcfilters-highlight-color-@{color3}.mw-rcfilters-highlight-color-@{color4} when not ( @color4 = false ) {
                @c3var: ~'highlight-@{color3}';
                @c4var: ~'highlight-@{color4}';
-               .highlight-changesListWrapperWidget( tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% ) );
+               .highlight-results( tint( mix( @@c1var, mix( @@c2var, average( @@c3var, @@c4var ), 25% ), 25% ), 25% ) );
        }
 }
index e9e331b..e0c3c8b 100644 (file)
                        width: 100%;
                }
        }
+}
 
-       &-highlights {
-               display: none;
-               padding: 0 @result-circle-general-margin 0 0;
-               text-align: right;
-               // The width is 5 circles times their diameter + individual margin
-               // and then plus the general margin
-               width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
-               // And we want to shift the entire block to the left of the li
-               position: relative;
-               // Negative left margin of width + padding
-               margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * -5 - @{result-circle-general-margin} )';
-
-               .mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
-                       display: inline-block;
-               }
+.mw-rcfilters-ui-highlights {
+       display: none;
+       padding: 0 @result-circle-general-margin 0 0;
+       // The width is 5 circles times their diameter + individual margin
+       // and then plus the general margin
+       width: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * 5 )';
+       // And we want to shift the entire block to the left of the li
+       position: relative;
+       // Negative left margin of width + padding
+       margin-left: ~'calc( ( @{result-circle-diameter} + @{result-circle-margin} ) * -5 - @{result-circle-general-margin} )';
 
-               // This needs to be very specific, since these are
-               // position rules that should apply to all overrides
-               .mw-rcfilters-ui-changesListWrapperWidget .mw-rcfilters-ui-changesListWrapperWidget-highlights > div&-circle {
-                       .box-sizing( border-box );
-                       margin-right: @result-circle-margin;
-                       vertical-align: middle;
-                       // This is to make the dots appear at the center of the
-                       // text itself; it's a horrendous hack and blame JamesF for it.
-                       margin-top: -2px;
-               }
+       .mw-rcfilters-ui-changesListWrapperWidget-highlighted & {
+               display: inline-block;
+       }
 
-               &-color {
+       > div {
+               .box-sizing( border-box );
+               margin-right: @result-circle-margin;
+               vertical-align: middle;
+               // This is to make the dots appear at the center of the
+               // text itself; it's a horrendous hack and blame JamesF for it.
+               margin-top: -2px;
+               float: right;
+       }
 
-                       &-none {
-                               .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true );
-                               display: inline-block;
+       &-color {
+               &-none {
+                       .mw-rcfilters-mixin-circle( @highlight-none, @result-circle-diameter, 0, true );
+                       display: inline-block;
 
-                               .mw-rcfilters-highlight-color-c1 &,
-                               .mw-rcfilters-highlight-color-c2 &,
-                               .mw-rcfilters-highlight-color-c3 &,
-                               .mw-rcfilters-highlight-color-c4 &,
-                               .mw-rcfilters-highlight-color-c5 & {
-                                       display: none;
-                               }
+                       .mw-rcfilters-highlight-color-c1 &,
+                       .mw-rcfilters-highlight-color-c2 &,
+                       .mw-rcfilters-highlight-color-c3 &,
+                       .mw-rcfilters-highlight-color-c4 &,
+                       .mw-rcfilters-highlight-color-c5 & {
+                               display: none;
                        }
-                       .result-circle( c1 );
-                       .result-circle( c2 );
-                       .result-circle( c3 );
-                       .result-circle( c4 );
-                       .result-circle( c5 );
                }
+               .result-circle( c1 );
+               .result-circle( c2 );
+               .result-circle( c3 );
+               .result-circle( c4 );
+               .result-circle( c5 );
        }
 }
 
 // One color
 .mw-rcfilters-highlight-color-c1 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c1, 70% ); );
+       .highlight-results( tint( @highlight-c1, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c2 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c2, 70% ); );
+       .highlight-results( tint( @highlight-c2, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c3 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c3, 70% ); );
+       .highlight-results( tint( @highlight-c3, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c4 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c4, 70% ); );
+       .highlight-results( tint( @highlight-c4, 70% ); );
 }
 
 .mw-rcfilters-highlight-color-c5 {
-       .highlight-changesListWrapperWidget( tint( @highlight-c5, 70% ); );
+       .highlight-results( tint( @highlight-c5, 70% ); );
 }
 
 // Two colors
 // a custom color rather than the computed tint
 // see https://phabricator.wikimedia.org/T161267
 .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c3 {
-       .highlight-changesListWrapperWidget( @light-green );
+       .highlight-results( @light-green );
 }
 .highlight-color-mix( c1, c4 );
 .highlight-color-mix( c1, c5 );
 
 // Five colors:
 .mw-rcfilters-highlight-color-c1.mw-rcfilters-highlight-color-c2.mw-rcfilters-highlight-color-c3.mw-rcfilters-highlight-color-c4.mw-rcfilters-highlight-color-c5 {
-       .highlight-changesListWrapperWidget( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
+       .highlight-results( tint( mix( @highlight-c1, mix( @highlight-c2, mix( @highlight-c3, average( @highlight-c4, @highlight-c5 ), 20% ), 20% ), 20% ), 15% ) );
 }
index b49a1cb..ec3fe31 100644 (file)
         * @param {jQuery|string} $content The content of the updated changes list
         */
        mw.rcfilters.ui.ChangesListWrapperWidget.prototype.setupHighlightContainers = function ( $content ) {
-               var $enhancedTopPageCell, $enhancedNestedPagesCell,
-                       widget = this,
-                       highlightClass = 'mw-rcfilters-ui-changesListWrapperWidget-highlights',
-                       $highlights = $( '<div>' )
-                               .addClass( highlightClass )
-                               .append(
-                                       $( '<div>' )
-                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
-                                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-none' )
-                                               .prop( 'data-color', 'none' )
-                               );
-
-               if ( $( '.mw-rcfilters-ui-changesListWrapperWidget-highlights' ).length ) {
-                       // Already set up
-                       return;
-               }
-
-               mw.rcfilters.HighlightColors.forEach( function ( color ) {
-                       $highlights.append(
-                               $( '<div>' )
-                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-color-' + color )
-                                       .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-highlights-circle' )
-                                       .prop( 'data-color', color )
-                       );
-               } );
+               var $enhancedTopPageCell,
+                       widget = this;
 
                if ( this.inEnhancedMode() ) {
                        $enhancedTopPageCell = $content.find( 'table.mw-enhanced-rc.mw-collapsible' );
-                       $enhancedNestedPagesCell = $content.find( 'td.mw-enhanced-rc-nested' );
-
-                       // Enhanced RC highlight containers
-                       $content.find( 'table.mw-enhanced-rc tr:first-child' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-toplevel' )
-                               .prepend(
-                                       $( '<td>' )
-                                               .append( $highlights.clone() )
-                               );
-
-                       // We are adding and changing cells in a table that, despite having nested rows,
-                       // is actually all one big table. To prevent the highlights cell in the "nested"
-                       // rows from stretching out the cell with the flags and timestamp in the top row,
-                       // we give the latter colspan=2. Then to make things line up again, we add
-                       // an empty <td> to the "nested" rows.
-
-                       // Set colspan=2 on cell with flags and timestamp in top row
-                       $content.find( 'table.mw-enhanced-rc tr:first-child td.mw-enhanced-rc' )
-                               .prop( 'colspan', '2' );
-                       // Add empty <td> to nested rows to compensate
-                       $enhancedNestedPagesCell.parent().prepend( $( '<td>' ) );
-                       // Add highlights cell to nested rows
-                       $enhancedNestedPagesCell
-                               .before(
-                                       $( '<td>' )
-                                               .append( $highlights.clone().addClass( 'mw-enhanced-rc-nested' ) )
-                               );
-
-                       // We need to target the nested rows differently than the top rows so that the
-                       // LESS rules applies correctly. In top rows, the rule should highlight all but
-                       // the first 2 cells td:not( :nth-child( -n+2 ) and the nested rows, the rule
-                       // should highlight all but the first 4 cells td:not( :nth-child( -n+4 )
-                       $enhancedNestedPagesCell
-                               .closest( 'tr' )
-                               .addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhanced-nested' );
-
                        // Go over pages that have sub results
                        // HACK: We really only can collect those by targetting the collapsible class
                        $enhancedTopPageCell.each( function () {
                                $table.find( 'tr:first-child' )
                                        .addClass( collectedClasses.join( ' ' ) );
                        } );
-
-                       $content.addClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhancedView' );
-               } else {
-                       // Regular RC
-                       $content.find( 'ul.special li' )
-                               .prepend( $highlights.clone() );
-
-                       $content.removeClass( 'mw-rcfilters-ui-changesListWrapperWidget-enhancedView' );
                }
        };
 
index c840d7c..e3de55e 100644 (file)
@@ -7,34 +7,24 @@
         * @constructor
         * @param {mw.rcfilters.Controller} controller RCFilters controller
         * @param {mw.rcfilters.dm.FilterItem} model Filter item model
+        * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
         * @param {Object} [config] Configuration object
         */
-       mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, config ) {
+       mw.rcfilters.ui.FilterItemHighlightButton = function MwRcfiltersUiFilterItemHighlightButton( controller, model, highlightPopup, config ) {
                config = config || {};
 
-               this.colorPickerWidget = new mw.rcfilters.ui.HighlightColorPickerWidget( controller, model );
-
                // Parent
                mw.rcfilters.ui.FilterItemHighlightButton.parent.call( this, $.extend( true, {}, config, {
                        icon: 'highlight',
-                       indicator: 'down',
-                       popup: {
-                               anchor: false,
-                               padded: true,
-                               align: 'backwards',
-                               horizontalPosition: 'end',
-                               $floatableContainer: this.$element,
-                               width: 290,
-                               $content: this.colorPickerWidget.$element
-                       }
+                       indicator: 'down'
                } ) );
 
                this.controller = controller;
                this.model = model;
+               this.popup = highlightPopup;
 
                // Event
                this.model.connect( this, { update: 'updateUiBasedOnModel' } );
-               this.colorPickerWidget.connect( this, { chooseColor: 'onChooseColor' } );
                // This lives inside a MenuOptionWidget, which intercepts mousedown
                // to select the item. We want to prevent that when we click the highlight
                // button
 
        /* Methods */
 
+       mw.rcfilters.ui.FilterItemHighlightButton.prototype.onAction = function () {
+               this.popup.setAssociatedButton( this );
+               this.popup.setFilterItem( this.model );
+
+               // Parent method
+               mw.rcfilters.ui.FilterItemHighlightButton.parent.prototype.onAction.call( this );
+       };
+
        /**
         * Respond to item model update event
         */
@@ -79,8 +77,4 @@
                                );
                } );
        };
-
-       mw.rcfilters.ui.FilterItemHighlightButton.prototype.onChooseColor = function () {
-               this.popup.toggle( false );
-       };
 }( mediaWiki, jQuery ) );
index 926502d..65b4420 100644 (file)
@@ -9,10 +9,11 @@
         * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
         * @param {mw.rcfilters.dm.FilterItem} invertModel
         * @param {mw.rcfilters.dm.FilterItem} itemModel Filter item model
+        * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker popup
         * @param {Object} config Configuration object
         */
        mw.rcfilters.ui.FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
+               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
        ) {
                config = config || {};
 
@@ -21,7 +22,7 @@
                this.model = itemModel;
 
                // Parent
-               mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, config );
+               mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, controller, filtersViewModel, this.invertModel, itemModel, highlightPopup, config );
 
                // Event
                this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } );
index d59fdfb..907c535 100644 (file)
                        ) {
                                this.addTag( item.getName(), item.getLabel() );
                        } else {
-                               this.removeTagByData( item.getName() );
+                               // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
+                               if ( this.findItemFromData( item.getName() ) !== null ) {
+                                       this.removeTagByData( item.getName() );
+                               }
                        }
                }
 
                        // Remove capsule widgets if they're not selected
                        highlightedItems.forEach( function ( filterItem ) {
                                if ( !filterItem.isSelected() ) {
-                                       this.removeTagByData( filterItem.getName() );
+                                       // Only attempt to remove the tag if we can find an item for it (T198140, T198231)
+                                       if ( this.findItemFromData( filterItem.getName() ) !== null ) {
+                                               this.removeTagByData( filterItem.getName() );
+                                       }
                                }
                        }.bind( this ) );
                }
index 64a7fcf..fda0772 100644 (file)
@@ -7,10 +7,9 @@
         *
         * @constructor
         * @param {mw.rcfilters.Controller} controller RCFilters controller
-        * @param {mw.rcfilters.dm.FilterItem} model Filter item model
         * @param {Object} [config] Configuration object
         */
-       mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, model, config ) {
+       mw.rcfilters.ui.HighlightColorPickerWidget = function MwRcfiltersUiHighlightColorPickerWidget( controller, config ) {
                var colors = [ 'none' ].concat( mw.rcfilters.HighlightColors );
                config = config || {};
 
@@ -22,7 +21,6 @@
                } ) );
 
                this.controller = controller;
-               this.model = model;
 
                this.currentSelection = 'none';
                this.buttonSelect = new OO.ui.ButtonSelectWidget( {
                } );
 
                // Event
-               this.model.connect( this, { update: 'updateUiBasedOnModel' } );
                this.buttonSelect.connect( this, { choose: 'onChooseColor' } );
 
-               this.updateUiBasedOnModel();
-
                this.$element
                        .addClass( 'mw-rcfilters-ui-highlightColorPickerWidget' )
                        .append(
 
        /* Methods */
 
+       /**
+        * Bind the color picker to an item
+        * @param {mw.rcfilters.dm.FilterItem} filterItem
+        */
+       mw.rcfilters.ui.HighlightColorPickerWidget.prototype.setFilterItem = function ( filterItem ) {
+               if ( this.filterItem ) {
+                       this.filterItem.disconnect( this );
+               }
+
+               this.filterItem = filterItem;
+               this.filterItem.connect( this, { update: 'updateUiBasedOnModel' } );
+               this.updateUiBasedOnModel();
+       };
+
        /**
         * Respond to item model update event
         */
        mw.rcfilters.ui.HighlightColorPickerWidget.prototype.updateUiBasedOnModel = function () {
-               this.selectColor( this.model.getHighlightColor() || 'none' );
+               this.selectColor( this.filterItem.getHighlightColor() || 'none' );
        };
 
        /**
        mw.rcfilters.ui.HighlightColorPickerWidget.prototype.onChooseColor = function ( button ) {
                var color = button.data;
                if ( color === 'none' ) {
-                       this.controller.clearHighlightColor( this.model.getName() );
+                       this.controller.clearHighlightColor( this.filterItem.getName() );
                } else {
-                       this.controller.setHighlightColor( this.model.getName(), color );
+                       this.controller.setHighlightColor( this.filterItem.getName(), color );
                }
                this.emit( 'chooseColor', color );
        };
diff --git a/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js b/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.HighlightPopupWidget.js
new file mode 100644 (file)
index 0000000..aedecc4
--- /dev/null
@@ -0,0 +1,63 @@
+( function ( mw, $ ) {
+       /**
+        * A popup containing a color picker, for setting highlight colors.
+        *
+        * @extends OO.ui.PopupWidget
+        *
+        * @constructor
+        * @param {mw.rcfilters.Controller} controller RCFilters controller
+        * @param {Object} [config] Configuration object
+        */
+       mw.rcfilters.ui.HighlightPopupWidget = function MwRcfiltersUiHighlightPopupWidget( controller, config ) {
+               config = config || {};
+
+               // Parent
+               mw.rcfilters.ui.HighlightPopupWidget.parent.call( this, $.extend( {
+                       autoClose: true,
+                       anchor: false,
+                       padded: true,
+                       align: 'backwards',
+                       horizontalPosition: 'end',
+                       width: 290
+               }, config ) );
+
+               this.colorPicker = new mw.rcfilters.ui.HighlightColorPickerWidget( controller );
+
+               this.colorPicker.connect( this, { chooseColor: 'onChooseColor' } );
+
+               this.$body.append( this.colorPicker.$element );
+       };
+
+       /* Initialization */
+
+       OO.inheritClass( mw.rcfilters.ui.HighlightPopupWidget, OO.ui.PopupWidget );
+
+       /* Methods */
+
+       /**
+        * Set the button (or other widget) that this popup should hang off.
+        *
+        * @param {OO.ui.Widget} widget Widget the popup should orient itself to
+        */
+       mw.rcfilters.ui.HighlightPopupWidget.prototype.setAssociatedButton = function ( widget ) {
+               this.setFloatableContainer( widget.$element );
+               this.$autoCloseIgnore = widget.$element;
+       };
+
+       /**
+        * Set the filter item that this popup should control the highlight color for.
+        *
+        * @param {mw.rcfilters.dm.FilterItem} item
+        */
+       mw.rcfilters.ui.HighlightPopupWidget.prototype.setFilterItem = function ( item ) {
+               this.colorPicker.setFilterItem( item );
+       };
+
+       /**
+        * When the user chooses a color in the color picker, close the popup.
+        */
+       mw.rcfilters.ui.HighlightPopupWidget.prototype.onChooseColor = function () {
+               this.toggle( false );
+       };
+
+}( mediaWiki, jQuery ) );
index 8c349e5..83d510b 100644 (file)
@@ -9,10 +9,11 @@
         * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
         * @param {mw.rcfilters.dm.ItemModel} invertModel
         * @param {mw.rcfilters.dm.ItemModel} itemModel Item model
+        * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
         * @param {Object} config Configuration object
         */
        mw.rcfilters.ui.ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget(
-               controller, filtersViewModel, invertModel, itemModel, config
+               controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
        ) {
                var layout,
                        classes = [],
@@ -55,6 +56,7 @@
                this.highlightButton = new mw.rcfilters.ui.FilterItemHighlightButton(
                        this.controller,
                        this.itemModel,
+                       highlightPopup,
                        {
                                $overlay: config.$overlay || this.$element,
                                title: mw.msg( 'rcfilters-highlightmenu-help' )
index d968f0c..04b7709 100644 (file)
 
                this.menuInitialized = true;
 
+               // Create shared popup for highlight buttons
+               this.highlightPopup = new mw.rcfilters.ui.HighlightPopupWidget( this.controller );
+               this.$overlay.append( this.highlightPopup.$element );
+
                // Count groups per view
                $.each( groups, function ( groupName, groupModel ) {
                        if ( !groupModel.isHidden() ) {
                                                        widget.model,
                                                        widget.model.getInvertModel(),
                                                        filterItem,
+                                                       widget.highlightPopup,
                                                        {
                                                                $overlay: widget.$overlay
                                                        }