r114064 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r114063‎ | r114064 | r114065 >
Date:20:44, 17 March 2012
Author:rsterbin
Status:resolved (Comments)
Tags:
Comment:
Brought trigger links into the plugin itself; styled flyover panel:
- modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.js:
* Brought in trigger links, standardized them, and added the disable
flyover.
- New property selectedLinks
- New template disableFlyover
- Added object triggerLinks (like buckets and ctas)
- Added selecting and insertion of trigger links to init()
- New methods selectTriggerLinks(), addTriggerLinks(),
buildDisableFlyover(), and clickTriggerLink()
- Updated buildLink() to handle a flexible number of replacements, and
to handle tags other than links
- modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.css:
- Updated flyover styles to match latest mockup and to work with both
link E and link A
- Added trigger link styles from ext.articleFeedbackv5.css
- modules/ext.articleFeedbackv5/ext.articleFeedbackv5.css:
- Removed trigger link styles
- modules/ext.articleFeedbackv5/ext.articleFeedbackv5.js:
- Removed building of trigger links
- Plugin is now attached after it's been added to the page, so that
trigger links can be inserted relative to it
- ArticleFeedbackv5.i18n.php:
- Changed messages and wording to match latest mockup
- Put in real doc lines
- ArticleFeedbackv5.hooks.php:
- Updated to match new messages
Modified paths:
  • /trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.hooks.php (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.i18n.php (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/modules/ext.articleFeedbackv5/ext.articleFeedbackv5.css (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/modules/ext.articleFeedbackv5/ext.articleFeedbackv5.js (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.css (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.js (modified) (history)

Diff [purge]

Index: trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.i18n.php
@@ -420,14 +420,12 @@
421421 publicized to the community for this testing period.',
422422
423423 /* Front-end: feedback link close button */
424 - 'articlefeedbackv5-link-close-caption' => 'Remove article feedback?',
425 - 'articlefeedbackv5-link-close-text1' => 'To remove this widget, go to', // FIXME: Patchwork message
426 - 'articlefeedbackv5-link-close-linktext' => '"My preferences > Appearance"', // FIXME: Patchwork message
427 - 'articlefeedbackv5-link-close-linkurl' => '#', // FIXME: Patchwork message
428 - 'articlefeedbackv5-link-close-text2' => 'then check this box:', // FIXME: Patchwork message
429 - 'articlefeedbackv5-link-cllse-text3' => '"Do not show the Article Feedback widget."', // FIXME: Patchwork message
430 - 'articlefeedbackv5-link-close-submit' => 'Remove',
431 - 'articlefeedbackv5-link-close-cancel' => 'Cancel',
 424+ 'articlefeedbackv5-disable-flyover-title' => 'Remove this tool?',
 425+ 'articlefeedbackv5-disable-flyover-help-goto' => 'To remove $1, go to',
 426+ 'articlefeedbackv5-disable-flyover-help-emphasis-text' => 'Article Feedback',
 427+ 'articlefeedbackv5-disable-flyover-help-location' => 'My preferences > Appearance',
 428+ 'articlefeedbackv5-disable-flyover-help-direction' => 'and check',
 429+ 'articlefeedbackv5-disable-flyover-prefbutton' => 'Go to my preferences',
432430
433431 );
434432
@@ -702,13 +700,13 @@
703701 * <code>$2</code> – Page name of item with feedback requiring oversight.
704702 * <code>$3</code> – URL directly to feedback location
705703 * <code>$4</code> – The help link.',
706 - 'articlefeedbackv5-link-close-caption' => 'Remove article feedback tipsy - caption',
707 - 'articlefeedbackv5-link-close-text1' => 'Remove article feedback tipsy - text line 1',
708 - 'articlefeedbackv5-link-close-linktext' => 'Remove article feedback tipsy - text for close link',
709 - 'articlefeedbackv5-link-close-text2' => 'Remove article feedback tipsy - text line 2',
710 - 'articlefeedbackv5-link-cllse-text3' => 'Remove article feedback tipsy - text line 3. Identical to the text of {{msg-mw|Articlefeedbackv5-disable-preference}}',
711 - 'articlefeedbackv5-link-close-submit' => 'Remove article feedback tipsy - confirm button text',
712 - 'articlefeedbackv5-link-close-cancel' => 'Remove article feedback tipsy - cancel link text',
 704+ 'articlefeedbackv5-disable-flyover-title' => 'Title of the tooltip that pops up when you click the close button on a feedback trigger link, explaining how to remove the Article Feedback tool',
 705+ 'articlefeedbackv5-disable-flyover-help-goto' => 'Help text for the tooltip that pops up when you click the close button on a feedback trigger link, explaining where to go to remove the Article Feedback tool. <code>$1</code>: Emphasized name of the tool (text is {{msg-mw|articlefeedbackv5-disable-flyover-help-emphasis-text}})',
 706+ 'articlefeedbackv5-disable-flyover-help-emphasis-text' => 'The emphasis text for {{msg-mw|articlefeedbackv5-disable-flyover-help-goto}}',
 707+ 'articlefeedbackv5-disable-flyover-help-location' => 'A short indication of where to go to change your Article Feedback preferences, immediately below {{msg-mw|articlefeedbackv5-disable-flyover-help-goto}}',
 708+ 'articlefeedbackv5-disable-flyover-help-direction' => 'Help text for what to do once you get to the preferences panel (name of checkbox will be on the line below)',
 709+ 'articlefeedbackv5-disable-flyover-prefbutton' => 'The text of the big glossy button used to send the user to their preferences in the tooltip that pops up when you click the close button on a feedback trigger link, explaining how to remove the Article Feedback tool',
 710+
713711 );
714712
715713 /** Afrikaans (Afrikaans)
Index: trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.css
@@ -1032,10 +1032,103 @@
10331033 border-radius: 0;
10341034 }
10351035
1036 -/* Tipsy */
1037 -tipsy {
1038 - padding: 5px 5px 11px 5px;
 1036+/** Styles for feedback links **/
 1037+
 1038+#articleFeedbackv5-titlebarlink {
 1039+ float: right;
 1040+ font-size: 85%;
 1041+ font-weight: bold;
 1042+ line-height: 1.5em;
 1043+ margin: 5px 0;
 1044+ padding: 0;
 1045+ position: absolute;
 1046+ right: 0;
 1047+ text-align: right;
 1048+ text-indent: 0;
 1049+ text-transform: none;
 1050+ top: 0;
 1051+ white-space: nowrap;
10391052 }
 1053+
 1054+.articleFeedbackv5-fixedtab {
 1055+ position: fixed;
 1056+ margin: 0;
 1057+ right: 0;
 1058+ top: 200px;
 1059+}
 1060+.articleFeedbackv5-fixedtabbox {
 1061+ position: relative;
 1062+ /*-moz-transform:rotate(90deg);
 1063+ -moz-transform-origin: top left;
 1064+ -webkit-transform: rotate(90deg);
 1065+ -webkit-transform-origin: top left;
 1066+ -o-transform: rotate(90deg);
 1067+ -o-transform-origin: top left;
 1068+ -ms-transform: rotate(90deg);
 1069+ -ms-transform-origin: top left;
 1070+ transform: rotate(90deg);
 1071+ transform-origin: top left;*/
 1072+}
 1073+.articleFeedbackv5-fixedtablink {
 1074+ /*border: none;
 1075+ background-color: #5373a6;
 1076+ -moz-border-radius: 0 0 10px 10px;
 1077+ -webkit-border-radius: 0 0 10px 10px;
 1078+ -ms-border-radius: 0 0 10px 10px;
 1079+ border-radius: 0 0 10px 10px;
 1080+ min-width: 105px;*/
 1081+ width: 27px;
 1082+ height: 114px;
 1083+ right: 0;
 1084+ display: block;
 1085+ margin: 0;
 1086+ /* @embed */
 1087+ background: url(images/img_aftv5_tablink.png) no-repeat;
 1088+ /*padding: 5px 10px;
 1089+ color: #fff;
 1090+ text-align: center;
 1091+ writing-mode: tb-rl;*/
 1092+ position: absolute;
 1093+ z-index: 999;
 1094+}
 1095+.articleFeedbackv5-fixedtablink:hover {
 1096+ text-decoration: none;
 1097+}
 1098+
 1099+.articleFeedbackv5-bottomrighttab {
 1100+ position: fixed;
 1101+ margin: 0;
 1102+ right: 0;
 1103+ bottom: 0;
 1104+ height: 27px;
 1105+ width: 141px;
 1106+}
 1107+.articleFeedbackv5-bottomrighttabbox {
 1108+ position: relative;
 1109+}
 1110+.articleFeedbackv5-bottomrighttablink {
 1111+ border: none;
 1112+ border-top: 1px solid gray;
 1113+ border-left: 1px solid gray;
 1114+ color: #000;
 1115+ background-color: #d0e1f4;
 1116+ min-width: 105px;
 1117+ right: 0;
 1118+ display: block;
 1119+ margin: 0;
 1120+ padding: 5px 10px;
 1121+ text-align: center;
 1122+ position: absolute;
 1123+ z-index: 999;
 1124+}
 1125+.articleFeedbackv5-bottomrighttablink:hover {
 1126+ text-decoration: none;
 1127+}
 1128+.articleFeedbackv5-bottomrighttablink.articleFeedbackv5-closeable {
 1129+ white-space: nowrap;
 1130+}
 1131+
 1132+/* Disable flyover */
10401133 .tipsy-inner {
10411134 padding: 0;
10421135 border-color: #888;
@@ -1046,30 +1139,34 @@
10471140 margin-bottom: 5px;
10481141 font-size: 0.9em;
10491142 }
1050 -.tipsy-se .tipsy-arrow {
 1143+.tipsy-arrow {
10511144 /* @embed */
10521145 background-image: url(images/tipsy-flyover.png);
10531146 width: 23px;
10541147 height: 11px;
 1148+}
 1149+.tipsy-nw .tipsy-arrow {
 1150+ margin-top: -6px;
 1151+}
 1152+.tipsy-se .tipsy-arrow {
10551153 margin-top: -11px;
10561154 }
1057 -.articlefeedbackv5-flyover-header {
1058 - background-color: #d2e5f7;
1059 - padding: 5px 10px 8px 10px;
 1155+.articleFeedbackv5-disable-flyover {
 1156+ padding: 10px;
 1157+}
 1158+.articleFeedbackv5-flyover-header {
10601159 -moz-border-radius: 3px 3px 0 0;
10611160 -webkit-border-radius: 3px 3px 0 0;
10621161 border-radius: 3px 3px 0 0;
10631162 -khtml-border-radius: 3px 3px 0 0;
1064 - width: 200px;
10651163 }
1066 -.articlefeedbackv5-flyover-header h3 {
1067 - font-size: 1.0em;
 1164+.articleFeedbackv5-flyover-header h3 {
 1165+ font-size: 1.1em;
10681166 }
1069 -.articlefeedbackv5-flyover-footer {
1070 - padding: 10px 10px 15px 10px;
 1167+.articleFeedbackv5-flyover-footer {
10711168 width: 100%;
10721169 }
1073 -#articlefeedbackv5-noteflyover-close {
 1170+#articleFeedbackv5-noteflyover-close {
10741171 display: block;
10751172 position: absolute;
10761173 top: 0;
@@ -1083,10 +1180,28 @@
10841181 background-position: left top;
10851182 background-size: 16px 16px;
10861183 }
1087 -#articlefeedbackv5-noteflyover-close:hover {
 1184+#articleFeedbackv5-noteflyover-close:hover {
10881185 /* @embed */
10891186 background-image: url(images/bg-close-hov.png);
10901187 }
1091 -div.articlefeedbackv5-form-flyover {
1092 - padding: 10px 20px 10px 10px;
 1188+.articleFeedbackv5-trigger-link-holder .articleFeedbackv5-close-trigger-link {
 1189+ visibility: hidden;
10931190 }
 1191+.articleFeedbackv5-trigger-link-holder:hover .articleFeedbackv5-close-trigger-link {
 1192+ visibility: visible;
 1193+}
 1194+.articleFeedbackv5-trigger-link-holder.articleFeedbackv5-tipsy-active .articleFeedbackv5-close-trigger-link {
 1195+ visibility: visible;
 1196+}
 1197+.articleFeedbackv5-trigger-link-holder .articleFeedbackv5-close-trigger-link {
 1198+ /* @embed */
 1199+ background: url(images/bg-close-hov.png) no-repeat;
 1200+ background-size: 16px 16px;
 1201+ display: inline-block;
 1202+ width: 16px;
 1203+ height: 16px;
 1204+ vertical-align: middle;
 1205+}
 1206+.tipsy.articleFeedbackv5-disable-flyover-tip-E {
 1207+ position: fixed;
 1208+}
Index: trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.js
@@ -4,15 +4,18 @@
55 * This file creates the plugin that will be used to build the Article Feedback
66 * form. The flow goes like this:
77 *
8 - * User arrives at page -> build appropriate form
9 - * -> User clicks the view link -> replace form with average ratings display
 8+ * User arrives at page -> build appropriate form and trigger link(s)
 9+ * -> User clicks trigger link -> open form in modal window
 10+ * -> User scrolls to end of article -> open form below article
1011 * -> User submits form -> submit to API
1112 * -> has errors -> show errors
1213 * -> has no errors -> select random CTA and display
1314 *
14 - * This plugin supports a choice of forms and CTAs. Each form option is called
15 - * a "bucket" because users are sorted into buckets and each bucket gets a
16 - * different form option. Right now, these buckets are:
 15+ * This plugin supports a choice of forms, trigger links, and CTAs. Each form
 16+ * option is called a "bucket" because users are sorted into buckets and each
 17+ * bucket gets a different form option.
 18+ *
 19+ * Right now, these buckets are:
1720 * 0. No Feedback
1821 * Shows nothing at all.
1922 * 1. Share Your Feedback
@@ -28,12 +31,27 @@
2932 * 5. Rate This Page
3033 * The existing article feedback tool, except that it can use any of the
3134 * CTA types.
 35+ *
 36+ * The available trigger links are:
 37+ * A. After the site tagline (below the article title)
 38+ * B. Below the titlebar on the right
 39+ * C. Button fixed to right side
 40+ * D. Button fixed to bottom right
 41+ * E. Same as D, with other colors
 42+ * F. Button fixed to left side -- NOT IMPLEMENTED
 43+ * G. Button below logo -- NOT IMPLEMENTED
 44+ * H. Link on each section bar
 45+ * TBX. In the toolbox section (always added)
 46+ *
3247 * The available CTAs are:
3348 * 0. Just a confirmation notice
3449 * 1. Edit this page
3550 * Just a big glossy button to send the user to the edit page.
36 - * 2. Take a survey - NOT implemented
37 - * Asks the user to take a survey, which will probably pop up in a new
 51+ * 2. Learn More
 52+ * Just a big glossy button to tell the user about how the wiki works
 53+ * (used if the user doesn't have edit privileges on the article).
 54+ * 3. Take a survey
 55+ * Asks the user to take an external survey, which will pop up in a new
3856 * window.
3957 *
4058 * This file is really long, so it's commented with manual fold markers. To use
@@ -104,6 +122,15 @@
105123 $.articleFeedbackv5.ctaId = '1';
106124
107125 /**
 126+ * The selected trigger links are the ones chosen to be loaded onto the
 127+ * page. Options are "-" or A-H
 128+ *
 129+ * @see $wgArticleFeedbackv5LinkBuckets
 130+ * @see http://www.mediawiki.org/wiki/Article_feedback/Version_5/Feature_Requirements#Feedback_links_on_article_pages
 131+ */
 132+ $.articleFeedbackv5.selectedLinks = [];
 133+
 134+ /**
108135 * The link ID indicates where the user clicked (or not) to get to the
109136 * feedback form. Options are "-" or A-H
110137 *
@@ -199,8 +226,30 @@
200227 </div>\
201228 ',
202229
203 - clear: '<div class="clear"></div>'
 230+ clear: '<div class="clear"></div>',
204231
 232+ disableFlyover: '\
 233+ <div>\
 234+ <div class="articleFeedbackv5-disable-flyover">\
 235+ <div class="articleFeedbackv5-flyover-header">\
 236+ <h3 id="articleFeedbackv5-noteflyover-caption"><html:msg key="disable-flyover-title" /></h3>\
 237+ <a id="articleFeedbackv5-noteflyover-close" class="articleFeedbackv5-form-flyover-closebutton" href="#"></a>\
 238+ </div>\
 239+ <div class="articleFeedbackv5-form-flyover">\
 240+ <div class="articleFeedbackv5-disable-flyover-help" >\
 241+ <p class="articleFeedbackv5-disable-flyover-help-goto"></p>\
 242+ <a class="articleFeedbackv5-disable-flyover-goto-link" target="_blank"><html:msg key="disable-flyover-help-location" /></a>\
 243+ <p><html:msg key="disable-flyover-help-direction" /></p>\
 244+ <p>&quot;<html:msg key="disable-preference" />&quot;</p>\
 245+ </div>\
 246+ <div class="articleFeedbackv5-flyover-footer">\
 247+ <a class="articleFeedbackv5-disable-flyover-button" target="_blank"><html:msg key="disable-flyover-prefbutton" /></a>\
 248+ </div>\
 249+ </div>\
 250+ </div>\
 251+ </div>\
 252+ '
 253+
205254 };
206255
207256 // }}}
@@ -2076,8 +2125,6 @@
20772126 */
20782127 getSurveyUrl: function () {
20792128 var base = mw.config.get( 'wgArticleFeedbackv5SurveyUrls' );
2080 - aft5_debug( base );
2081 - aft5_debug( $.articleFeedbackv5.bucketId );
20822129 if ( typeof base != 'object' || !( $.articleFeedbackv5.bucketId in base ) ) {
20832130 return false;
20842131 }
@@ -2137,6 +2184,521 @@
21382185 };
21392186
21402187 // }}}
 2188+ // {{{ Trigger link objects
 2189+
 2190+ /**
 2191+ * Set up the trigger link options
 2192+ */
 2193+ $.articleFeedbackv5.triggerLinks = {
 2194+
 2195+ // {{{ A: After the site tagline (below the article title)
 2196+
 2197+ 'A': {
 2198+
 2199+ // {{{ templates
 2200+
 2201+ /**
 2202+ * Pull out the markup so it's easy to find
 2203+ */
 2204+ templates: {
 2205+
 2206+ /**
 2207+ * The link template, when it does not include a close button
 2208+ */
 2209+ basic: '<span><a href="#mw-articleFeedbackv5" id="articleFeedbackv5-sitesublink"></a></span>',
 2210+
 2211+ /**
 2212+ * The link template, when it includes a close button
 2213+ */
 2214+ closeable: '\
 2215+ <span>\
 2216+ <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-sitesublink"></a>\
 2217+ <a href="#" class="articleFeedbackv5-close-trigger-link"></a>\
 2218+ </span>\
 2219+ '
 2220+
 2221+ },
 2222+
 2223+ // }}}
 2224+ // {{{ closeable
 2225+
 2226+ /**
 2227+ * Returns whether the link includes a close button
 2228+ *
 2229+ * @return boolean
 2230+ */
 2231+ closeable: function () {
 2232+ return mw.user.name() != null;
 2233+ },
 2234+
 2235+ // }}}
 2236+ // {{{ build
 2237+
 2238+ /**
 2239+ * Builds the trigger link
 2240+ *
 2241+ * @return Element the link
 2242+ */
 2243+ build: function () {
 2244+ var self = $.articleFeedbackv5.triggerLinks['A'];
 2245+ var $link = $( self.closeable() ? self.templates.closeable : self.templates.basic )
 2246+ $link.find('#articleFeedbackv5-sitesublink')
 2247+ .data( 'linkId', 'A' )
 2248+ .text( mw.msg( 'articlefeedbackv5-sitesub-linktext' ) )
 2249+ .click( function ( e ) {
 2250+ e.preventDefault();
 2251+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2252+ } );
 2253+ return $link;
 2254+ },
 2255+
 2256+ // }}}
 2257+ // {{{ insert
 2258+
 2259+ /**
 2260+ * Inserts the link into the page
 2261+ *
 2262+ * @param Element $link the link
 2263+ */
 2264+ insert: function ( $link ) {
 2265+ // The link is going to be at different markup locations on different skins,
 2266+ // and it needs to show up if the site subhead (e.g., "From Wikipedia, the free
 2267+ // encyclopedia") is not visible for any reason.
 2268+ if ( $( '#siteSub' ).filter( ':visible' ).length ) {
 2269+ $( '#siteSub' ).append( ' &nbsp; ' ).append( $link );
 2270+ } else if ( $( 'h1.pagetitle + p.subtitle' ).filter( ':visible' ).length ) {
 2271+ $( 'h1.pagetitle + p.subtitle' ).append( ' ' ).append( $link );
 2272+ } else if ( $( '#mw_contentholder .mw-topboxes' ).length ) {
 2273+ $( '#mw_contentholder .mw-topboxes' ).after( $link );
 2274+ } else if ( $( '#bodyContent' ).length ) {
 2275+ $( '#bodyContent' ).prepend( $link );
 2276+ }
 2277+ }
 2278+
 2279+ // }}}
 2280+
 2281+ },
 2282+
 2283+ // }}}
 2284+ // {{{ B: Below the titlebar on the right
 2285+
 2286+ 'B': {
 2287+
 2288+ // {{{ closeable
 2289+
 2290+ /**
 2291+ * Returns whether the link includes a close button
 2292+ *
 2293+ * @return boolean
 2294+ */
 2295+ closeable: function () {
 2296+ return false;
 2297+ },
 2298+
 2299+ // }}}
 2300+ // {{{ build
 2301+
 2302+ /**
 2303+ * Builds the trigger link
 2304+ *
 2305+ * @return Element the link
 2306+ */
 2307+ build: function () {
 2308+ var $link = $( '<a href="#mw-articleFeedbackv5" id="articleFeedbackv5-titlebarlink"></a>' )
 2309+ .data( 'linkId', 'B' )
 2310+ .text( mw.msg( 'articlefeedbackv5-titlebar-linktext' ) )
 2311+ .click( function ( e ) {
 2312+ e.preventDefault();
 2313+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2314+ } );
 2315+ if ( $( '#coordinates' ).length ) {
 2316+ $link.css( 'margin-top: 2.5em' );
 2317+ }
 2318+ return $link;
 2319+ }
 2320+
 2321+ // }}}
 2322+
 2323+ },
 2324+
 2325+ // }}}
 2326+ // {{{ C: Button fixed to right side
 2327+
 2328+ 'C': {
 2329+
 2330+ // {{{ templates
 2331+
 2332+ /**
 2333+ * Pull out the markup so it's easy to find
 2334+ */
 2335+ templates: {
 2336+
 2337+ /**
 2338+ * The link template
 2339+ */
 2340+ block: '\
 2341+ <div id="articleFeedbackv5-fixedtab" class="articleFeedbackv5-fixedtab">\
 2342+ <div id="articleFeedbackv5-fixedtabbox" class="articleFeedbackv5-fixedtabbox">\
 2343+ <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-fixedtablink" class="articleFeedbackv5-fixedtablink"></a>\
 2344+ </div>\
 2345+ </div>'
 2346+
 2347+ },
 2348+
 2349+ // }}}
 2350+ // {{{ closeable
 2351+
 2352+ /**
 2353+ * Returns whether the link includes a close button
 2354+ *
 2355+ * @return boolean
 2356+ */
 2357+ closeable: function () {
 2358+ return false;
 2359+ },
 2360+
 2361+ // }}}
 2362+ // {{{ build
 2363+
 2364+ /**
 2365+ * Builds the trigger link
 2366+ *
 2367+ * @return Element the link
 2368+ */
 2369+ build: function () {
 2370+ var $link = $( $.articleFeedbackv5.triggerLinks['C'].templates.block );
 2371+ $link.find( '#articleFeedbackv5-fixedtablink' )
 2372+ .data( 'linkId', 'C' )
 2373+ .attr( 'title', mw.msg( 'articlefeedbackv5-fixedtab-linktext' ) )
 2374+ .click( function( e ) {
 2375+ e.preventDefault();
 2376+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2377+ } );
 2378+ return $link;
 2379+ }
 2380+
 2381+ // }}}
 2382+
 2383+ },
 2384+
 2385+ // }}}
 2386+ // {{{ D: Button fixed to bottom right
 2387+
 2388+ 'D': {
 2389+
 2390+ // {{{ templates
 2391+
 2392+ /**
 2393+ * Pull out the markup so it's easy to find
 2394+ */
 2395+ templates: {
 2396+
 2397+ /**
 2398+ * The link template
 2399+ */
 2400+ block: '\
 2401+ <div id="articleFeedbackv5-bottomrighttab" class="articleFeedbackv5-bottomrighttab">\
 2402+ <div id="articleFeedbackv5-bottomrighttabbox" class="articleFeedbackv5-bottomrighttabbox">\
 2403+ <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-bottomrighttablink" class="articleFeedbackv5-bottomrighttablink"></a>\
 2404+ </div>\
 2405+ </div>'
 2406+
 2407+ },
 2408+
 2409+ // }}}
 2410+ // {{{ closeable
 2411+
 2412+ /**
 2413+ * Returns whether the link includes a close button
 2414+ *
 2415+ * @return boolean
 2416+ */
 2417+ closeable: function () {
 2418+ return false;
 2419+ },
 2420+
 2421+ // }}}
 2422+ // {{{ build
 2423+
 2424+ /**
 2425+ * Builds the trigger link
 2426+ *
 2427+ * @return Element the link
 2428+ */
 2429+ build: function () {
 2430+ var $link = $( $.articleFeedbackv5.triggerLinks['D'].templates.block );
 2431+ $link.find( '#articleFeedbackv5-bottomrighttablink' )
 2432+ .data( 'linkId', 'D' )
 2433+ .text( mw.msg( 'articlefeedbackv5-bottomrighttab-linktext' ) )
 2434+ .click( function( e ) {
 2435+ e.preventDefault();
 2436+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2437+ } );
 2438+ return $link;
 2439+ }
 2440+
 2441+ // }}}
 2442+
 2443+ },
 2444+
 2445+ // }}}
 2446+ // {{{ E: Same as D, with other colors
 2447+
 2448+ 'E': {
 2449+
 2450+ // {{{ templates
 2451+
 2452+ /**
 2453+ * Pull out the markup so it's easy to find
 2454+ */
 2455+ templates: {
 2456+
 2457+ /**
 2458+ * The link template, when it does not include a close button
 2459+ */
 2460+ basic: '\
 2461+ <div id="articleFeedbackv5-bottomrighttab" class="articleFeedbackv5-bottomrighttab">\
 2462+ <div id="articleFeedbackv5-bottomrighttabbox" class="articleFeedbackv5-bottomrighttabbox">\
 2463+ <div class="articleFeedbackv5-bottomrighttablink">\
 2464+ <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-bottomrighttablink"></a>\
 2465+ </div>\
 2466+ </div>\
 2467+ </div>\
 2468+ ',
 2469+
 2470+ /**
 2471+ * The link template, when it includes a close button
 2472+ */
 2473+ closeable: '\
 2474+ <div id="articleFeedbackv5-bottomrighttab" class="articleFeedbackv5-bottomrighttab articleFeedbackv5-trigger-link">\
 2475+ <div id="articleFeedbackv5-bottomrighttabbox" class="articleFeedbackv5-bottomrighttabbox">\
 2476+ <div class="articleFeedbackv5-bottomrighttablink articleFeedbackv5-closeable">\
 2477+ <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-bottomrighttablink"></a>\
 2478+ <a href="#" class="articleFeedbackv5-close-trigger-link"></a>\
 2479+ </div>\
 2480+ </div>\
 2481+ </div>\
 2482+ '
 2483+
 2484+ },
 2485+
 2486+ // }}}
 2487+ // {{{ closeable
 2488+
 2489+ /**
 2490+ * Returns whether the link includes a close button
 2491+ *
 2492+ * @return boolean
 2493+ */
 2494+ closeable: function () {
 2495+ return mw.user.name() != null;
 2496+ },
 2497+
 2498+ // }}}
 2499+ // {{{ build
 2500+
 2501+ /**
 2502+ * Builds the trigger link
 2503+ *
 2504+ * @return Element the link
 2505+ */
 2506+ build: function () {
 2507+ var self = $.articleFeedbackv5.triggerLinks['E'];
 2508+ var $link = $( self.closeable() ? self.templates.closeable : self.templates.basic );
 2509+ $link.find( '#articleFeedbackv5-bottomrighttablink' )
 2510+ .data( 'linkId', 'E' )
 2511+ .text( mw.msg( 'articlefeedbackv5-bottomrighttab-linktext' ) )
 2512+ .click( function( e ) {
 2513+ e.preventDefault();
 2514+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2515+ } );
 2516+ return $link;
 2517+ }
 2518+
 2519+ // }}}
 2520+
 2521+ },
 2522+
 2523+ // }}}
 2524+ // {{{ F: Button fixed to left side -- NOT IMPLEMENTED
 2525+
 2526+ 'F': {
 2527+
 2528+ // {{{ closeable
 2529+
 2530+ /**
 2531+ * Returns whether the link includes a close button
 2532+ *
 2533+ * @return boolean
 2534+ */
 2535+ closeable: function () {
 2536+ return false;
 2537+ },
 2538+
 2539+ // }}}
 2540+ // {{{ build
 2541+
 2542+ /**
 2543+ * Builds the trigger link
 2544+ *
 2545+ * @return Element the link
 2546+ */
 2547+ build: function () {
 2548+ }
 2549+
 2550+ // }}}
 2551+
 2552+ },
 2553+
 2554+ // }}}
 2555+ // {{{ G: Button below logo -- NOT IMPLEMENTED
 2556+
 2557+ 'G': {
 2558+
 2559+ // {{{ closeable
 2560+
 2561+ /**
 2562+ * Returns whether the link includes a close button
 2563+ *
 2564+ * @return boolean
 2565+ */
 2566+ closeable: function () {
 2567+ return false;
 2568+ },
 2569+
 2570+ // }}}
 2571+ // {{{ build
 2572+
 2573+ /**
 2574+ * Builds the trigger link
 2575+ *
 2576+ * @return Element the link
 2577+ */
 2578+ build: function () {
 2579+ }
 2580+
 2581+ // }}}
 2582+
 2583+ },
 2584+
 2585+ // }}}
 2586+ // {{{ H: Link on each section bar
 2587+
 2588+ 'H': {
 2589+
 2590+ // {{{ closeable
 2591+
 2592+ /**
 2593+ * Returns whether the link includes a close button
 2594+ *
 2595+ * @return boolean
 2596+ */
 2597+ closeable: function () {
 2598+ return false;
 2599+ },
 2600+
 2601+ // }}}
 2602+ // {{{ build
 2603+
 2604+ /**
 2605+ * Builds the trigger link
 2606+ *
 2607+ * @return Element the link
 2608+ */
 2609+ build: function () {
 2610+ var $wrap = $( '<span class="articleFeedbackv5-sectionlink-wrap"></span>' )
 2611+ .html( '&nbsp;[<a href="#mw-articlefeedbackv5" class="articleFeedbackv5-sectionlink"></a>]' );
 2612+ $wrap.find( 'a.articleFeedbackv5-sectionlink' )
 2613+ .data( 'linkId', 'H' )
 2614+ .text( mw.msg( 'articlefeedbackv5-section-linktext' ) )
 2615+ .click( function ( e ) {
 2616+ e.preventDefault();
 2617+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2618+ } );
 2619+ return $wrap;
 2620+ },
 2621+
 2622+ // }}}
 2623+ // {{{ insert
 2624+
 2625+ /**
 2626+ * Inserts the link into the page
 2627+ *
 2628+ * @param Element $link the link
 2629+ */
 2630+ insert: function ( $link ) {
 2631+ $( 'span.editsection' ).append( $link );
 2632+ }
 2633+
 2634+ // }}}
 2635+
 2636+ },
 2637+
 2638+ // }}}
 2639+ // {{{ TBX: In the toolbox section (always added)
 2640+
 2641+ 'TBX': {
 2642+
 2643+ // {{{ closeable
 2644+
 2645+ /**
 2646+ * Returns whether the link includes a close button
 2647+ *
 2648+ * @return boolean
 2649+ */
 2650+ closeable: function () {
 2651+ return false;
 2652+ },
 2653+
 2654+ // }}}
 2655+ // {{{ build
 2656+
 2657+ /**
 2658+ * Builds the trigger link
 2659+ *
 2660+ * @return Element the link
 2661+ */
 2662+ build: function () {
 2663+ var $link = $( '<li id="t-articlefeedbackv5"><a href="#mw-articlefeedbackv5"></a></li>' );
 2664+ $link.find( 'a' ).text( mw.msg( 'articlefeedbackv5-toolbox-linktext' ) );
 2665+ if ( '5' == $.articleFeedbackv5.bucketId ) {
 2666+ $link.find( 'a' )
 2667+ .click( function ( e ) {
 2668+ // Just set the link ID -- this should act just like AFTv4
 2669+ $.articleFeedbackv5.setLinkId( 'TBX' );
 2670+ } );
 2671+ } else {
 2672+ $link.find( 'a' )
 2673+ .data( 'linkId', 'TBX' )
 2674+ .click( function ( e ) {
 2675+ e.preventDefault();
 2676+ $.articleFeedbackv5.clickTriggerLink( $( e.target ) );
 2677+ } );
 2678+ }
 2679+ return $link;
 2680+ },
 2681+
 2682+ // }}}
 2683+ // {{{ insert
 2684+
 2685+ /**
 2686+ * Inserts the link into the page
 2687+ *
 2688+ * @param Element $link the link
 2689+ */
 2690+ insert: function ( $link ) {
 2691+ $( '#p-tb' ).find( 'ul' ).append( $link );
 2692+ }
 2693+
 2694+ // }}}
 2695+
 2696+ }
 2697+
 2698+ // }}}
 2699+
 2700+ };
 2701+
 2702+ // }}}
21412703 // {{{ Initialization
21422704
21432705 // {{{ init
@@ -2174,6 +2736,9 @@
21752737 } );
21762738 // Keep track of links that must be removed after a successful submission
21772739 $.articleFeedbackv5.$toRemove = $( [] );
 2740+ // Select the trigger link(s)
 2741+ $.articleFeedbackv5.selectTriggerLinks();
 2742+ $.articleFeedbackv5.addTriggerLinks();
21782743 // Track init at 1%
21792744 if ( Math.random() * 100 < 1 ) {
21802745 $.articleFeedbackv5.trackClick( $.articleFeedbackv5.bucketName() + '-init' );
@@ -2184,7 +2749,7 @@
21852750 // {{{ selectBucket
21862751
21872752 /**
2188 - * Chooses a bucket and loads the appropriate form
 2753+ * Chooses a bucket
21892754 *
21902755 * If the plugin is in debug mode, you'll be able to pass in a particular
21912756 * bucket in the url. Otherwise, it will use the core bucketing
@@ -2244,8 +2809,46 @@
22452810 };
22462811
22472812 // }}}
 2813+ // {{{ selectTriggerLinks
22482814
 2815+ /**
 2816+ * Chooses the trigger link(s) to add
 2817+ *
 2818+ * If the plugin is in debug mode, you'll be able to pass in a particular
 2819+ * link in the url. Otherwise, it will use the core bucketing
 2820+ * (configuration for this module passed in) to choose a trigger link.
 2821+ */
 2822+ $.articleFeedbackv5.selectTriggerLinks = function () {
 2823+ // The bucketed link:
 2824+ // 1. Display buckets 0 or 5? Always no link.
 2825+ // 2. Requested in query string (debug only)
 2826+ // 3. Random bucketing
 2827+ var bucketedLink = '-';
 2828+ if ( '5' != $.articleFeedbackv5.bucketId && '0' != $.articleFeedbackv5.bucketId ) {
 2829+ var cfg = mw.config.get( 'wgArticleFeedbackv5LinkBuckets' );
 2830+ if ( 'buckets' in cfg ) {
 2831+ var knownBuckets = cfg.buckets;
 2832+ var requested = mw.util.getParamValue( 'aftv5_link' );
 2833+ if ( $.articleFeedbackv5.inDebug() && requested in knownBuckets ) {
 2834+ bucketedLink = requested;
 2835+ } else {
 2836+ bucketedLink = mw.user.bucket( 'ext.articleFeedbackv5-links', cfg );
 2837+ }
 2838+ }
 2839+ }
 2840+ if ( $.articleFeedbackv5.inDebug() ) {
 2841+ aft5_debug( 'Using link option ' + bucketedLink );
 2842+ }
 2843+ if ('-' != bucketedLink) {
 2844+ $.articleFeedbackv5.selectedLinks.push(bucketedLink);
 2845+ }
 2846+ // Always add the toolbox link
 2847+ $.articleFeedbackv5.selectedLinks.push('TBX');
 2848+ };
 2849+
22492850 // }}}
 2851+
 2852+ // }}}
22502853 // {{{ Utility methods
22512854
22522855 // {{{ prefix
@@ -2304,24 +2907,15 @@
23052908 */
23062909 $.articleFeedbackv5.buildLink = function ( fulltext, link1, link2, link3 ) {
23072910 var full = mw.html.escape( mw.msg( fulltext ) );
2308 - if ( link1 ) {
2309 - full = full.replace(
2310 - /\$1/,
2311 - mw.html.element( 'a', $.articleFeedbackv5.attribs( link1 ), mw.msg( link1.text )
 2911+ for ( var i = 1; i < arguments.length; i++ ) {
 2912+ var sub = arguments[i];
 2913+ var re = new RegExp("\\$" + i);
 2914+ full = full.replace( re, mw.html.element(
 2915+ 'tag' in sub ? sub.tag : 'a',
 2916+ $.articleFeedbackv5.attribs( sub ),
 2917+ mw.msg( sub.text )
23122918 ).toString() );
23132919 }
2314 - if ( link2 ) {
2315 - full = full.replace(
2316 - /\$2/,
2317 - mw.html.element( 'a', $.articleFeedbackv5.attribs( link2 ), mw.msg( link2.text )
2318 - ).toString() );
2319 - }
2320 - if ( link3 ) {
2321 - full = full.replace(
2322 - /\$3/,
2323 - mw.html.element( 'a', $.articleFeedbackv5.attribs( link3 ), mw.msg( link3.text )
2324 - ).toString() );
2325 - }
23262920 return full;
23272921 };
23282922
@@ -2339,7 +2933,7 @@
23402934 $.articleFeedbackv5.attribs = function ( link ) {
23412935 var attr = {};
23422936 for ( var k in link ) {
2343 - if ( 'text' != k ) {
 2937+ if ( 'text' != k && 'tag' != k ) {
23442938 attr[k] = link[k];
23452939 }
23462940 }
@@ -2701,9 +3295,9 @@
27023296 $.articleFeedbackv5.showCTA( $.articleFeedbackv5.inDialog ? 'overlay' : 'bottom' );
27033297 // Drop a cookie for a successful submit
27043298 $.cookie( $.articleFeedbackv5.prefix( 'submitted' ), 'true', { 'expires': 365, 'path': '/' } );
2705 - // Clear out anything that needs removing (usually feedback links)
 3299+ // Clear out anything that needs removing (usually trigger links)
27063300 // Comment this out and uncomment the clear on dialog close to switch to
2707 - // the feedback link replacing the form. _SWITCH_CLEAR_
 3301+ // the trigger link replacing the form. _SWITCH_CLEAR_
27083302 $.articleFeedbackv5.$toRemove.remove();
27093303 $.articleFeedbackv5.$toRemove = $( [] );
27103304 } else {
@@ -2870,8 +3464,116 @@
28713465 };
28723466
28733467 // }}}
 3468+ // {{{ addTriggerLinks
28743469
 3470+ /**
 3471+ * Adds the trigger links to the page
 3472+ */
 3473+ $.articleFeedbackv5.addTriggerLinks = function () {
 3474+ hasTipsy = false;
 3475+ for ( var i in $.articleFeedbackv5.selectedLinks ) {
 3476+ var linkId = $.articleFeedbackv5.selectedLinks[i];
 3477+ if ( linkId in $.articleFeedbackv5.triggerLinks ) {
 3478+ var option = $.articleFeedbackv5.triggerLinks[linkId];
 3479+ var $link = option.build();
 3480+ if ( 'insert' in option ) {
 3481+ option.insert( $link );
 3482+ } else {
 3483+ $link.insertBefore( $.articleFeedbackv5.$holder );
 3484+ }
 3485+ if ( option.closeable ) {
 3486+ $.articleFeedbackv5.buildDisableFlyover( linkId, $link );
 3487+ hasTipsy = true;
 3488+ }
 3489+ if ( 'TBX' != linkId && '5' != $.articleFeedbackv5.bucketId ) {
 3490+ $.articleFeedbackv5.addToRemovalQueue( $link );
 3491+ }
 3492+ }
 3493+ }
 3494+ if ( hasTipsy ) {
 3495+ $( '.articleFeedbackv5-form-flyover-closebutton' ).live( 'click', function( e ) {
 3496+ e.preventDefault();
 3497+ var $host = $( '.articleFeedbackv5-trigger-link-' + $( e.target ).attr( 'rel' ) )
 3498+ $host.tipsy( 'hide' );
 3499+ $host.closest( '.articleFeedbackv5-trigger-link-holder' )
 3500+ .removeClass( 'articleFeedbackv5-tipsy-active' );
 3501+ } );
 3502+ }
 3503+ };
 3504+
28753505 // }}}
 3506+ // {{{ buildDisableFlyover
 3507+
 3508+ /**
 3509+ * Builds a disable flyover for a link
 3510+ *
 3511+ * @param string linkId the name of the link (A-H, TBX)
 3512+ * @param Element $link the link object
 3513+ */
 3514+ $.articleFeedbackv5.buildDisableFlyover = function ( linkId, $link ) {
 3515+ $link.addClass( 'articleFeedbackv5-trigger-link-holder' );
 3516+ $link.addClass( 'articleFeedbackv5-trigger-link-holder-' + linkId );
 3517+ var gravity = 'se';
 3518+ if ( 'A' == linkId ) {
 3519+ gravity = 'nw';
 3520+ }
 3521+ $link.find( '.articleFeedbackv5-close-trigger-link' )
 3522+ .addClass( 'articleFeedbackv5-trigger-link-' + linkId )
 3523+ .tipsy( {
 3524+ delayIn: 0,
 3525+ delayOut: 0,
 3526+ fade: false,
 3527+ fallback: '',
 3528+ gravity: gravity,
 3529+ html: true,
 3530+ live: false,
 3531+ offset: 10,
 3532+ opacity: 1.0,
 3533+ trigger: 'manual',
 3534+ className: 'articleFeedbackv5-disable-flyover-tip-' + linkId,
 3535+ title: function () {
 3536+ var $flyover = $( $.articleFeedbackv5.templates.disableFlyover );
 3537+ $flyover.localize( { 'prefix': 'articlefeedbackv5-' } );
 3538+ $flyover.find( '.articleFeedbackv5-disable-flyover' )
 3539+ .addClass( 'articleFeedbackv5-disable-flyover-' + linkId );
 3540+ var prefLink = mw.config.get( 'wgScript' ) + '?' +
 3541+ $.param( { title: 'Special:Preferences' } ) +
 3542+ '#mw-prefsection-rendering';
 3543+ $flyover.find( '.articleFeedbackv5-disable-flyover-help-goto' )
 3544+ .html( $.articleFeedbackv5.buildLink(
 3545+ 'articlefeedbackv5-disable-flyover-help-goto', {
 3546+ tag: 'strong',
 3547+ text: 'articlefeedbackv5-disable-flyover-help-emphasis-text'
 3548+ } ) );
 3549+ $flyover.find( '.articleFeedbackv5-disable-flyover-goto-link' )
 3550+ .attr( 'href', prefLink )
 3551+ $flyover.find( '.articleFeedbackv5-disable-flyover-button' )
 3552+ .attr( 'href', prefLink )
 3553+ .button()
 3554+ .addClass( 'ui-button-blue' );
 3555+ $flyover.find('.articleFeedbackv5-form-flyover-closebutton')
 3556+ .attr( 'href', '#hello' )
 3557+ .attr( 'rel', linkId );
 3558+ return $flyover.html();
 3559+ }
 3560+ } )
 3561+ .click( function ( e ) {
 3562+ e.preventDefault();
 3563+ var $host = $( e.target );
 3564+ var $wrap = $host.closest( '.articleFeedbackv5-trigger-link-holder' )
 3565+ if ( $wrap.hasClass( 'articleFeedbackv5-tipsy-active' ) ) {
 3566+ $host.tipsy( 'hide' );
 3567+ $wrap.removeClass( 'articleFeedbackv5-tipsy-active' );
 3568+ } else {
 3569+ $host.tipsy( 'show' );
 3570+ $wrap.addClass( 'articleFeedbackv5-tipsy-active' );
 3571+ }
 3572+ } );
 3573+ };
 3574+
 3575+ // }}}
 3576+
 3577+ // }}}
28763578 // {{{ UI methods
28773579
28783580 // {{{ markShowstopperError
@@ -2991,7 +3693,7 @@
29923694 // {{{ addToRemovalQueue
29933695
29943696 /**
2995 - * Adds an element (usually a feedback link) to the collection that will be
 3697+ * Adds an element (usually a trigger link) to the collection that will be
29963698 * removed after a successful submission
29973699 *
29983700 * @param $el Element the element
@@ -3054,7 +3756,7 @@
30553757 /**
30563758 * Opens the feedback tool as a modal window
30573759 *
3058 - * @param $link Element the feedback link
 3760+ * @param $link Element the trigger link
30593761 */
30603762 $.articleFeedbackv5.openAsModal = function ( $link ) {
30613763 if ( 'cta' == $.articleFeedbackv5.nowShowing ) {
@@ -3116,7 +3818,7 @@
31173819 /**
31183820 * Toggles the modal state
31193821 *
3120 - * @param $link Element the feedback link
 3822+ * @param $link Element the trigger link
31213823 */
31223824 $.articleFeedbackv5.toggleModal = function ( $link ) {
31233825 if ( $.articleFeedbackv5.inDialog ) {
@@ -3196,7 +3898,23 @@
31973899 };
31983900
31993901 // }}}
 3902+ // {{{ clickTriggerLink
32003903
 3904+ /**
 3905+ * Handles the click event on a trigger link
 3906+ *
 3907+ * @param $link Element the trigger link
 3908+ */
 3909+ $.articleFeedbackv5.clickTriggerLink = function( $link ) {
 3910+ var tracking_id = $.articleFeedbackv5.bucketName() +
 3911+ '-trigger' + $link.data( 'linkId' ) +
 3912+ '-click-overlay';
 3913+ $.articleFeedbackv5.trackClick( tracking_id );
 3914+ $.articleFeedbackv5.toggleModal( $link );
 3915+ };
 3916+
 3917+ // }}}
 3918+
32013919 // }}}
32023920 // {{{ articleFeedbackv5 plugin
32033921
Index: trunk/extensions/ArticleFeedbackv5/modules/ext.articleFeedbackv5/ext.articleFeedbackv5.css
@@ -1,93 +0,0 @@
2 -/** Styles for feedback links **/
3 -
4 -#articleFeedbackv5-titlebarlink {
5 - float: right;
6 - font-size: 85%;
7 - font-weight: bold;
8 - line-height: 1.5em;
9 - margin: 5px 0;
10 - padding: 0;
11 - position: absolute;
12 - right: 0;
13 - text-align: right;
14 - text-indent: 0;
15 - text-transform: none;
16 - top: 0;
17 - white-space: nowrap;
18 -}
19 -
20 -.articleFeedbackv5-fixedtab {
21 - position: fixed;
22 - margin: 0;
23 - right: 0;
24 - top: 200px;
25 -}
26 -.articleFeedbackv5-fixedtabbox {
27 - position: relative;
28 - /*-moz-transform:rotate(90deg);
29 - -moz-transform-origin: top left;
30 - -webkit-transform: rotate(90deg);
31 - -webkit-transform-origin: top left;
32 - -o-transform: rotate(90deg);
33 - -o-transform-origin: top left;
34 - -ms-transform: rotate(90deg);
35 - -ms-transform-origin: top left;
36 - transform: rotate(90deg);
37 - transform-origin: top left;*/
38 -}
39 -.articleFeedbackv5-fixedtablink {
40 - /*border: none;
41 - background-color: #5373a6;
42 - -moz-border-radius: 0 0 10px 10px;
43 - -webkit-border-radius: 0 0 10px 10px;
44 - -ms-border-radius: 0 0 10px 10px;
45 - border-radius: 0 0 10px 10px;
46 - min-width: 105px;*/
47 - width: 27px;
48 - height: 114px;
49 - right: 0;
50 - display: block;
51 - margin: 0;
52 - /* @embed */
53 - background: url(images/img_aftv5_tablink.png) no-repeat;
54 - /*padding: 5px 10px;
55 - color: #fff;
56 - text-align: center;
57 - writing-mode: tb-rl;*/
58 - position: absolute;
59 - z-index: 999;
60 -}
61 -.articleFeedbackv5-fixedtablink:hover {
62 - text-decoration: none;
63 -}
64 -
65 -.articleFeedbackv5-bottomrighttab {
66 - position: fixed;
67 - margin: 0;
68 - right: 0;
69 - bottom: 0;
70 - height: 27px;
71 - width: 141px;
72 -}
73 -.articleFeedbackv5-bottomrighttabbox {
74 - position: relative;
75 -}
76 -.articleFeedbackv5-bottomrighttablink {
77 - border: none;
78 - border-top: 1px solid gray;
79 - border-left: 1px solid gray;
80 - color: #000;
81 - background-color: #d0e1f4;
82 - min-width: 105px;
83 - right: 0;
84 - display: block;
85 - margin: 0;
86 - padding: 5px 10px;
87 - text-align: center;
88 - position: absolute;
89 - z-index: 999;
90 -}
91 -.articleFeedbackv5-bottomrighttablink:hover {
92 - text-decoration: none;
93 -}
94 -
Index: trunk/extensions/ArticleFeedbackv5/modules/ext.articleFeedbackv5/ext.articleFeedbackv5.js
@@ -4,25 +4,8 @@
55 ( function( $ ) {
66
77 /* Load at the bottom of the article */
8 -var $aftDiv = $( '<div id="mw-articlefeedbackv5"></div>' ).articleFeedbackv5();
 8+var $aftDiv = $( '<div id="mw-articlefeedbackv5"></div>' );
99
10 -var closeAftTipsyHtml = '\
11 - <div class="articlefeedbackv5-flyover-header">\
12 - <h3 id="articlefeedbackv5-noteflyover-caption">' + mw.msg( 'articlefeedbackv5-link-close-caption' ) + '</h3>\
13 - <a id="articlefeedbackv5-noteflyover-close" href="#"></a>\
14 - </div>\
15 - <div class="articlefeedbackv5-form-flyover">\
16 - <div>' + mw.msg( 'articlefeedbackv5-link-close-text1' ) + '</div>\
17 - <a href="' + mw.msg( 'articlefeedbackv5-link-close-linkurl' ) + '">' + mw.msg( 'articlefeedbackv5-link-close-linktext' ) + '</a>\
18 - <div>' + mw.msg( 'articlefeedbackv5-link-close-text2' ) + '</div>\
19 - <div>' + mw.msg( 'articlefeedbackv5-link-close-text3' ) + '</div>\
20 - <div class="articlefeedbackv5-flyover-footer">\
21 - <a id="articlefeedbackv5-noteflyover-submit" class="articlefeedbackv5-flyover-button" href="#">CLOSE</a>\
22 - <a id="articlefeedbackv5-noteflyover-cancel" href="#">CANCEL</a>\
23 - <a class="articlefeedbackv5-flyover-help" id="articlefeedbackv5-noteflyover-help" href="#">[?]</a>\
24 - </div>\
25 - </div>';
26 -
2710 // Put on bottom of article before #catlinks (if it exists)
2811 // Except in legacy skins, which have #catlinks above the article but inside content-div.
2912 var legacyskins = [ 'standard', 'cologneblue', 'nostalgia' ];
@@ -33,6 +16,8 @@
3417 mw.util.$content.append( $aftDiv );
3518 }
3619
 20+$aftDiv.articleFeedbackv5();
 21+
3722 /* Add basic edit tracking */
3823 if ( $aftDiv.articleFeedbackv5( 'clickTrackingOn' ) ) {
3924 var clickTrackingSession = $.cookie( 'clicktracking-session' );
@@ -54,212 +39,4 @@
5540 } );
5641 }
5742
58 -/* Setup for feedback links */
59 -
60 -// Click event
61 -var clickFeedbackLink = function ( $link ) {
62 - var tracking_id = $aftDiv.articleFeedbackv5( 'bucketName' ) +
63 - '-trigger' + $link.data( 'linkId' ) +
64 - '-click-overlay';
65 - $aftDiv.articleFeedbackv5( 'trackClick', tracking_id );
66 - $aftDiv.articleFeedbackv5( 'toggleModal', $link );
67 -};
68 -
69 -// Bucketing
70 -var linkBucket = function () {
71 - // Find out which link bucket they go in:
72 - // 1. Display buckets 0 or 5? Always no link.
73 - // 2. Requested in query string (debug only)
74 - // 3. Random bucketing
75 - var displayBucket = $aftDiv.articleFeedbackv5( 'getBucketId' );
76 - if ( '5' == displayBucket || '0' == displayBucket ) {
77 - return '-';
78 - }
79 - var cfg = mw.config.get( 'wgArticleFeedbackv5LinkBuckets' );
80 - if ( !( 'buckets' in cfg ) ) {
81 - return '-';
82 - }
83 - var knownBuckets = cfg.buckets;
84 - var requested = mw.util.getParamValue( 'aftv5_link' );
85 - if ( $aftDiv.articleFeedbackv5( 'inDebug' ) && requested in knownBuckets ) {
86 - return requested;
87 - }
88 - return mw.user.bucket( 'ext.articleFeedbackv5-links', cfg );
89 -}();
90 -if ( $aftDiv.articleFeedbackv5( 'inDebug' ) ) {
91 - aft5_debug( 'Using link option ' + linkBucket );
92 -}
93 -
94 -// A: After the site tagline (below the article title)
95 -if ( 'A' == linkBucket ) {
96 - var $sub = $( '<a href="#mw-articleFeedbackv5" id="articleFeedbackv5-sitesublink"></a>' )
97 - .data( 'linkId', 'A' )
98 - .text( mw.msg( 'articlefeedbackv5-sitesub-linktext' ) )
99 - .click( function ( e ) {
100 - e.preventDefault();
101 - clickFeedbackLink( $( e.target ) );
102 - } )
103 - // The link is going to be at different markup locations on different skins,
104 - // and it needs to show up if the site subhead (e.g., "From Wikipedia, the free
105 - // encyclopedia") is not visible for any reason.
106 - if ( $( '#siteSub' ).filter( ':visible' ).length ) {
107 - $( '#siteSub' ).append( ' ' ).append( $sub );
108 - } else if ( $( 'h1.pagetitle + p.subtitle' ).filter( ':visible' ).length ) {
109 - $( 'h1.pagetitle + p.subtitle' ).append( ' ' ).append( $sub );
110 - } else if ( $( '#mw_contentholder .mw-topboxes' ).length ) {
111 - $( '#mw_contentholder .mw-topboxes' ).after( $sub );
112 - } else if ( $( '#bodyContent' ).length ) {
113 - $( '#bodyContent' ).prepend( $sub );
114 - }
115 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $sub );
116 -}
117 -
118 -// B: Below the titlebar on the right
119 -if ( 'B' == linkBucket ) {
120 - var $tlk = $( '<a href="#mw-articleFeedbackv5" id="articleFeedbackv5-titlebarlink"></a>' )
121 - .data( 'linkId', 'B' )
122 - .text( mw.msg( 'articlefeedbackv5-titlebar-linktext' ) )
123 - .click( function ( e ) {
124 - e.preventDefault();
125 - clickFeedbackLink( $( e.target ) );
126 - } );
127 - if ( $( '#coordinates' ).length ) {
128 - $tlk.css( 'margin-top: 2.5em' );
129 - }
130 - $tlk.insertBefore( $aftDiv );
131 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $tlk );
132 -}
133 -
134 -// C: Button fixed to right side
135 -if ( 'C' == linkBucket ) {
136 - var $fixedTab = $( '\
137 - <div id="articleFeedbackv5-fixedtab" class="articleFeedbackv5-fixedtab">\
138 - <div id="articleFeedbackv5-fixedtabbox" class="articleFeedbackv5-fixedtabbox">\
139 - <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-fixedtablink" class="articleFeedbackv5-fixedtablink"></a>\
140 - </div>\
141 - </div>' );
142 - $fixedTab.find( '#articleFeedbackv5-fixedtablink' )
143 - .data( 'linkId', 'C' )
144 - .attr( 'title', mw.msg( 'articlefeedbackv5-fixedtab-linktext' ) )
145 - .click( function( e ) {
146 - e.preventDefault();
147 - clickFeedbackLink( $( e.target ) );
148 - } );
149 - $fixedTab.insertBefore( $aftDiv );
150 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $fixedTab );
151 -}
152 -
153 -// D: Button fixed to bottom right
154 -if ( 'D' == linkBucket ) {
155 - var $bottomRightTab = $( '\
156 - <div id="articleFeedbackv5-bottomrighttab" class="articleFeedbackv5-bottomrighttab">\
157 - <div id="articleFeedbackv5-bottomrighttabbox" class="articleFeedbackv5-bottomrighttabbox">\
158 - <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-bottomrighttablink" class="articleFeedbackv5-bottomrighttablink"></a>\
159 - </div>\
160 - </div>' );
161 - $bottomRightTab.find( '#articleFeedbackv5-bottomrighttablink' )
162 - .data( 'linkId', 'D' )
163 - .text( mw.msg( 'articlefeedbackv5-bottomrighttab-linktext' ) )
164 - .click( function( e ) {
165 - e.preventDefault();
166 - clickFeedbackLink( $( e.target ) );
167 - } );
168 - $bottomRightTab.insertBefore( $aftDiv );
169 -
170 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $bottomRightTab );
171 -}
172 -
173 -// E: Same as D, with other colors
174 -if ( 'E' == linkBucket ) {
175 - var $bottomRightTab = $( '\
176 - <div id="articleFeedbackv5-bottomrighttab" class="articleFeedbackv5-bottomrighttab">\
177 - <div id="articleFeedbackv5-bottomrighttabbox" class="articleFeedbackv5-bottomrighttabbox">\
178 - <div class="articleFeedbackv5-bottomrighttablink">\
179 - <a href="#mw-articleFeedbackv5" id="articleFeedbackv5-bottomrighttablink"></a>\
180 - <a href="#" id="articleFeedbackv5-bottmrighttabclose" class="articleFeedbackv5-bottomrighttabclose">X</a>\
181 - </div>\
182 - </div>\
183 - </div>' );
184 - $bottomRightTab.find( '#articleFeedbackv5-bottomrighttablink' )
185 - .data( 'linkId', linkBucket )
186 - .text( mw.msg( 'articlefeedbackv5-bottomrighttab-linktext' ) )
187 - .click( function( e ) {
188 - e.preventDefault();
189 - clickFeedbackLink( $( e.target ) );
190 - } );
191 - $bottomRightTab.find( '#articleFeedbackv5-bottmrighttabclose' )
192 - .tipsy( {
193 - delayIn: 0, // delay before showing tooltip (ms)
194 - delayOut: 0, // delay before hiding tooltip (ms)
195 - fade: false, // fade tooltips in/out?
196 - fallback: '', // fallback text to use when no tooltip text
197 - gravity: 'se', // gravity
198 - html: true, // is tooltip content HTML?
199 - live: false, // use live event support?
200 - offset: 10, // pixel offset of tooltip from element
201 - opacity: 1.0, // opacity of tooltip
202 - trigger: 'manual', // how tooltip is triggered - hover | focus | manual
203 - title: function() {
204 - return closeAftTipsyHtml;
205 - }
206 - } );
207 - $bottomRightTab.find( '#articleFeedbackv5-bottmrighttabclose' )
208 - .click( function( e ) {
209 - e.preventDefault();
210 - //dropFeedbackLink( $( e.target ).parents( '#articleFeedbackv5-bottomrighttab' ), linkBucket );
211 - $( e.target ).tipsy( 'show' );
212 - } );
213 - $bottomRightTab.insertBefore( $aftDiv );
214 -
215 - // Setup close tipsy
216 -
217 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $bottomRightTab );
218 -}
219 -
220 -// F: Button fixed to left side
221 -// NOT IMPLEMENTED
222 -
223 -// G: Button below logo
224 -// NOT IMPLEMENTED
225 -
226 -// H: Link on each section bar
227 -if ( 'H' == linkBucket ) {
228 - var $wrp = $( '<span class="articleFeedbackv5-sectionlink-wrap"></span>' )
229 - .html( '&nbsp;[<a href="#mw-articlefeedbackv5" class="articleFeedbackv5-sectionlink"></a>]' );
230 - $wrp.find( 'a.articleFeedbackv5-sectionlink' )
231 - .data( 'linkId', 'H' )
232 - .text( mw.msg( 'articlefeedbackv5-section-linktext' ) )
233 - .click( function ( e ) {
234 - e.preventDefault();
235 - clickFeedbackLink( $( e.target ) );
236 - } );
237 - $( 'span.editsection' ).append( $wrp );
238 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $wrp );
239 -}
240 -
241 -// Add toolbox link
242 -if ( '5' == $aftDiv.articleFeedbackv5( 'getBucketId' ) ) {
243 - var $tbx = $( '<li id="t-articlefeedbackv5"><a href="#mw-articlefeedbackv5"></a></li>' )
244 - .find( 'a' )
245 - .text( mw.msg( 'articlefeedbackv5-bucket5-toolbox-linktext' ) )
246 - .click( function ( e ) {
247 - // Just set the link ID -- this should act just like AFTv4
248 - $aftDiv.articleFeedbackv5( 'setLinkId', 'TBX' );
249 - } )
250 - .end();
251 - $( '#p-tb' ).find( 'ul' ).append( $tbx );
252 -} else {
253 - var $tbx = $( '<li id="t-articlefeedbackv5"><a href="#mw-articlefeedbackv5"></a></li>' )
254 - .find( 'a' )
255 - .text( mw.msg( 'articlefeedbackv5-toolbox-linktext' ) )
256 - .data( 'linkId', 'TBX' )
257 - .click( function ( e ) {
258 - e.preventDefault();
259 - clickFeedbackLink( $( e.target ) );
260 - } )
261 - .end();
262 - $( '#p-tb' ).find( 'ul' ).append( $tbx );
263 - $aftDiv.articleFeedbackv5( 'addToRemovalQueue', $tbx );
264 -}
265 -
26643 } )( jQuery );
Index: trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.hooks.php
@@ -146,14 +146,13 @@
147147 'articlefeedbackv5-transparency-terms',
148148 'articlefeedbackv5-transparency-terms-linktext',
149149 'parentheses',
150 - 'articlefeedbackv5-link-close-caption',
151 - 'articlefeedbackv5-link-close-text1',
152 - 'articlefeedbackv5-link-close-linktext',
153 - 'articlefeedbackv5-link-close-linkurl',
154 - 'articlefeedbackv5-link-close-text2',
155 - 'articlefeedbackv5-link-cllse-text3',
156 - 'articlefeedbackv5-link-close-submit',
157 - 'articlefeedbackv5-link-close-cancel',
 150+ 'articlefeedbackv5-disable-flyover-title',
 151+ 'articlefeedbackv5-disable-flyover-help-goto',
 152+ 'articlefeedbackv5-disable-flyover-help-emphasis-text',
 153+ 'articlefeedbackv5-disable-flyover-help-location',
 154+ 'articlefeedbackv5-disable-flyover-help-direction',
 155+ 'articlefeedbackv5-disable-flyover-prefbutton',
 156+ 'articlefeedbackv5-disable-preference',
158157 ),
159158 'dependencies' => array(
160159 'jquery.appear',

Follow-up revisions

RevisionCommit summaryAuthorDate
r114066r114064: Update keys. Ignored message was deleted.raymond20:53, 17 March 2012
r114328Followup to r114271 and r114064:...rsterbin23:08, 20 March 2012
r114329Followup to r114064 -- fixed scope leakagersterbin23:10, 20 March 2012

Comments

#Comment by Siebrand (talk | contribs)   21:28, 17 March 2012

Seeing the way i18n is handled here, makes me sad.

#Comment by Rsterbin (talk | contribs)   22:53, 17 March 2012

...really? I've read the docs, and I thought I was following them. If what I'm doing here is wrong or not helpful, I'd like to know why and how I can fix it.

#Comment by Catrope (talk | contribs)   19:31, 20 March 2012
+ 'articlefeedbackv5-disable-flyover-help-goto' => 'To remove $1, go to',
+ 'articlefeedbackv5-disable-flyover-help-emphasis-text' => 'Article Feedback',
+ 'articlefeedbackv5-disable-flyover-help-location' => 'My preferences > Appearance',
+ 'articlefeedbackv5-disable-flyover-help-direction' => 'and check',
+ 'articlefeedbackv5-disable-flyover-prefbutton' => 'Go to my preferences',

This is one big pile of Lego. You should have a master message that looks like 'To remove $1, got to $2 and check $3' rather than concatenating things together with the hardcoded assumption that they'll always be in that order in every single one of the 250+ languages we support.

+.tipsy-arrow {
/* @embed */
background-image: url(images/tipsy-flyover.png);
width: 23px;
height: 11px;
+}
+.tipsy-nw .tipsy-arrow {
+ margin-top: -6px;
+}
+.tipsy-se .tipsy-arrow {
margin-top: -11px;
}

The CSS rules for Tipsy here should be namespaced (made more specific) so they only apply to Tipsy tooltips created by AFTv5, not to any other Tipsy tooltips that might appear on the page.

+ var re = new RegExp("\\$" + i);
+ full = full.replace( re, mw.html.element(

The replace function takes a string too, so you can do full.replace( '$' + i, ... ) and that's equivalent to this code. That will only replace the first occurrence though; if you care about replacing multiple occurrences of the same parameter, use the g modifier in your regex: re = new RegExp("\\$" + i, 'g');.

However, this still suffers from a potential bug where $1 expands to something containing the literal string "$2", which is then expanded again, and it's also buggy if $10 is used (because that'll get expanded as $1 followed by a literal 0). If you're paranoid enough to want to fix that (or just like cleaner code), you can use a callback with replace():

full.replace( /\$(\d+)/g, function( str, number ) {
    var i = parseInt( number, 10 );
    return whatTheReplacementShouldBeFor( i );
} );
+ hasTipsy = false;

AFAICT this variable is leaked to the global scope.

#Comment by Rsterbin (talk | contribs)   21:06, 20 March 2012

Annoyingly enough, your suggestion was what I did first, before I noticed that the mockups called for line breaks. I would LOVE to put it back the way you suggest, but Fabrice needs to sign off on not having the line breaks he wanted.

I'll fix the other stuff soon.

#Comment by Rsterbin (talk | contribs)   00:00, 21 March 2012

Fixed in followups; marking back to new.

Status & tagging log