Index: branches/RL2/extensions/Gadgets/SpecialGadgetManager.php |
— | — | @@ -1,176 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * SpecialPage for Gadget manager |
5 | | - * |
6 | | - * @file |
7 | | - * @ingroup Extensions |
8 | | - */ |
9 | | - |
10 | | -class SpecialGadgetManager extends SpecialPage { |
11 | | - |
12 | | - public function __construct() { |
13 | | - parent::__construct( 'GadgetManager' ); |
14 | | - } |
15 | | - |
16 | | - /** |
17 | | - * @param $par String: Optionally the id of the gadget to show info for. |
18 | | - */ |
19 | | - public function execute( $par ) { |
20 | | - $out = $this->getOutput(); |
21 | | - |
22 | | - $this->setHeaders(); |
23 | | - $out->setPagetitle( wfMsg( 'gadgetmanager-title' ) ); |
24 | | - $out->addModuleStyles( 'ext.gadgets.gadgetmanager.prejs' ); |
25 | | - |
26 | | - // Only load ajax editor if user is allowed to edit |
27 | | - if ( $this->getUser()->isAllowed( 'gadgets-definition-edit' ) ) { |
28 | | - $out->addModules( 'ext.gadgets.gadgetmanager.ui' ); |
29 | | - } |
30 | | - |
31 | | - // Determine view |
32 | | - if ( is_string( $par ) && $par !== '' ) { |
33 | | - $html = $this->generateGadgetView( $par ); |
34 | | - } else { |
35 | | - $html = $this->generateOverview(); |
36 | | - } |
37 | | - |
38 | | - $out->addHtml( $html ); |
39 | | - } |
40 | | - |
41 | | - /** |
42 | | - * @return String: HTML |
43 | | - */ |
44 | | - private function generateOverview() { |
45 | | - global $wgGadgetEnableSharing; |
46 | | - |
47 | | - $repo = LocalGadgetRepo::singleton(); |
48 | | - $gadgetsByCategory = $repo->getGadgetsByCategory(); |
49 | | - |
50 | | - // If there there are no gadgets at all, exit early. |
51 | | - if ( !count( $gadgetsByCategory ) ) { |
52 | | - $noGadgetsMsgHtml = Html::element( 'p', |
53 | | - array( |
54 | | - 'class' => 'mw-gadgetmanager-nogadgets' |
55 | | - ), wfMessage( 'gadgetmanager-nogadgets' )->plain() |
56 | | - ); |
57 | | - $this->getOutput()->addHtml( $noGadgetsMsgHtml ); |
58 | | - return; |
59 | | - } |
60 | | - // There is atleast one gadget, let's get started. |
61 | | - $this->getOutput()->addWikiMsg( 'gadgetmanager-pagetext', SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL('namespace=' . NS_GADGET_DEFINITION ) ); |
62 | | - $html = ''; |
63 | | - |
64 | | - // Sort categories alphabetically |
65 | | - // @todo Sort causes the key "''" to be at the top, it should be on the bottom. |
66 | | - ksort( $gadgetsByCategory ); |
67 | | - |
68 | | - foreach ( $gadgetsByCategory as $category => $gadgets ) { |
69 | | - // Avoid broken or empty headings. Fallback to a special message |
70 | | - // for uncategorized gadgets (e.g. gadgets with category '' ). |
71 | | - if ( $category !== '' ) { |
72 | | - $categoryTitle = $repo->getCategoryTitle( $category ); |
73 | | - } else { |
74 | | - $categoryTitle = wfMessage( 'gadgetmanager-uncategorized' )->plain(); |
75 | | - } |
76 | | - |
77 | | - // Category header |
78 | | - $html .= Html::element( 'h2', |
79 | | - array( 'class' => 'mw-gadgetmanager-category' ), |
80 | | - $categoryTitle |
81 | | - ); |
82 | | - |
83 | | - // Start per-category gadgets table |
84 | | - $html .= '<table class="mw-gadgetmanager-gadgets mw-datatable sortable"><thead><tr>'; |
85 | | - $html .= |
86 | | - '<th>' . wfMessage( 'gadgetmanager-tablehead-title' )->escaped() |
87 | | - . '</th><th>' . wfMessage( 'gadgetmanager-tablehead-default' )->escaped() |
88 | | - . '</th><th>' . wfMessage( 'gadgetmanager-tablehead-hidden' )->escaped() |
89 | | - . '</th>'; |
90 | | - if ( $wgGadgetEnableSharing ) { |
91 | | - $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-shared' )->escaped() . '</th>'; |
92 | | - } |
93 | | - $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th>'; |
94 | | - $html .= '</tr></thead><tbody>'; |
95 | | - |
96 | | - // Populate table rows for the current category |
97 | | - foreach ( $gadgets as $gadgetId => $gadget ) { |
98 | | - $html .= '<tr>'; |
99 | | - |
100 | | - $tickedCheckboxHtml = Html::element( 'input', array( |
101 | | - 'type' => 'checkbox', |
102 | | - 'disabled' => 'disabled', |
103 | | - 'value' => 1, |
104 | | - 'checked' => 'checked', |
105 | | - ) ); |
106 | | - |
107 | | - // Title |
108 | | - $titleLink = Linker::link( |
109 | | - $this->getTitle( $gadget->getId() ), |
110 | | - $gadget->getTitleMessage(), |
111 | | - array( 'data-gadget-id' => $gadget->getId() ) |
112 | | - ); |
113 | | - $html .= "<td class=\"mw-gadgetmanager-gadgets-title\">$titleLink</td>"; |
114 | | - // Default |
115 | | - $html .= '<td class="mw-gadgetmanager-gadgets-default">' |
116 | | - . ( $gadget->isEnabledByDefault() ? $tickedCheckboxHtml : '' ) . '</td>'; |
117 | | - // Hidden |
118 | | - $html .= '<td class="mw-gadgetmanager-gadgets-hidden">' |
119 | | - . ( $gadget->isHidden() ? $tickedCheckboxHtml : '' ) . '</td>'; |
120 | | - // Shared |
121 | | - if ( $wgGadgetEnableSharing ) { |
122 | | - $html .= '<td class="mw-gadgetmanager-gadgets-shared">' |
123 | | - . ( $gadget->isShared() ? $tickedCheckboxHtml : '' ) . '</td>'; |
124 | | - } |
125 | | - |
126 | | - // Last modified |
127 | | - $lastModText = ''; |
128 | | - $definitionTitle = Title::makeTitleSafe( NS_GADGET_DEFINITION, $gadget->getId() . '.js' ); |
129 | | - if ( $definitionTitle ) { |
130 | | - $definitionRev = Revision::newFromTitle( $definitionTitle ); |
131 | | - if ( $definitionRev ) { |
132 | | - $userLang = $this->getLang(); |
133 | | - $revTimestamp = $definitionRev->getTimestamp(); |
134 | | - $userText = $definitionRev->getUserText(); |
135 | | - $userLinks = |
136 | | - Linker::userLink( |
137 | | - $definitionRev->getUser(), |
138 | | - $userText |
139 | | - ) . |
140 | | - Linker::userToolLinks( |
141 | | - $definitionRev->getUser(), |
142 | | - $userText |
143 | | - ); |
144 | | - $lastModText = wfMsgExt( |
145 | | - 'gadgetmanager-tablecell-lastmod', |
146 | | - array( 'replaceafter', 'parseinline' ), |
147 | | - array( |
148 | | - $userLang->timeanddate( $revTimestamp, true ), |
149 | | - $userLinks, |
150 | | - $userLang->date( $revTimestamp, true ), |
151 | | - $userLang->time( $revTimestamp, true ), |
152 | | - $userText |
153 | | - ) |
154 | | - ); |
155 | | - } |
156 | | - $html .= "<td class=\"mw-gadgetmanager-gadgets-lastmod\">$lastModText</td>"; |
157 | | - } |
158 | | - |
159 | | - $html .= '</tr>'; |
160 | | - } |
161 | | - |
162 | | - // End of per-category gadgets table |
163 | | - $html .= '</tbody></table>'; |
164 | | - } |
165 | | - |
166 | | - return $html; |
167 | | - } |
168 | | - |
169 | | - /** |
170 | | - * @return String: HTML |
171 | | - */ |
172 | | - public function generateGadgetView( $gadgetId ) { |
173 | | - return 'TODO - This page is about "' |
174 | | - . htmlspecialchars( $gadgetId ) |
175 | | - . '". Also used as permalink from other places.'; |
176 | | - } |
177 | | -} |
Index: branches/RL2/extensions/Gadgets/Gadgets.i18n.php |
— | — | @@ -29,11 +29,12 @@ |
30 | 30 | 'gadgets-preference-description' => '$1: $2', |
31 | 31 | 'gadgets-sharedprefstext' => 'Below is a list of gadgets from other wikis. TODO: This needs more text', |
32 | 32 | |
33 | | - # For Special:Gadgets (overview for users; titles, messages, description, exporting etc.) |
| 33 | + # For Special:Gadgets |
34 | 34 | 'gadgets' => 'Gadgets', |
35 | 35 | 'gadgets-title' => 'Gadgets', |
36 | 36 | 'gadgets-pagetext' => "Below is a list of gadgets available on this wiki. Users can enable or disable these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]]. |
37 | | -This overview provides easy access to the system message pages that define each gadget's description and title.", |
| 37 | +This overview provides easy access to the system message pages that define each gadget's description and title. Welcome to the gadget management interface. Below is an overview of all the configurable options for this gadget. defined on this wiki. Users can opt in or opt out of these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]]. All modifications to gadget definitions can be followed in the [$1 recent changes]", |
| 38 | + 'gadgets-nogadgets' => 'This wiki currently has no gadgets defined.', |
38 | 39 | 'gadgets-uses' => 'Uses', |
39 | 40 | 'gadgets-required-rights' => 'Requires the {{PLURAL:$2|$1 right|following rights: $1}}.', |
40 | 41 | 'gadgets-default' => 'Enabled for everyone by default.', |
— | — | @@ -44,16 +45,9 @@ |
45 | 46 | go to Special:Import on destination wiki and upload it. You must have appropriate permissions on the destination wiki (including the right to edit in the {{ns:Gadget}} and {{ns:Gadget definition}} namespaces) and the import from file uploads must be enabled.', |
46 | 47 | 'gadgets-export-download' => 'Download', |
47 | 48 | |
48 | | - # For Special:GadgetManager (for gadget definition management) |
49 | | - 'gadgetmanager' => 'Gadget manager', |
| 49 | + # For the ext.gadgets.gadgetmanager module |
50 | 50 | 'gadgetmanager-title' => 'Gadget management', |
51 | | - 'gadgetmanager-pagetext' => 'Welcome to the gadget management interface. Below is an overview of all gadgets defined on this wiki. Users can opt in or opt out of these through their [[Special:Preferences#mw-prefsection-gadgets|preferences page]]. All modifications to gadget definitions can be followed in the [$1 recent changes].', |
52 | | - 'gadgetmanager-nogadgets' => 'This wiki currently has no gadgets defined.', |
53 | 51 | 'gadgetmanager-uncategorized' => 'Uncategorized', |
54 | | - 'gadgetmanager-tablehead-title' => 'Gadget title', |
55 | | - 'gadgetmanager-tablehead-default' => 'Default', |
56 | | - 'gadgetmanager-tablehead-hidden' => 'Hidden', |
57 | | - 'gadgetmanager-tablehead-shared' => 'Shared', |
58 | 52 | 'gadgetmanager-tablehead-lastmod' => 'Last modified', |
59 | 53 | 'gadgetmanager-tablecell-lastmod' => '$1 by $2', |
60 | 54 | 'gadgetmanager-editor-title' => 'Editing $1:', |
— | — | @@ -68,7 +62,7 @@ |
69 | 63 | 'gadgetmanager-prop-messages' => 'Messages', |
70 | 64 | 'gadgetmanager-prop-category' => 'Category', |
71 | 65 | 'gadgetmanager-prop-rights' => 'Required user rights', |
72 | | - 'gadgetmanager-prop-default' => 'Enable by default', |
| 66 | + 'gadgetmanager-prop-default' => 'Enable for everyone by default', |
73 | 67 | 'gadgetmanager-prop-hidden' => 'Hide gadget', |
74 | 68 | 'gadgetmanager-prop-shared' => 'Share gadget', |
75 | 69 | 'gadgetmanager-prop-default-yes' => 'This gadget is loaded by default.', |
Index: branches/RL2/extensions/Gadgets/Gadgets.php |
— | — | @@ -125,10 +125,10 @@ |
126 | 126 | $wgAutoloadClasses['SpecialGadgetManager'] = $dir . 'SpecialGadgetManager.php'; |
127 | 127 | $wgAutoloadClasses['SpecialGadgets'] = $dir . 'SpecialGadgets.php'; |
128 | 128 | |
129 | | -#$wgSpecialPages['Gadgets'] = 'SpecialGadgets'; |
130 | | -#$wgSpecialPageGroups['Gadgets'] = 'wiki'; |
131 | | -$wgSpecialPages['GadgetManager'] = 'SpecialGadgetManager'; |
132 | | -$wgSpecialPageGroups['GadgetManager'] = 'wiki'; |
| 129 | +$wgSpecialPages['Gadgets'] = 'SpecialGadgets'; |
| 130 | +$wgSpecialPageGroups['Gadgets'] = 'wiki'; |
| 131 | +#$wgSpecialPages['GadgetManager'] = 'SpecialGadgetManager'; |
| 132 | +#$wgSpecialPageGroups['GadgetManager'] = 'wiki'; |
133 | 133 | |
134 | 134 | $wgAPIListModules['gadgetcategories'] = 'ApiQueryGadgetCategories'; |
135 | 135 | $wgAPIListModules['gadgets'] = 'ApiQueryGadgets'; |
— | — | @@ -140,8 +140,8 @@ |
141 | 141 | ); |
142 | 142 | $wgResourceModules += array( |
143 | 143 | // Also loaded in if javascript disabled |
144 | | - 'ext.gadgets.gadgetmanager.prejs' => $gadResourceTemplate + array( |
145 | | - 'styles' => 'ext.gadgets.gadgetmanager.prejs.css', |
| 144 | + 'ext.gadgets.prejs' => $gadResourceTemplate + array( |
| 145 | + 'styles' => 'ext.gadgets.prejs.css', |
146 | 146 | 'position' => 'top', |
147 | 147 | ), |
148 | 148 | // Method to interact with API |
— | — | @@ -153,14 +153,11 @@ |
154 | 154 | // jQuery plugin |
155 | 155 | 'jquery.createPropCloud' => $gadResourceTemplate + array( |
156 | 156 | 'scripts' => 'jquery.createPropCloud.js', |
157 | | - 'messages' => array( |
158 | | - 'gadgetmanager-editor-prop-remove', |
159 | | - ), |
160 | 157 | ), |
161 | 158 | // Event handling, UI components, initiates on document ready |
162 | | - 'ext.gadgets.gadgetmanager.ui' => $gadResourceTemplate + array( |
163 | | - 'scripts' => 'ext.gadgets.gadgetmanager.ui.js', |
164 | | - 'styles' => 'ext.gadgets.gadgetmanager.ui.css', |
| 159 | + 'ext.gadgets.gadgetmanager' => $gadResourceTemplate + array( |
| 160 | + 'scripts' => 'ext.gadgets.gadgetmanager.js', |
| 161 | + 'styles' => 'ext.gadgets.gadgetmanager.css', |
165 | 162 | 'dependencies' => array( |
166 | 163 | 'ext.gadgets.api', |
167 | 164 | 'jquery.localize', |
— | — | @@ -172,6 +169,7 @@ |
173 | 170 | ), |
174 | 171 | 'messages' => array( |
175 | 172 | 'gadgetmanager-editor-title', |
| 173 | + 'gadgetmanager-editor-prop-remove', |
176 | 174 | 'gadgetmanager-editor-removeprop-tooltip', |
177 | 175 | 'gadgetmanager-editor-save', |
178 | 176 | 'gadgetmanager-editor-cancel', |
Index: branches/RL2/extensions/Gadgets/SpecialGadgets.php |
— | — | @@ -1,168 +1,176 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | | - * Special:Gadgets, provides a preview of MediaWiki:Gadgets. |
| 4 | + * SpecialPage for Gadget manager |
5 | 5 | * |
6 | 6 | * @file |
7 | | - * @ingroup SpecialPage |
8 | | - * @author Daniel Kinzler, brightbyte.de |
9 | | - * @copyright © 2007 Daniel Kinzler |
10 | | - * @license GNU General Public License 2.0 or later |
| 7 | + * @ingroup Extensions |
11 | 8 | */ |
12 | 9 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
14 | | - echo( "not a valid entry point.\n" ); |
15 | | - die( 1 ); |
16 | | -} |
| 10 | +class SpecialGadgetManager extends SpecialPage { |
17 | 11 | |
18 | | -/** |
19 | | - * |
20 | | - */ |
21 | | -class SpecialGadgets extends SpecialPage { |
| 12 | + public function __construct() { |
| 13 | + parent::__construct( 'GadgetManager' ); |
| 14 | + } |
22 | 15 | |
23 | 16 | /** |
24 | | - * Constructor |
| 17 | + * @param $par String: Optionally the id of the gadget to show info for. |
25 | 18 | */ |
26 | | - function __construct() { |
27 | | - parent::__construct( 'Gadgets', '', true ); |
28 | | - } |
| 19 | + public function execute( $par ) { |
| 20 | + $out = $this->getOutput(); |
29 | 21 | |
30 | | - /** |
31 | | - * Main execution function |
32 | | - * @param $par Parameters passed to the page |
33 | | - */ |
34 | | - function execute( $par ) { |
35 | | - $parts = explode( '/', $par ); |
36 | | - if ( count( $parts ) == 2 && $parts[0] == 'export' ) { |
37 | | - $this->showExportForm( $parts[1] ); |
| 22 | + $this->setHeaders(); |
| 23 | + $out->setPagetitle( wfMsg( 'gadgetmanager-title' ) ); |
| 24 | + $out->addModuleStyles( 'ext.gadgets.gadgetmanager.prejs' ); |
| 25 | + |
| 26 | + // Only load ajax editor if user is allowed to edit |
| 27 | + if ( $this->getUser()->isAllowed( 'gadgets-definition-edit' ) ) { |
| 28 | + $out->addModules( 'ext.gadgets.gadgetmanager.ui' ); |
| 29 | + } |
| 30 | + |
| 31 | + // Determine view |
| 32 | + if ( is_string( $par ) && $par !== '' ) { |
| 33 | + $html = $this->generateGadgetView( $par ); |
38 | 34 | } else { |
39 | | - $this->showMainForm(); |
| 35 | + $html = $this->generateOverview(); |
40 | 36 | } |
| 37 | + |
| 38 | + $out->addHtml( $html ); |
41 | 39 | } |
42 | | - |
| 40 | + |
43 | 41 | /** |
44 | | - * Displays form showing the list of installed gadgets |
| 42 | + * @return String: HTML |
45 | 43 | */ |
46 | | - public function showMainForm() { |
47 | | - global $wgOut, $wgUser, $wgLang, $wgContLang; |
| 44 | + private function generateOverview() { |
| 45 | + global $wgGadgetEnableSharing; |
48 | 46 | |
49 | | - $skin = $wgUser->getSkin(); |
| 47 | + $repo = LocalGadgetRepo::singleton(); |
| 48 | + $gadgetsByCategory = $repo->getGadgetsByCategory(); |
50 | 49 | |
51 | | - $this->setHeaders(); |
52 | | - $wgOut->setPagetitle( wfMsg( "gadgets-title" ) ); |
53 | | - $wgOut->addWikiMsg( 'gadgets-pagetext' ); |
54 | | - |
55 | | - $gadgets = Gadget::loadStructuredList(); |
56 | | - if ( !$gadgets ) return; |
57 | | - |
58 | | - $lang = ""; |
59 | | - if ( $wgLang->getCode() != $wgContLang->getCode() ) { |
60 | | - $lang = "/" . $wgLang->getCode(); |
| 50 | + // If there there are no gadgets at all, exit early. |
| 51 | + if ( !count( $gadgetsByCategory ) ) { |
| 52 | + $noGadgetsMsgHtml = Html::element( 'p', |
| 53 | + array( |
| 54 | + 'class' => 'mw-gadgetmanager-nogadgets' |
| 55 | + ), wfMessage( 'gadgetmanager-nogadgets' )->plain() |
| 56 | + ); |
| 57 | + $this->getOutput()->addHtml( $noGadgetsMsgHtml ); |
| 58 | + return; |
61 | 59 | } |
| 60 | + // There is atleast one gadget, let's get started. |
| 61 | + $this->getOutput()->addWikiMsg( 'gadgetmanager-pagetext', SpecialPage::getTitleFor( 'Recentchanges' )->getFullURL('namespace=' . NS_GADGET_DEFINITION ) ); |
| 62 | + $html = ''; |
| 63 | + |
| 64 | + // Sort categories alphabetically |
| 65 | + // @todo Sort causes the key "''" to be at the top, it should be on the bottom. |
| 66 | + ksort( $gadgetsByCategory ); |
62 | 67 | |
63 | | - $listOpen = false; |
| 68 | + foreach ( $gadgetsByCategory as $category => $gadgets ) { |
| 69 | + // Avoid broken or empty headings. Fallback to a special message |
| 70 | + // for uncategorized gadgets (e.g. gadgets with category '' ). |
| 71 | + if ( $category !== '' ) { |
| 72 | + $categoryTitle = $repo->getCategoryTitle( $category ); |
| 73 | + } else { |
| 74 | + $categoryTitle = wfMessage( 'gadgetmanager-uncategorized' )->plain(); |
| 75 | + } |
64 | 76 | |
65 | | - $msgOpt = array( 'parseinline', 'parsemag' ); |
66 | | - $editInterfaceAllowed = $wgUser->isAllowed( 'editinterface' ); |
67 | | - |
68 | | - foreach ( $gadgets as $section => $entries ) { |
69 | | - if ( $section !== false && $section !== '' ) { |
70 | | - $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-section-$section$lang" ); |
71 | | - if ( $editInterfaceAllowed ) { |
72 | | - $lnkTarget = $t |
73 | | - ? $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) ) |
74 | | - : htmlspecialchars( $section ); |
75 | | - $lnk = "    [$lnkTarget]"; |
76 | | - } else { |
77 | | - $lnk = ''; |
78 | | - } |
79 | | - $ttext = wfMsgExt( "gadget-section-$section", $msgOpt ); |
| 77 | + // Category header |
| 78 | + $html .= Html::element( 'h2', |
| 79 | + array( 'class' => 'mw-gadgetmanager-category' ), |
| 80 | + $categoryTitle |
| 81 | + ); |
80 | 82 | |
81 | | - if( $listOpen ) { |
82 | | - $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" ); |
83 | | - $listOpen = false; |
84 | | - } |
85 | | - $wgOut->addHTML( Html::rawElement( 'h2', array(), $ttext . $lnk ) . "\n" ); |
| 83 | + // Start per-category gadgets table |
| 84 | + $html .= '<table class="mw-gadgetmanager-gadgets mw-datatable sortable"><thead><tr>'; |
| 85 | + $html .= |
| 86 | + '<th>' . wfMessage( 'gadgetmanager-tablehead-title' )->escaped() |
| 87 | + . '</th><th>' . wfMessage( 'gadgetmanager-tablehead-default' )->escaped() |
| 88 | + . '</th><th>' . wfMessage( 'gadgetmanager-tablehead-hidden' )->escaped() |
| 89 | + . '</th>'; |
| 90 | + if ( $wgGadgetEnableSharing ) { |
| 91 | + $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-shared' )->escaped() . '</th>'; |
86 | 92 | } |
| 93 | + $html .= '<th>' . wfMessage( 'gadgetmanager-tablehead-lastmod' )->escaped() . '</th>'; |
| 94 | + $html .= '</tr></thead><tbody>'; |
87 | 95 | |
88 | | - foreach ( $entries as $gadget ) { |
89 | | - $t = Title::makeTitleSafe( NS_MEDIAWIKI, "Gadget-{$gadget->getId()}$lang" ); |
90 | | - if ( !$t ) continue; |
| 96 | + // Populate table rows for the current category |
| 97 | + foreach ( $gadgets as $gadgetId => $gadget ) { |
| 98 | + $html .= '<tr>'; |
91 | 99 | |
92 | | - $links = array(); |
93 | | - if ( $editInterfaceAllowed ) { |
94 | | - $links[] = $skin->link( $t, wfMsgHTML( 'edit' ), array(), array( 'action' => 'edit' ) ); |
| 100 | + $tickedCheckboxHtml = Html::element( 'input', array( |
| 101 | + 'type' => 'checkbox', |
| 102 | + 'disabled' => 'disabled', |
| 103 | + 'value' => 1, |
| 104 | + 'checked' => 'checked', |
| 105 | + ) ); |
| 106 | + |
| 107 | + // Title |
| 108 | + $titleLink = Linker::link( |
| 109 | + $this->getTitle( $gadget->getId() ), |
| 110 | + $gadget->getTitleMessage(), |
| 111 | + array( 'data-gadget-id' => $gadget->getId() ) |
| 112 | + ); |
| 113 | + $html .= "<td class=\"mw-gadgetmanager-gadgets-title\">$titleLink</td>"; |
| 114 | + // Default |
| 115 | + $html .= '<td class="mw-gadgetmanager-gadgets-default">' |
| 116 | + . ( $gadget->isEnabledByDefault() ? $tickedCheckboxHtml : '' ) . '</td>'; |
| 117 | + // Hidden |
| 118 | + $html .= '<td class="mw-gadgetmanager-gadgets-hidden">' |
| 119 | + . ( $gadget->isHidden() ? $tickedCheckboxHtml : '' ) . '</td>'; |
| 120 | + // Shared |
| 121 | + if ( $wgGadgetEnableSharing ) { |
| 122 | + $html .= '<td class="mw-gadgetmanager-gadgets-shared">' |
| 123 | + . ( $gadget->isShared() ? $tickedCheckboxHtml : '' ) . '</td>'; |
95 | 124 | } |
96 | | - $links[] = $skin->link( $this->getTitle( "export/{$gadget->getId()}" ), wfMsgHtml( 'gadgets-export' ) ); |
97 | | - |
98 | | - $ttext = wfMsgExt( "gadget-{$gadget->getId()}", $msgOpt ); |
99 | 125 | |
100 | | - if( !$listOpen ) { |
101 | | - $listOpen = true; |
102 | | - $wgOut->addHTML( Xml::openElement( 'ul' ) ); |
| 126 | + // Last modified |
| 127 | + $lastModText = ''; |
| 128 | + $definitionTitle = Title::makeTitleSafe( NS_GADGET_DEFINITION, $gadget->getId() . '.js' ); |
| 129 | + if ( $definitionTitle ) { |
| 130 | + $definitionRev = Revision::newFromTitle( $definitionTitle ); |
| 131 | + if ( $definitionRev ) { |
| 132 | + $userLang = $this->getLang(); |
| 133 | + $revTimestamp = $definitionRev->getTimestamp(); |
| 134 | + $userText = $definitionRev->getUserText(); |
| 135 | + $userLinks = |
| 136 | + Linker::userLink( |
| 137 | + $definitionRev->getUser(), |
| 138 | + $userText |
| 139 | + ) . |
| 140 | + Linker::userToolLinks( |
| 141 | + $definitionRev->getUser(), |
| 142 | + $userText |
| 143 | + ); |
| 144 | + $lastModText = wfMsgExt( |
| 145 | + 'gadgetmanager-tablecell-lastmod', |
| 146 | + array( 'replaceafter', 'parseinline' ), |
| 147 | + array( |
| 148 | + $userLang->timeanddate( $revTimestamp, true ), |
| 149 | + $userLinks, |
| 150 | + $userLang->date( $revTimestamp, true ), |
| 151 | + $userLang->time( $revTimestamp, true ), |
| 152 | + $userText |
| 153 | + ) |
| 154 | + ); |
| 155 | + } |
| 156 | + $html .= "<td class=\"mw-gadgetmanager-gadgets-lastmod\">$lastModText</td>"; |
103 | 157 | } |
104 | | - $lnk = '  ' . wfMsg( 'parentheses', $wgLang->pipeList( $links ) ); |
105 | | - $wgOut->addHTML( Xml::openElement( 'li' ) . |
106 | | - $ttext . $lnk . "<br />" . |
107 | | - wfMsgHTML( 'gadgets-uses' ) . wfMsg( 'colon-separator' ) |
108 | | - ); |
109 | 158 | |
110 | | - $lnk = array(); |
111 | | - foreach ( $gadget->getScriptsAndStyles() as $codePage ) { |
112 | | - $t = Title::makeTitleSafe( NS_MEDIAWIKI, $codePage ); |
113 | | - if ( !$t ) continue; |
| 159 | + $html .= '</tr>'; |
| 160 | + } |
114 | 161 | |
115 | | - $lnk[] = $skin->link( $t, htmlspecialchars( $t->getText() ) ); |
116 | | - } |
117 | | - $wgOut->addHTML( $wgLang->commaList( $lnk ) ); |
118 | | - $rights = $gadget->getRequiredRights(); |
119 | | - if ( count( $rights ) ) { |
120 | | - $wgOut->addHTML( '<br />' . |
121 | | - wfMessage( 'gadgets-required-rights', $wgLang->commaList( $rights ), count( $rights ) )->parse() |
122 | | - ); |
123 | | - } |
124 | | - if ( $gadget->isOnByDefault() ) { |
125 | | - $wgOut->addHTML( '<br />' . wfMessage( 'gadgets-default' )->parse() ); |
126 | | - } |
127 | | - |
128 | | - $wgOut->addHTML( Xml::closeElement( 'li' ) . "\n" ); |
129 | | - } |
| 162 | + // End of per-category gadgets table |
| 163 | + $html .= '</tbody></table>'; |
130 | 164 | } |
131 | 165 | |
132 | | - if( $listOpen ) { |
133 | | - $wgOut->addHTML( Xml::closeElement( 'ul' ) . "\n" ); |
134 | | - } |
| 166 | + return $html; |
135 | 167 | } |
136 | 168 | |
137 | 169 | /** |
138 | | - * Exports a gadget with its dependencies in a serialized form |
139 | | - * @param $gadget String Name of gadget to export |
| 170 | + * @return String: HTML |
140 | 171 | */ |
141 | | - public function showExportForm( $gadget ) { |
142 | | - global $wgOut, $wgScript; |
143 | | - |
144 | | - $gadgets = Gadget::loadList(); |
145 | | - if ( !isset( $gadgets[$gadget] ) ) { |
146 | | - $wgOut->showErrorPage( 'error', 'gadgets-not-found', array( $gadget ) ); |
147 | | - return; |
148 | | - } |
149 | | - |
150 | | - $g = $gadgets[$gadget]; |
151 | | - $this->setHeaders(); |
152 | | - $wgOut->setPagetitle( wfMsg( "gadgets-export-title" ) ); |
153 | | - $wgOut->addWikiMsg( 'gadgets-export-text', $gadget, $g->getDefinition() ); |
154 | | - |
155 | | - $exportList = "MediaWiki:gadget-$gadget\n"; |
156 | | - foreach ( $g->getScriptsAndStyles() as $page ) { |
157 | | - $exportList .= "MediaWiki:$page\n"; |
158 | | - } |
159 | | - |
160 | | - $wgOut->addHTML( Html::openElement( 'form', array( 'method' => 'get', 'action' => $wgScript ) ) |
161 | | - . Html::hidden( 'title', SpecialPage::getTitleFor( 'Export' )->getPrefixedDBKey() ) |
162 | | - . Html::hidden( 'pages', $exportList ) |
163 | | - . Html::hidden( 'wpDownload', '1' ) |
164 | | - . Html::hidden( 'templates', '1' ) |
165 | | - . Xml::submitButton( wfMsg( 'gadgets-export-download' ) ) |
166 | | - . Html::closeElement( 'form' ) |
167 | | - ); |
| 172 | + public function generateGadgetView( $gadgetId ) { |
| 173 | + return 'TODO - This page is about "' |
| 174 | + . htmlspecialchars( $gadgetId ) |
| 175 | + . '". Also used as permalink from other places.'; |
168 | 176 | } |
169 | 177 | } |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.css |
— | — | @@ -1,67 +0,0 @@ |
2 | | -/** |
3 | | - * Styling for the gadget manager javascript-generated user interface. |
4 | | - */ |
5 | | - |
6 | | -/** |
7 | | - * Form |
8 | | - */ |
9 | | -.mw-gadgetmanager-form fieldset { |
10 | | - margin: 0; |
11 | | -} |
12 | | - |
13 | | -.mw-gadgetmanager-form table { |
14 | | - width: 100%; |
15 | | -} |
16 | | - |
17 | | -.mw-gadgetmanager-form td, |
18 | | -.mw-gadgetmanager-form th { |
19 | | - vertical-align: top; |
20 | | -} |
21 | | - |
22 | | -/** |
23 | | - * The PropCloud |
24 | | - */ |
25 | | -.mw-gadgetmanager-propcloud { |
26 | | - background: white; |
27 | | - border: 1px solid grey; |
28 | | - overflow: hidden; |
29 | | -} |
30 | | - |
31 | | -.mw-gadgetmanager-propcontainer {} |
32 | | - |
33 | | -.mw-gadgetmanager-prop { |
34 | | - float: left; |
35 | | - margin: 2px 5px 5px 2px; |
36 | | - padding: 2px 5px; |
37 | | - background: #e5eff6; |
38 | | - border: 1px solid #a4d2fb; |
39 | | - border-radius: 10px; |
40 | | - line-height: 1; |
41 | | -} |
42 | | - |
43 | | -.mw-gadgetmanager-prop-label {} |
44 | | - |
45 | | -.mw-gadgetmanager-prop-delete { |
46 | | - display: inline-block; |
47 | | - width: 10px; |
48 | | - height: 10px; |
49 | | - /* @embed */ |
50 | | - background: url(images/close.png) 50% 50% no-repeat; |
51 | | - opacity: 0.4; |
52 | | -} |
53 | | - |
54 | | -.mw-gadgetmanager-prop:hover .mw-gadgetmanager-prop-delete { |
55 | | - opacity: 0.7; |
56 | | -} |
57 | | - |
58 | | -.mw-gadgetmanager-prop:hover .mw-gadgetmanager-prop-delete:hover { |
59 | | - opacity: 1; |
60 | | - cursor: pointer; |
61 | | -} |
62 | | - |
63 | | -.mw-gadgetmanager-propinput, |
64 | | -.mw-gadgetmanager-propinput:focus { |
65 | | - border: 0; |
66 | | - outline: 0; |
67 | | - background: transparent; |
68 | | -} |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.ui.js |
— | — | @@ -1,405 +0,0 @@ |
2 | | -/** |
3 | | - * JavaScript to initialize the UI of the gadget manager. |
4 | | - * |
5 | | - * @author Timo Tijhof |
6 | | - * @copyright © 2011 Timo Tijhof |
7 | | - * @license GNU General Public Licence 2.0 or later |
8 | | - */ |
9 | | -( function( $ ) { |
10 | | - |
11 | | - var |
12 | | - /** |
13 | | - * @var {Object} Local alias to mw.gadgets |
14 | | - */ |
15 | | - ga = mw.gadgets, |
16 | | - /** |
17 | | - * @var {Object} HTML fragements |
18 | | - */ |
19 | | - tpl = { |
20 | | - fancyForm: '<form class="mw-gadgetmanager-form">\ |
21 | | - <fieldset>\ |
22 | | - <legend>Module properties</legend>\ |
23 | | - <table>\ |
24 | | - <tr>\ |
25 | | - <td><label for="mw-gadgetmanager-input-scripts"><html:msg key="gadgetmanager-prop-scripts"></label></td>\ |
26 | | - <td><input type="text" id="mw-gadgetmanager-input-scripts" /></td>\ |
27 | | - </tr>\ |
28 | | - <tr>\ |
29 | | - <td><label for="mw-gadgetmanager-input-styles"><html:msg key="gadgetmanager-prop-styles"></label></td>\ |
30 | | - <td><input type="text" id="mw-gadgetmanager-input-styles" /></td>\ |
31 | | - </tr>\ |
32 | | - <tr>\ |
33 | | - <td><label for="mw-gadgetmanager-input-dependencies"><html:msg key="gadgetmanager-prop-dependencies"></label></td>\ |
34 | | - <td><input type="text" id="mw-gadgetmanager-input-dependencies" /></td>\ |
35 | | - </tr>\ |
36 | | - <tr>\ |
37 | | - <td><label for="mw-gadgetmanager-input-messages"><html:msg key="gadgetmanager-prop-messages"></label></td>\ |
38 | | - <td><input type="text" id="mw-gadgetmanager-input-messages" /></td>\ |
39 | | - </tr>\ |
40 | | - </table>\ |
41 | | - </fieldset>\ |
42 | | - <fieldset>\ |
43 | | - <legend>Gadget settings</legend>\ |
44 | | - <table>\ |
45 | | - <tr>\ |
46 | | - <td><label for="mw-gadgetmanager-input-category"><html:msg key="gadgetmanager-prop-category"></label></td>\ |
47 | | - <td><select id="mw-gadgetmanager-input-category"></select></td>\ |
48 | | - </tr>\ |
49 | | - <tr>\ |
50 | | - <td><label for="mw-gadgetmanager-input-rights"><html:msg key="gadgetmanager-prop-rights"></label></td>\ |
51 | | - <td><input type="text" id="mw-gadgetmanager-input-rights" /></td>\ |
52 | | - </tr>\ |
53 | | - <tr>\ |
54 | | - <td><label for="mw-gadgetmanager-input-default"><html:msg key="gadgetmanager-prop-default"></label></td>\ |
55 | | - <td><input type="checkbox" id="mw-gadgetmanager-input-default" /></td>\ |
56 | | - </tr>\ |
57 | | - <tr>\ |
58 | | - <td><label for="mw-gadgetmanager-input-hidden"><html:msg key="gadgetmanager-prop-hidden"></label></td>\ |
59 | | - <td><input type="checkbox" id="mw-gadgetmanager-input-hidden" /></td>\ |
60 | | - </tr>\ |
61 | | - ' + ( ga.conf.enableSharing ? '<tr>\ |
62 | | - <td><label for="mw-gadgetmanager-input-shared"><html:msg key="gadgetmanager-prop-shared"></label></td>\ |
63 | | - <td><input type="checkbox" id="mw-gadgetmanager-input-shared" /></td>\ |
64 | | - </tr>\ |
65 | | - ' : '' ) + '</table>\ |
66 | | - </fieldset>\ |
67 | | - </form>' |
68 | | - }, |
69 | | - /** |
70 | | - * @var {Object} Static cache for suggestions by script prefix. |
71 | | - */ |
72 | | - suggestCacheScripts = {}, |
73 | | - /** |
74 | | - * @var {Object} Static cache for suggestions by style prefix. |
75 | | - */ |
76 | | - suggestCacheStyles = {}, |
77 | | - /** |
78 | | - * @var {Object} Static cache for suggestions by messages prefix. |
79 | | - */ |
80 | | - suggestCacheMsgs = {}, |
81 | | - /** |
82 | | - * @var {Object} Complete static cache for module names. Lazy loaded from null. |
83 | | - */ |
84 | | - suggestCacheDependencies = null, |
85 | | - /** |
86 | | - * @var {Object} Complete static cache for all rights. |
87 | | - */ |
88 | | - suggestCacheRights = ga.conf.allRights, |
89 | | - /** |
90 | | - * @var {Number} Maximum number of autocomplete suggestions in the gadget editor input fields. |
91 | | - */ |
92 | | - suggestLimit = 7; |
93 | | - |
94 | | - /* Local functions */ |
95 | | - |
96 | | - /** |
97 | | - * Utility function to pad a zero |
98 | | - * to single digit number. Used by ISODateString(). |
99 | | - * @param n {Number} |
100 | | - * @return {String} |
101 | | - */ |
102 | | - function pad( n ) { |
103 | | - return n < 10 ? '0' + n : n; |
104 | | - } |
105 | | - /** |
106 | | - * Format a date in an ISO 8601 format using UTC. |
107 | | - * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example:_ISO_8601_formatted_dates |
108 | | - * |
109 | | - * @param d {Date} |
110 | | - * @return {String} |
111 | | - */ |
112 | | - function ISODateString( d ) { |
113 | | - return d.getUTCFullYear() + '-' |
114 | | - + pad( d.getUTCMonth() + 1 ) + '-' |
115 | | - + pad( d.getUTCDate() ) + 'T' |
116 | | - + pad( d.getUTCHours() ) + ':' |
117 | | - + pad( d.getUTCMinutes() ) + ':' |
118 | | - + pad( d.getUTCSeconds() ) + 'Z'; |
119 | | - } |
120 | | - |
121 | | - /* Public functions */ |
122 | | - |
123 | | - ga.ui = { |
124 | | - /** |
125 | | - * Initializes the the page. For now just binding click handlers |
126 | | - * to the anchor tags in the table. |
127 | | - */ |
128 | | - initUI: function() { |
129 | | - // Bind trigger to the links |
130 | | - $( '.mw-gadgetmanager-gadgets .mw-gadgetmanager-gadgets-title a' ) |
131 | | - .click( function( e ) { |
132 | | - e.preventDefault(); |
133 | | - ga.ui.startGadgetEditor( $( this ).data( 'gadget-id' ) ); |
134 | | - }); |
135 | | - }, |
136 | | - |
137 | | - /** |
138 | | - * Initialize the gadget editor dialog. |
139 | | - * |
140 | | - * @asynchronous |
141 | | - * @param gadgetId {String} |
142 | | - */ |
143 | | - startGadgetEditor: function( gadgetId ) { |
144 | | - // Ad hoc multi-loader. We need both requests, which are asynchronous, |
145 | | - // to be complete. Which ever finishes first will set the local variable |
146 | | - // to it's return value for the other callback to use. |
147 | | - // @todo Notification: In case of an 'error'. |
148 | | - var gadget, cats; |
149 | | - |
150 | | - ga.api.getGadgetCategories( function( ret ) { |
151 | | - if ( gadget ) { |
152 | | - // getGadgetData already done |
153 | | - return ga.ui.showFancyForm( gadget, ret ); |
154 | | - } |
155 | | - // getGadgetData not done yet, leave cats for it's callback to use |
156 | | - cats = ret; |
157 | | - }); |
158 | | - |
159 | | - ga.api.getGadgetData( gadgetId, function( ret ) { |
160 | | - if ( cats ) { |
161 | | - // getGadgetCategories already done |
162 | | - return ga.ui.showFancyForm( ret, cats ); |
163 | | - } |
164 | | - // getGadgetCategories not done yet, leave gadget for it's callback to use |
165 | | - gadget = ret; |
166 | | - }); |
167 | | - }, |
168 | | - |
169 | | - /** |
170 | | - * Generate form, create a dialog and open it into view. |
171 | | - * |
172 | | - * @param gadget {Object} Gadget object of the gadget to be modified. |
173 | | - * @param categories {Array} Gadget categories. |
174 | | - * @return {jQuery} The (dialogged) form. |
175 | | - */ |
176 | | - showFancyForm: function( gadget, categories ) { |
177 | | - var $form = ga.ui.getFancyForm( gadget.metadata, categories ), |
178 | | - buttons = {}; |
179 | | - |
180 | | - // Form submit |
181 | | - buttons[mw.msg( 'gadgetmanager-editor-save' )] = function() { |
182 | | - ga.api.doModifyGadget( gadget, { |
183 | | - starttimestamp: ISODateString( new Date() ), |
184 | | - success: function( response ) { |
185 | | - $form.dialog( 'close' ); |
186 | | - window.location.reload(); |
187 | | - }, |
188 | | - error: function( error ) { |
189 | | - mw.log( 'mw.gadgets.api.doModifyGadget: error', error ); |
190 | | - // @todo Notification: $formNotif.add( .. ); |
191 | | - } |
192 | | - }); |
193 | | - }; |
194 | | - |
195 | | - return $form |
196 | | - .dialog({ |
197 | | - autoOpen: true, |
198 | | - width: 800, |
199 | | - modal: true, |
200 | | - draggable: false, |
201 | | - resizable: false, |
202 | | - title: mw.message( 'gadgetmanager-editor-title', gadget.title ).escaped(), |
203 | | - buttons: buttons, |
204 | | - open: function() { |
205 | | - // Dialog is ready for action. |
206 | | - // Push out any notifications if some were queued up already between |
207 | | - // getting the gadget data and the display of the form. |
208 | | - |
209 | | - // @todo Notification: $formNotif.add( .. ); |
210 | | - } |
211 | | - }); |
212 | | - }, |
213 | | - |
214 | | - /** |
215 | | - * Generate a <form> for the given module. |
216 | | - * Also binds events for submission and autocompletion. |
217 | | - * |
218 | | - * @param metadata {Object} Object to read and write to, used when saving |
219 | | - * the gadget metadata back through the API. |
220 | | - * @param categories {Array} Gadget categories. |
221 | | - * @return {jQuery} The form. |
222 | | - */ |
223 | | - getFancyForm: function( metadata, categories ) { |
224 | | - var nsGadgetId = mw.config.get( 'wgNamespaceIds' ).gadget, |
225 | | - $form = $( tpl.fancyForm ).localize(); |
226 | | - |
227 | | - // Module properties: scripts |
228 | | - $form.find( '#mw-gadgetmanager-input-scripts' ).createPropCloud({ |
229 | | - props: metadata.module.scripts, |
230 | | - autocompleteSource: function( data, response ) { |
231 | | - // Use cache if available |
232 | | - if ( data.term in suggestCacheScripts ) { |
233 | | - response( suggestCacheScripts[data.term] ); |
234 | | - return; |
235 | | - } |
236 | | - $.getJSON( mw.util.wikiScript( 'api' ), { |
237 | | - format: 'json', |
238 | | - action: 'query', |
239 | | - list: 'gadgetpages', |
240 | | - gpnamespace: nsGadgetId, |
241 | | - gpextension: 'js', |
242 | | - gpprefix: data.term |
243 | | - }, function( json ) { |
244 | | - if ( json && json.query && json.query.gadgetpages ) { |
245 | | - var suggestions = json.query.gadgetpages.splice( 0, suggestLimit ); |
246 | | - suggestions = $.map( suggestions, function( val, i ) { |
247 | | - return val.pagename; |
248 | | - }); |
249 | | - |
250 | | - // Update cache |
251 | | - suggestCacheScripts[data.term] = suggestions; |
252 | | - |
253 | | - response( suggestions ); |
254 | | - } else { |
255 | | - response( [] ); |
256 | | - } |
257 | | - } |
258 | | - ); |
259 | | - }, |
260 | | - prefix: 'mw-gadgetmanager-', |
261 | | - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
262 | | - }); |
263 | | - |
264 | | - // Module properties: styles |
265 | | - $form.find( '#mw-gadgetmanager-input-styles' ).createPropCloud({ |
266 | | - props: metadata.module.styles, |
267 | | - autocompleteSource: function( data, response ) { |
268 | | - // Use cache if available |
269 | | - if ( data.term in suggestCacheStyles ) { |
270 | | - response( suggestCacheStyles[data.term] ); |
271 | | - return; |
272 | | - } |
273 | | - $.getJSON( mw.util.wikiScript( 'api' ), { |
274 | | - format: 'json', |
275 | | - action: 'query', |
276 | | - list: 'gadgetpages', |
277 | | - gpnamespace: nsGadgetId, |
278 | | - gpextension: 'css', |
279 | | - gpprefix: data.term |
280 | | - }, function( json ) { |
281 | | - if ( json && json.query && json.query.gadgetpages ) { |
282 | | - var suggestions = $.map( json.query.gadgetpages, function( val, i ) { |
283 | | - return val.pagename; |
284 | | - }); |
285 | | - suggestions = suggestions.splice( 0, suggestLimit ); |
286 | | - |
287 | | - // Update cache |
288 | | - suggestCacheStyles[data.term] = suggestions; |
289 | | - |
290 | | - response( suggestions ); |
291 | | - } else { |
292 | | - response( [] ); |
293 | | - } |
294 | | - } |
295 | | - ); |
296 | | - }, |
297 | | - prefix: 'mw-gadgetmanager-', |
298 | | - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
299 | | - }); |
300 | | - |
301 | | - // Module properties: dependencies |
302 | | - $form.find( '#mw-gadgetmanager-input-dependencies' ).createPropCloud({ |
303 | | - props: metadata.module.dependencies, |
304 | | - autocompleteSource: function( data, response ) { |
305 | | - if ( suggestCacheDependencies === null ) { |
306 | | - suggestCacheDependencies = mw.loader.getModuleNames(); |
307 | | - } |
308 | | - var output = $.ui.autocomplete.filter( suggestCacheDependencies, data.term ); |
309 | | - response( output.slice( 0, suggestLimit ) ); |
310 | | - }, |
311 | | - prefix: 'mw-gadgetmanager-', |
312 | | - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
313 | | - }); |
314 | | - |
315 | | - // Module properties: messages |
316 | | - $form.find( '#mw-gadgetmanager-input-messages' ).createPropCloud({ |
317 | | - props: metadata.module.messages, |
318 | | - autocompleteSource: function( data, response ) { |
319 | | - // Use cache if available |
320 | | - if ( data.term in suggestCacheMsgs ) { |
321 | | - response( suggestCacheMsgs[data.term] ); |
322 | | - return; |
323 | | - } |
324 | | - $.getJSON( mw.util.wikiScript( 'api' ), { |
325 | | - format: 'json', |
326 | | - action: 'query', |
327 | | - meta: 'allmessages', |
328 | | - amprefix: data.term, |
329 | | - amnocontent: true, |
330 | | - amlang: mw.config.get( 'wgContentLanguage' ) |
331 | | - }, function( json ) { |
332 | | - if ( json && json.query && json.query.allmessages ) { |
333 | | - var suggestions = $.map( json.query.allmessages, function( val, i ) { |
334 | | - return val.name; |
335 | | - }); |
336 | | - suggestions = suggestions.splice( 0, suggestLimit ); |
337 | | - |
338 | | - // Update cache |
339 | | - suggestCacheMsgs[data.term] = suggestions; |
340 | | - |
341 | | - response( suggestions ); |
342 | | - } else { |
343 | | - response( [] ); |
344 | | - } |
345 | | - } |
346 | | - ); |
347 | | - }, |
348 | | - prefix: 'mw-gadgetmanager-', |
349 | | - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
350 | | - }); |
351 | | - |
352 | | - // Gadget settings: category |
353 | | - $form.find( '#mw-gadgetmanager-input-category' ).append( function() { |
354 | | - var current = metadata.settings.category, |
355 | | - opts = '', |
356 | | - i = 0, |
357 | | - cat; |
358 | | - for ( ; i < categories.length; i++ ) { |
359 | | - cat = categories[i]; |
360 | | - opts += mw.html.element( 'option', { |
361 | | - value: cat.name, |
362 | | - selected: cat.name === current |
363 | | - }, cat.title ); |
364 | | - } |
365 | | - return opts; |
366 | | - }).change( function() { |
367 | | - metadata.settings.category = $(this).val(); |
368 | | - }); |
369 | | - |
370 | | - // Gadget settings: rights |
371 | | - $form.find( '#mw-gadgetmanager-input-rights' ).createPropCloud({ |
372 | | - props: metadata.settings.rights, |
373 | | - autocompleteSource: function( data, response ) { |
374 | | - var output = $.ui.autocomplete.filter( suggestCacheRights, data.term ); |
375 | | - response( output.slice( 0, suggestLimit ) ); |
376 | | - }, |
377 | | - prefix: 'mw-gadgetmanager-', |
378 | | - removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
379 | | - }); |
380 | | - |
381 | | - // Gadget settings: Default |
382 | | - $form.find( '#mw-gadgetmanager-input-default' ) |
383 | | - .prop( 'checked', metadata.settings['default'] ) |
384 | | - .change( function() { |
385 | | - metadata.settings['default'] = this.checked; |
386 | | - }); |
387 | | - |
388 | | - // Gadget settings: Hidden |
389 | | - $form.find( '#mw-gadgetmanager-input-hidden' ) |
390 | | - .prop( 'checked', metadata.settings.hidden ) |
391 | | - .change( function() { metadata.settings.hidden = this.checked; }); |
392 | | - |
393 | | - // Gadget settings: Shared |
394 | | - $form.find( '#mw-gadgetmanager-input-shared' ) |
395 | | - .prop( 'checked', metadata.settings.shared ) |
396 | | - .change( function() { metadata.settings.shared = this.checked; }); |
397 | | - |
398 | | - |
399 | | - return $form; |
400 | | - } |
401 | | - }; |
402 | | - |
403 | | - // Launch on document ready |
404 | | - $( document ).ready( ga.ui.initUI ); |
405 | | - |
406 | | -})( jQuery ); |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.prejs.css |
— | — | @@ -1,14 +0,0 @@ |
2 | | -.mw-gadgetmanager-gadgets.mw-datatable th { |
3 | | - padding: 2px 21px 2px 5px; |
4 | | -} |
5 | | - |
6 | | -.mw-gadgetmanager-gadgets.mw-datatable td { |
7 | | - padding: 2px 5px; |
8 | | -} |
9 | | - |
10 | | -.mw-gadgetmanager-gadgets-default, |
11 | | -.mw-gadgetmanager-gadgets-hidden, |
12 | | -.mw-gadgetmanager-gadgets-shared { |
13 | | - width: 4em; |
14 | | - text-align: center; |
15 | | -} |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.prejs.css |
— | — | @@ -0,0 +1,14 @@ |
| 2 | +.mw-gadgetmanager-gadgets.mw-datatable th { |
| 3 | + padding: 2px 21px 2px 5px; |
| 4 | +} |
| 5 | + |
| 6 | +.mw-gadgetmanager-gadgets.mw-datatable td { |
| 7 | + padding: 2px 5px; |
| 8 | +} |
| 9 | + |
| 10 | +.mw-gadgetmanager-gadgets-default, |
| 11 | +.mw-gadgetmanager-gadgets-hidden, |
| 12 | +.mw-gadgetmanager-gadgets-shared { |
| 13 | + width: 4em; |
| 14 | + text-align: center; |
| 15 | +} |
Property changes on: branches/RL2/extensions/Gadgets/modules/ext.gadgets.prejs.css |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 16 | + native |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.css |
— | — | @@ -0,0 +1,67 @@ |
| 2 | +/** |
| 3 | + * Styling for the gadget manager javascript-generated user interface. |
| 4 | + */ |
| 5 | + |
| 6 | +/** |
| 7 | + * Form |
| 8 | + */ |
| 9 | +.mw-gadgetmanager-form fieldset { |
| 10 | + margin: 0; |
| 11 | +} |
| 12 | + |
| 13 | +.mw-gadgetmanager-form table { |
| 14 | + width: 100%; |
| 15 | +} |
| 16 | + |
| 17 | +.mw-gadgetmanager-form td, |
| 18 | +.mw-gadgetmanager-form th { |
| 19 | + vertical-align: top; |
| 20 | +} |
| 21 | + |
| 22 | +/** |
| 23 | + * The PropCloud |
| 24 | + */ |
| 25 | +.mw-gadgetmanager-propcloud { |
| 26 | + background: white; |
| 27 | + border: 1px solid grey; |
| 28 | + overflow: hidden; |
| 29 | +} |
| 30 | + |
| 31 | +.mw-gadgetmanager-propcontainer {} |
| 32 | + |
| 33 | +.mw-gadgetmanager-prop { |
| 34 | + float: left; |
| 35 | + margin: 2px 5px 5px 2px; |
| 36 | + padding: 2px 5px; |
| 37 | + background: #e5eff6; |
| 38 | + border: 1px solid #a4d2fb; |
| 39 | + border-radius: 10px; |
| 40 | + line-height: 1; |
| 41 | +} |
| 42 | + |
| 43 | +.mw-gadgetmanager-prop-label {} |
| 44 | + |
| 45 | +.mw-gadgetmanager-prop-delete { |
| 46 | + display: inline-block; |
| 47 | + width: 10px; |
| 48 | + height: 10px; |
| 49 | + /* @embed */ |
| 50 | + background: url(images/close.png) 50% 50% no-repeat; |
| 51 | + opacity: 0.4; |
| 52 | +} |
| 53 | + |
| 54 | +.mw-gadgetmanager-prop:hover .mw-gadgetmanager-prop-delete { |
| 55 | + opacity: 0.7; |
| 56 | +} |
| 57 | + |
| 58 | +.mw-gadgetmanager-prop:hover .mw-gadgetmanager-prop-delete:hover { |
| 59 | + opacity: 1; |
| 60 | + cursor: pointer; |
| 61 | +} |
| 62 | + |
| 63 | +.mw-gadgetmanager-propinput, |
| 64 | +.mw-gadgetmanager-propinput:focus { |
| 65 | + border: 0; |
| 66 | + outline: 0; |
| 67 | + background: transparent; |
| 68 | +} |
Index: branches/RL2/extensions/Gadgets/modules/ext.gadgets.gadgetmanager.js |
— | — | @@ -0,0 +1,405 @@ |
| 2 | +/** |
| 3 | + * JavaScript to initialize the UI of the gadget manager. |
| 4 | + * |
| 5 | + * @author Timo Tijhof |
| 6 | + * @copyright © 2011 Timo Tijhof |
| 7 | + * @license GNU General Public Licence 2.0 or later |
| 8 | + */ |
| 9 | +( function( $ ) { |
| 10 | + |
| 11 | + var |
| 12 | + /** |
| 13 | + * @var {Object} Local alias to mw.gadgets |
| 14 | + */ |
| 15 | + ga = mw.gadgets, |
| 16 | + /** |
| 17 | + * @var {Object} HTML fragements |
| 18 | + */ |
| 19 | + tpl = { |
| 20 | + fancyForm: '<form class="mw-gadgetmanager-form">\ |
| 21 | + <fieldset>\ |
| 22 | + <legend>Module properties</legend>\ |
| 23 | + <table>\ |
| 24 | + <tr>\ |
| 25 | + <td><label for="mw-gadgetmanager-input-scripts"><html:msg key="gadgetmanager-prop-scripts"></label></td>\ |
| 26 | + <td><input type="text" id="mw-gadgetmanager-input-scripts" /></td>\ |
| 27 | + </tr>\ |
| 28 | + <tr>\ |
| 29 | + <td><label for="mw-gadgetmanager-input-styles"><html:msg key="gadgetmanager-prop-styles"></label></td>\ |
| 30 | + <td><input type="text" id="mw-gadgetmanager-input-styles" /></td>\ |
| 31 | + </tr>\ |
| 32 | + <tr>\ |
| 33 | + <td><label for="mw-gadgetmanager-input-dependencies"><html:msg key="gadgetmanager-prop-dependencies"></label></td>\ |
| 34 | + <td><input type="text" id="mw-gadgetmanager-input-dependencies" /></td>\ |
| 35 | + </tr>\ |
| 36 | + <tr>\ |
| 37 | + <td><label for="mw-gadgetmanager-input-messages"><html:msg key="gadgetmanager-prop-messages"></label></td>\ |
| 38 | + <td><input type="text" id="mw-gadgetmanager-input-messages" /></td>\ |
| 39 | + </tr>\ |
| 40 | + </table>\ |
| 41 | + </fieldset>\ |
| 42 | + <fieldset>\ |
| 43 | + <legend>Gadget settings</legend>\ |
| 44 | + <table>\ |
| 45 | + <tr>\ |
| 46 | + <td><label for="mw-gadgetmanager-input-category"><html:msg key="gadgetmanager-prop-category"></label></td>\ |
| 47 | + <td><select id="mw-gadgetmanager-input-category"></select></td>\ |
| 48 | + </tr>\ |
| 49 | + <tr>\ |
| 50 | + <td><label for="mw-gadgetmanager-input-rights"><html:msg key="gadgetmanager-prop-rights"></label></td>\ |
| 51 | + <td><input type="text" id="mw-gadgetmanager-input-rights" /></td>\ |
| 52 | + </tr>\ |
| 53 | + <tr>\ |
| 54 | + <td><label for="mw-gadgetmanager-input-default"><html:msg key="gadgetmanager-prop-default"></label></td>\ |
| 55 | + <td><input type="checkbox" id="mw-gadgetmanager-input-default" /></td>\ |
| 56 | + </tr>\ |
| 57 | + <tr>\ |
| 58 | + <td><label for="mw-gadgetmanager-input-hidden"><html:msg key="gadgetmanager-prop-hidden"></label></td>\ |
| 59 | + <td><input type="checkbox" id="mw-gadgetmanager-input-hidden" /></td>\ |
| 60 | + </tr>\ |
| 61 | + ' + ( ga.conf.enableSharing ? '<tr>\ |
| 62 | + <td><label for="mw-gadgetmanager-input-shared"><html:msg key="gadgetmanager-prop-shared"></label></td>\ |
| 63 | + <td><input type="checkbox" id="mw-gadgetmanager-input-shared" /></td>\ |
| 64 | + </tr>\ |
| 65 | + ' : '' ) + '</table>\ |
| 66 | + </fieldset>\ |
| 67 | + </form>' |
| 68 | + }, |
| 69 | + /** |
| 70 | + * @var {Object} Static cache for suggestions by script prefix. |
| 71 | + */ |
| 72 | + suggestCacheScripts = {}, |
| 73 | + /** |
| 74 | + * @var {Object} Static cache for suggestions by style prefix. |
| 75 | + */ |
| 76 | + suggestCacheStyles = {}, |
| 77 | + /** |
| 78 | + * @var {Object} Static cache for suggestions by messages prefix. |
| 79 | + */ |
| 80 | + suggestCacheMsgs = {}, |
| 81 | + /** |
| 82 | + * @var {Object} Complete static cache for module names. Lazy loaded from null. |
| 83 | + */ |
| 84 | + suggestCacheDependencies = null, |
| 85 | + /** |
| 86 | + * @var {Object} Complete static cache for all rights. |
| 87 | + */ |
| 88 | + suggestCacheRights = ga.conf.allRights, |
| 89 | + /** |
| 90 | + * @var {Number} Maximum number of autocomplete suggestions in the gadget editor input fields. |
| 91 | + */ |
| 92 | + suggestLimit = 7; |
| 93 | + |
| 94 | + /* Local functions */ |
| 95 | + |
| 96 | + /** |
| 97 | + * Utility function to pad a zero |
| 98 | + * to single digit number. Used by ISODateString(). |
| 99 | + * @param n {Number} |
| 100 | + * @return {String} |
| 101 | + */ |
| 102 | + function pad( n ) { |
| 103 | + return n < 10 ? '0' + n : n; |
| 104 | + } |
| 105 | + /** |
| 106 | + * Format a date in an ISO 8601 format using UTC. |
| 107 | + * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date#Example:_ISO_8601_formatted_dates |
| 108 | + * |
| 109 | + * @param d {Date} |
| 110 | + * @return {String} |
| 111 | + */ |
| 112 | + function ISODateString( d ) { |
| 113 | + return d.getUTCFullYear() + '-' |
| 114 | + + pad( d.getUTCMonth() + 1 ) + '-' |
| 115 | + + pad( d.getUTCDate() ) + 'T' |
| 116 | + + pad( d.getUTCHours() ) + ':' |
| 117 | + + pad( d.getUTCMinutes() ) + ':' |
| 118 | + + pad( d.getUTCSeconds() ) + 'Z'; |
| 119 | + } |
| 120 | + |
| 121 | + /* Public functions */ |
| 122 | + |
| 123 | + ga.ui = { |
| 124 | + /** |
| 125 | + * Initializes the the page. For now just binding click handlers |
| 126 | + * to the anchor tags in the table. |
| 127 | + */ |
| 128 | + initUI: function() { |
| 129 | + // Bind trigger to the links |
| 130 | + $( '.mw-gadgetmanager-gadgets .mw-gadgetmanager-gadgets-title a' ) |
| 131 | + .click( function( e ) { |
| 132 | + e.preventDefault(); |
| 133 | + ga.ui.startGadgetEditor( $( this ).data( 'gadget-id' ) ); |
| 134 | + }); |
| 135 | + }, |
| 136 | + |
| 137 | + /** |
| 138 | + * Initialize the gadget editor dialog. |
| 139 | + * |
| 140 | + * @asynchronous |
| 141 | + * @param gadgetId {String} |
| 142 | + */ |
| 143 | + startGadgetEditor: function( gadgetId ) { |
| 144 | + // Ad hoc multi-loader. We need both requests, which are asynchronous, |
| 145 | + // to be complete. Which ever finishes first will set the local variable |
| 146 | + // to it's return value for the other callback to use. |
| 147 | + // @todo Notification: In case of an 'error'. |
| 148 | + var gadget, cats; |
| 149 | + |
| 150 | + ga.api.getGadgetCategories( function( ret ) { |
| 151 | + if ( gadget ) { |
| 152 | + // getGadgetData already done |
| 153 | + return ga.ui.showFancyForm( gadget, ret ); |
| 154 | + } |
| 155 | + // getGadgetData not done yet, leave cats for it's callback to use |
| 156 | + cats = ret; |
| 157 | + }); |
| 158 | + |
| 159 | + ga.api.getGadgetData( gadgetId, function( ret ) { |
| 160 | + if ( cats ) { |
| 161 | + // getGadgetCategories already done |
| 162 | + return ga.ui.showFancyForm( ret, cats ); |
| 163 | + } |
| 164 | + // getGadgetCategories not done yet, leave gadget for it's callback to use |
| 165 | + gadget = ret; |
| 166 | + }); |
| 167 | + }, |
| 168 | + |
| 169 | + /** |
| 170 | + * Generate form, create a dialog and open it into view. |
| 171 | + * |
| 172 | + * @param gadget {Object} Gadget object of the gadget to be modified. |
| 173 | + * @param categories {Array} Gadget categories. |
| 174 | + * @return {jQuery} The (dialogged) form. |
| 175 | + */ |
| 176 | + showFancyForm: function( gadget, categories ) { |
| 177 | + var $form = ga.ui.getFancyForm( gadget.metadata, categories ), |
| 178 | + buttons = {}; |
| 179 | + |
| 180 | + // Form submit |
| 181 | + buttons[mw.msg( 'gadgetmanager-editor-save' )] = function() { |
| 182 | + ga.api.doModifyGadget( gadget, { |
| 183 | + starttimestamp: ISODateString( new Date() ), |
| 184 | + success: function( response ) { |
| 185 | + $form.dialog( 'close' ); |
| 186 | + window.location.reload(); |
| 187 | + }, |
| 188 | + error: function( error ) { |
| 189 | + mw.log( 'mw.gadgets.api.doModifyGadget: error', error ); |
| 190 | + // @todo Notification: $formNotif.add( .. ); |
| 191 | + } |
| 192 | + }); |
| 193 | + }; |
| 194 | + |
| 195 | + return $form |
| 196 | + .dialog({ |
| 197 | + autoOpen: true, |
| 198 | + width: 800, |
| 199 | + modal: true, |
| 200 | + draggable: false, |
| 201 | + resizable: false, |
| 202 | + title: mw.message( 'gadgetmanager-editor-title', gadget.title ).escaped(), |
| 203 | + buttons: buttons, |
| 204 | + open: function() { |
| 205 | + // Dialog is ready for action. |
| 206 | + // Push out any notifications if some were queued up already between |
| 207 | + // getting the gadget data and the display of the form. |
| 208 | + |
| 209 | + // @todo Notification: $formNotif.add( .. ); |
| 210 | + } |
| 211 | + }); |
| 212 | + }, |
| 213 | + |
| 214 | + /** |
| 215 | + * Generate a <form> for the given module. |
| 216 | + * Also binds events for submission and autocompletion. |
| 217 | + * |
| 218 | + * @param metadata {Object} Object to read and write to, used when saving |
| 219 | + * the gadget metadata back through the API. |
| 220 | + * @param categories {Array} Gadget categories. |
| 221 | + * @return {jQuery} The form. |
| 222 | + */ |
| 223 | + getFancyForm: function( metadata, categories ) { |
| 224 | + var nsGadgetId = mw.config.get( 'wgNamespaceIds' ).gadget, |
| 225 | + $form = $( tpl.fancyForm ).localize(); |
| 226 | + |
| 227 | + // Module properties: scripts |
| 228 | + $form.find( '#mw-gadgetmanager-input-scripts' ).createPropCloud({ |
| 229 | + props: metadata.module.scripts, |
| 230 | + autocompleteSource: function( data, response ) { |
| 231 | + // Use cache if available |
| 232 | + if ( data.term in suggestCacheScripts ) { |
| 233 | + response( suggestCacheScripts[data.term] ); |
| 234 | + return; |
| 235 | + } |
| 236 | + $.getJSON( mw.util.wikiScript( 'api' ), { |
| 237 | + format: 'json', |
| 238 | + action: 'query', |
| 239 | + list: 'gadgetpages', |
| 240 | + gpnamespace: nsGadgetId, |
| 241 | + gpextension: 'js', |
| 242 | + gpprefix: data.term |
| 243 | + }, function( json ) { |
| 244 | + if ( json && json.query && json.query.gadgetpages ) { |
| 245 | + var suggestions = json.query.gadgetpages.splice( 0, suggestLimit ); |
| 246 | + suggestions = $.map( suggestions, function( val, i ) { |
| 247 | + return val.pagename; |
| 248 | + }); |
| 249 | + |
| 250 | + // Update cache |
| 251 | + suggestCacheScripts[data.term] = suggestions; |
| 252 | + |
| 253 | + response( suggestions ); |
| 254 | + } else { |
| 255 | + response( [] ); |
| 256 | + } |
| 257 | + } |
| 258 | + ); |
| 259 | + }, |
| 260 | + prefix: 'mw-gadgetmanager-', |
| 261 | + removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
| 262 | + }); |
| 263 | + |
| 264 | + // Module properties: styles |
| 265 | + $form.find( '#mw-gadgetmanager-input-styles' ).createPropCloud({ |
| 266 | + props: metadata.module.styles, |
| 267 | + autocompleteSource: function( data, response ) { |
| 268 | + // Use cache if available |
| 269 | + if ( data.term in suggestCacheStyles ) { |
| 270 | + response( suggestCacheStyles[data.term] ); |
| 271 | + return; |
| 272 | + } |
| 273 | + $.getJSON( mw.util.wikiScript( 'api' ), { |
| 274 | + format: 'json', |
| 275 | + action: 'query', |
| 276 | + list: 'gadgetpages', |
| 277 | + gpnamespace: nsGadgetId, |
| 278 | + gpextension: 'css', |
| 279 | + gpprefix: data.term |
| 280 | + }, function( json ) { |
| 281 | + if ( json && json.query && json.query.gadgetpages ) { |
| 282 | + var suggestions = $.map( json.query.gadgetpages, function( val, i ) { |
| 283 | + return val.pagename; |
| 284 | + }); |
| 285 | + suggestions = suggestions.splice( 0, suggestLimit ); |
| 286 | + |
| 287 | + // Update cache |
| 288 | + suggestCacheStyles[data.term] = suggestions; |
| 289 | + |
| 290 | + response( suggestions ); |
| 291 | + } else { |
| 292 | + response( [] ); |
| 293 | + } |
| 294 | + } |
| 295 | + ); |
| 296 | + }, |
| 297 | + prefix: 'mw-gadgetmanager-', |
| 298 | + removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
| 299 | + }); |
| 300 | + |
| 301 | + // Module properties: dependencies |
| 302 | + $form.find( '#mw-gadgetmanager-input-dependencies' ).createPropCloud({ |
| 303 | + props: metadata.module.dependencies, |
| 304 | + autocompleteSource: function( data, response ) { |
| 305 | + if ( suggestCacheDependencies === null ) { |
| 306 | + suggestCacheDependencies = mw.loader.getModuleNames(); |
| 307 | + } |
| 308 | + var output = $.ui.autocomplete.filter( suggestCacheDependencies, data.term ); |
| 309 | + response( output.slice( 0, suggestLimit ) ); |
| 310 | + }, |
| 311 | + prefix: 'mw-gadgetmanager-', |
| 312 | + removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
| 313 | + }); |
| 314 | + |
| 315 | + // Module properties: messages |
| 316 | + $form.find( '#mw-gadgetmanager-input-messages' ).createPropCloud({ |
| 317 | + props: metadata.module.messages, |
| 318 | + autocompleteSource: function( data, response ) { |
| 319 | + // Use cache if available |
| 320 | + if ( data.term in suggestCacheMsgs ) { |
| 321 | + response( suggestCacheMsgs[data.term] ); |
| 322 | + return; |
| 323 | + } |
| 324 | + $.getJSON( mw.util.wikiScript( 'api' ), { |
| 325 | + format: 'json', |
| 326 | + action: 'query', |
| 327 | + meta: 'allmessages', |
| 328 | + amprefix: data.term, |
| 329 | + amnocontent: true, |
| 330 | + amlang: mw.config.get( 'wgContentLanguage' ) |
| 331 | + }, function( json ) { |
| 332 | + if ( json && json.query && json.query.allmessages ) { |
| 333 | + var suggestions = $.map( json.query.allmessages, function( val, i ) { |
| 334 | + return val.name; |
| 335 | + }); |
| 336 | + suggestions = suggestions.splice( 0, suggestLimit ); |
| 337 | + |
| 338 | + // Update cache |
| 339 | + suggestCacheMsgs[data.term] = suggestions; |
| 340 | + |
| 341 | + response( suggestions ); |
| 342 | + } else { |
| 343 | + response( [] ); |
| 344 | + } |
| 345 | + } |
| 346 | + ); |
| 347 | + }, |
| 348 | + prefix: 'mw-gadgetmanager-', |
| 349 | + removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
| 350 | + }); |
| 351 | + |
| 352 | + // Gadget settings: category |
| 353 | + $form.find( '#mw-gadgetmanager-input-category' ).append( function() { |
| 354 | + var current = metadata.settings.category, |
| 355 | + opts = '', |
| 356 | + i = 0, |
| 357 | + cat; |
| 358 | + for ( ; i < categories.length; i++ ) { |
| 359 | + cat = categories[i]; |
| 360 | + opts += mw.html.element( 'option', { |
| 361 | + value: cat.name, |
| 362 | + selected: cat.name === current |
| 363 | + }, cat.title ); |
| 364 | + } |
| 365 | + return opts; |
| 366 | + }).change( function() { |
| 367 | + metadata.settings.category = $(this).val(); |
| 368 | + }); |
| 369 | + |
| 370 | + // Gadget settings: rights |
| 371 | + $form.find( '#mw-gadgetmanager-input-rights' ).createPropCloud({ |
| 372 | + props: metadata.settings.rights, |
| 373 | + autocompleteSource: function( data, response ) { |
| 374 | + var output = $.ui.autocomplete.filter( suggestCacheRights, data.term ); |
| 375 | + response( output.slice( 0, suggestLimit ) ); |
| 376 | + }, |
| 377 | + prefix: 'mw-gadgetmanager-', |
| 378 | + removeTooltip: mw.msg( 'gadgetmanager-editor-removeprop-tooltip' ) |
| 379 | + }); |
| 380 | + |
| 381 | + // Gadget settings: Default |
| 382 | + $form.find( '#mw-gadgetmanager-input-default' ) |
| 383 | + .prop( 'checked', metadata.settings['default'] ) |
| 384 | + .change( function() { |
| 385 | + metadata.settings['default'] = this.checked; |
| 386 | + }); |
| 387 | + |
| 388 | + // Gadget settings: Hidden |
| 389 | + $form.find( '#mw-gadgetmanager-input-hidden' ) |
| 390 | + .prop( 'checked', metadata.settings.hidden ) |
| 391 | + .change( function() { metadata.settings.hidden = this.checked; }); |
| 392 | + |
| 393 | + // Gadget settings: Shared |
| 394 | + $form.find( '#mw-gadgetmanager-input-shared' ) |
| 395 | + .prop( 'checked', metadata.settings.shared ) |
| 396 | + .change( function() { metadata.settings.shared = this.checked; }); |
| 397 | + |
| 398 | + |
| 399 | + return $form; |
| 400 | + } |
| 401 | + }; |
| 402 | + |
| 403 | + // Launch on document ready |
| 404 | + $( document ).ready( ga.ui.initUI ); |
| 405 | + |
| 406 | +})( jQuery ); |