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 <[email protected]>
Gerrit-Reviewer: Joeytje50 <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits