jenkins-bot has submitted this change and it was merged.

Change subject: Add feature: <tab>s that show up in every tab
......................................................................


Add feature: <tab>s that show up in every tab

Using index="*" for a <tab> tag will now make it show up
 for every single tab. This is useful when nesting
 toggle boxes or dropdown menus inside tab menus.
Also fixed a bug that made it impossible to use
 {{#tab:#1|cont}} syntax, because index="#1" would be set.

Change-Id: Iff726f885bbd4b55d66dc0d2055e64eb7344cb4d
---
M Tabs.body.php
M ext.tabs.css
M ext.tabs.js
3 files changed, 66 insertions(+), 40 deletions(-)

Approvals:
  Joeytje50: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/Tabs.body.php b/Tabs.body.php
index 7aa8d9f..7383443 100644
--- a/Tabs.body.php
+++ b/Tabs.body.php
@@ -66,42 +66,47 @@
                }
                // Default value for the tab's given index: index attribute's 
value, or else the index of the tab with the same name as name attribute, or 
else the tab index
                if (!$nested) {
-                       $index = 0; // indices do nothing for non-nested tabs, 
so don't even bother doing the computations.
+                       $index = -1; // indices do nothing for non-nested tabs, 
so don't even bother doing the computations.
                } elseif (isset($attr['index']) && intval($attr['index']) <= 
count($names)) {
                        $index = intval($attr['index']); // if the index is 
given, and it isn't greater than the current index + 1.
-               } elseif (isset($attr['name']) && array_search($attr['name'], 
$names) !== false)
+               } elseif (isset($attr['index']) && $attr['index'] == '*') {
+                       $index = 0; //use wildcard index: this tab's contents 
shows up for every single tab;
+                       //this makes it possible to have a dropdown box inside 
a <tabs> box, which shows up for every tab.
+               } elseif (isset($attr['name']) && array_search($attr['name'], 
$names) !== false) {
                        $index = array_search($attr['name'], $names)+1; // if 
index is not defined, but the name is, use the index of the tabname.
-               else {
+               } else {
                        $index = count($names)+1; // index of this tab in this 
scope. Plus one because tabs are 1-based, arrays are 0-based.
                }
                
                $classPrefix = '';
-               if ($nested) // Note: This is defined seperately for 
toggleboxes, because of the different classes required.
+               if ($nested) {// Note: This is defined seperately for 
toggleboxes, because of the different classes required.
                        $classPrefix .= "tabs-content tabs-content-$index";
-               
-               if (!isset($attr['class']))
-                       $attr['class'] = $classPrefix; // only the prefix if no 
classes have been defined
-               else
-                       $attr['class'] = trim("$classPrefix 
".htmlspecialchars($attr['class']));
-               
-               if (isset($names[$index-1])) {// if array $names already has a 
name defined at position $index, use that.
-                       $name = $names[$index-1]; // minus 1 because tabs are 
1-based, arrays 0-based.
-               } else {// otherwise, use the entered name, or the $index with 
a "Tab " prefix if it is not defined or empty.
-                       $name = trim(isset($attr['name']) && $attr['name'] ? 
$attr['name'] : wfMessage('tabs-tab-label', $index));
                }
-
+               if (isset($attr['class'])) {
+                       $attr['class'] = trim("$classPrefix 
".htmlspecialchars($attr['class']));
+               } else {
+                       $attr['class'] = $classPrefix; // only the prefix if no 
classes have been defined
+               }
+               if ($index !== 0) {
+                       if (isset($names[$index-1])) { // if array $names 
already has a name defined at position $index, use that.
+                               $name = $names[$index-1]; // minus 1 because 
tabs are 1-based, arrays 0-based.
+                       } else { // otherwise, use the entered name, or the 
$index with a "Tab " prefix if it is not defined or empty.
+                               $name = trim(isset($attr['name']) && 
$attr['name'] ? $attr['name'] : wfMessage('tabs-tab-label', $index));
+                       }
+               }
                if (!$nested) { // This runs when the tab is not nested inside 
a <tabs> tag.
                        $container = $this->renderBox($input, $attr, $parser);
                } else { // this runs when the tab is nested inside a <tabs> 
tag.
-                       if (array_search($name, $names) === false) // append 
name if it's not already in the list.
+                       if ($index !== 0 && array_search($name, $names) === 
false) {// append name if it's not already in the list.
                                $names[] = $name;
-                       
-                       if (isset($attr['block']))
+                       }
+                       if (isset($attr['block'])) {
                                $ib = 'tabs-block ';
-                       elseif (isset($attr['inline']))
+                       } elseif (isset($attr['inline'])) {
                                $ib = 'tabs-inline ';
-                       else
+                       } else {
                                $ib = '';
+                       }
                        $attr['class'] = $ib.$attr['class'];
                        $container = array(
                                '',
@@ -109,7 +114,10 @@
                                'div',
                                $this->getSafeAttrs($attr)
                        );
-                       $parser->tabsData['labels'][intval($index)] = $name; // 
Store the index and the name so this can be used within the <tabs> hook to 
create labels
+                       if ($index !== 0) {
+                               // Store the index and the name so this can be 
used within the <tabs> hook to create labels
+                               $parser->tabsData['labels'][intval($index)] = 
$name;
+                       }
                }
                if ($input === null) return ''; // return empty string if the 
tag is self-closing. This can be used to pre-define tabs for referring to via 
the index later.
 
@@ -265,7 +273,7 @@
        /**
         * Renders parser function for simpler inline tab syntax ({{#tab:}})
         * @param Parser $parser
-        * @param string $index A comma-seperated list of tab names or indices. 
Integers will always be interpreted as indices.
+        * @param string $index A comma-seperated list of tab names or indices. 
Integers prefixed with '#' will always be interpreted as indices.
         * @return string A converted list of <tab> tags, further to be 
processed by the parser.
         */
        public function renderPf($parser, $index) {
@@ -280,7 +288,7 @@
                        $index_i = isset($index[$i-1]) ? trim($index[$i-1]) : 
'';
                        if (preg_match('/^#\d+$/',$index_i) && 
intval(substr($index_i,1)) > 0) {
                                //only assign an index if the attribute is just 
digits, preceded by #
-                               $attr = "index=\"$index_i\"";
+                               $attr = 'index="'.substr($index_i,1).'"';
                                $isname = false;
                        } elseif ($index_i) {
                                // only assign a name if the name attribute 
isn't just whitespace
diff --git a/ext.tabs.css b/ext.tabs.css
index 7329c3d..ebd5394 100644
--- a/ext.tabs.css
+++ b/ext.tabs.css
@@ -22,11 +22,15 @@
 
 /**
  * This is for testing if the browser supports the :not() selector. !important 
is used to ensure this style doesn't change.
- * The "sans-serif" ("without-serif") and "serif" fonts are used to indicate 
"sans" :not()-support or with.
+ * The "sans-serif" ("without-serif") and "serif" fonts are used to indicate 
:not()-support (so also :checked support, since those
+ * selectors gained support in almost every browser at the very same moment). 
"sans-serif" indicates no support; "serif" indicates :not() support.
  * This form is used as a "testcase" because it is hidden from view anyway, 
and always present when any <tab> or <tabs> tags are present.
  * The margin: 0px is to determine whether the browser supports the general 
sibling selector ~. If it doesn't, there is "no margin" for interactivity, so 
JS is not activated.
  */
-#tabs-inputform {font-family: sans-serif !important;margin: 0px !important;}
+#tabs-inputform {
+       font-family: sans-serif !important;
+       margin: 0px !important;
+}
 head~body #tabs-inputform {margin: 1px !important;}
 body:not(oldbrowser) #tabs-inputform {font-family: serif !important;}
 
@@ -91,6 +95,15 @@
        display: inline-block;
        vertical-align: bottom;
 }
+.tabs-tabbox .tabs-content-0 {
+       display: inline-block;
+}
+.tabs-tabbox .tabs-block.tabs-content-0 {
+       display: block;
+}
+.tabs-tabbox .tabs-inline.tabs-content-0 {
+       display: inline;
+}
 .tabs-plain > .tabs-label {
        border: 1px solid #AAA;
        border-radius: 8px;
@@ -105,6 +118,7 @@
 
 .tabs-togglebox > .tabs-container {
        display: inline-block; /* this is to make the box the minimal width it 
needs to be */
+       width: inherit;
        padding: 0;
        border-radius: 8px;
 }
diff --git a/ext.tabs.js b/ext.tabs.js
index 2c11d88..5ed0c87 100644
--- a/ext.tabs.js
+++ b/ext.tabs.js
@@ -1,9 +1,13 @@
 $(function() {
-       if ($('#tabs-inputform').css('font-family').replace(/["']/g,'') == 
'sans-serif' && $('#tabs-inputform').css('margin') == '1px') {
        // Credit for this testing method: 2astalavista @ 
http://stackoverflow.com/a/21095568/1256925
+       // The font will be sans-serif if the :not() property is supported. The 
margin will be 1px if the sibling selector is supported.
+       if ($('#tabs-inputform').css('font-family').replace(/["']/g,'') == 
'sans-serif' && $('#tabs-inputform').css('margin') == '1px') {
                $(function() {
                        $('body').addClass('tabs-oldbrowserscript'); // Make 
the unselected tabs hide when the browser loads this script
-                       $('.tabs-label').click(function(e) { 
$('#'+$(this).attr('for')).click(); e.preventDefault(); return false; });
+                       $('.tabs-label').click(function(e) {
+                               $('#'+$(this).attr('for')).click(); 
e.preventDefault();
+                               return false;
+                       });
                        $('.tabs-input').each(function() {
                                if (this.checked) $(this).addClass('checked'); 
// Adds checked class to each checked box
                        }).change(function() {
@@ -15,9 +19,9 @@
                        });
                        moveToHash();
                });
-       } else
+       } else {
                $(moveToHash);
-
+       }
        /**
         * Imitates the normal feature in browsers to scroll to an id that has 
the same id as the url fragment/hash.
         * This makes it unnecessary to use actual ids on the tabs, which could 
cause the same id to occur twice in the same document.
@@ -42,17 +46,17 @@
         * Idea for the use of <detail> and <summary> based on 
http://stackoverflow.com/q/21357641/1256925
         */
        var nua = navigator.userAgent;
-       var is_android = ((nua.indexOf('Mozilla/5.0') > -1 && 
nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1) && 
!(nua.indexOf('Chrome') > -1));
-       if (is_android) {
-               function replaces() { //General replacement function for both 
tags
-                       var tagName = $(this).is('.tabs-container') ? 'details' 
: 'summary'; //determine the required tag name
-                       var $newNode = $('<'+tagName+'/>').html($(this).html());
-                       for (var i=0;i<this.attributes.length;i++) { //copy all 
attributes from the original element
-                               if (this.attributes[i].nodeName === 'for') 
continue; //don't copy the label's for="" attribute, since it's not needed here.
-                               $newNode.attr(this.attributes[i].nodeName, 
this.attributes[i].value);
-                       }
-                       return $newNode;
+       var is_android = (nua.indexOf('Mozilla/5.0') > -1 && 
nua.indexOf('Android ') > -1 && nua.indexOf('AppleWebKit') > -1 && 
nua.indexOf('Chrome') === -1);
+       function replaces() { //General replacement function for both tags
+               var tagName = $(this).is('.tabs-container') ? 'details' : 
'summary'; //determine the required tag name
+               var $newNode = $('<'+tagName+'/>').html($(this).html());
+               for (var i=0;i<this.attributes.length;i++) { //copy all 
attributes from the original element
+                       if (this.attributes[i].nodeName === 'for') continue; 
//don't copy the label's for="" attribute, since it's not needed here.
+                       $newNode.attr(this.attributes[i].nodeName, 
this.attributes[i].value);
                }
+               return $newNode;
+       }
+       if (is_android) {
                $('.tabs-togglebox .tabs-container').not('.tabs-dropdown 
.tabs-container').replaceWith(replaces); //do not select dropdowns, which 
already work in Android
                $('.tabs-togglebox .tabs-label').not('.tabs-dropdown 
.tabs-label').each(function() {
                        if ($(this).prevAll('input').prop('checked')) { 
//preserve open state of the toggle box
@@ -60,4 +64,4 @@
                        }
                }).replaceWith(replaces); //Run this *after* the 
.tabs-container has finished, otherwise all .tabs-label elements will be 
skipped.
        }
-});
\ No newline at end of file
+});

-- 
To view, visit https://gerrit.wikimedia.org/r/184126
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Iff726f885bbd4b55d66dc0d2055e64eb7344cb4d
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/Tabs
Gerrit-Branch: master
Gerrit-Owner: Joeytje50 <joeytj...@gmail.com>
Gerrit-Reviewer: Joeytje50 <joeytj...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to