Merge "Update docs/hooks.txt for ShowSearchHitTitle"
[mediawiki.git] / resources / src / mediawiki / api / edit.js
blob21fad5e573b21faa6b0d5a4f859ac5623d8dff6e
1 /**
2  * @class mw.Api.plugin.edit
3  */
4 ( function ( mw, $ ) {
6         $.extend( mw.Api.prototype, {
8                 /**
9                  * Post to API with csrf token. If we have no token, get one and try to post.
10                  * If we have a cached token try using that, and if it fails, blank out the
11                  * cached token and start over.
12                  *
13                  * @param {Object} params API parameters
14                  * @param {Object} [ajaxOptions]
15                  * @return {jQuery.Promise} See #post
16                  */
17                 postWithEditToken: function ( params, ajaxOptions ) {
18                         return this.postWithToken( 'csrf', params, ajaxOptions );
19                 },
21                 /**
22                  * API helper to grab a csrf token.
23                  *
24                  * @return {jQuery.Promise} Received token.
25                  */
26                 getEditToken: function () {
27                         return this.getToken( 'csrf' );
28                 },
30                 /**
31                  * Create a new page.
32                  *
33                  * Example:
34                  *
35                  *     new mw.Api().create( 'Sandbox',
36                  *         { summary: 'Load sand particles.' },
37                  *         'Sand.'
38                  *     );
39                  *
40                  * @since 1.28
41                  * @param {mw.Title|string} title Page title
42                  * @param {Object} params Edit API parameters
43                  * @param {string} params.summary Edit summary
44                  * @param {string} content
45                  * @return {jQuery.Promise} API response
46                  */
47                 create: function ( title, params, content ) {
48                         return this.postWithEditToken( $.extend( {
49                                 action: 'edit',
50                                 title: String( title ),
51                                 text: content,
52                                 formatversion: '2',
54                                 // Protect against errors and conflicts
55                                 assert: mw.user.isAnon() ? undefined : 'user',
56                                 createonly: true
57                         }, params ) ).then( function ( data ) {
58                                 return data.edit;
59                         } );
60                 },
62                 /**
63                  * Edit an existing page.
64                  *
65                  * To create a new page, use #create() instead.
66                  *
67                  * Simple transformation:
68                  *
69                  *     new mw.Api()
70                  *         .edit( 'Sandbox', function ( revision ) {
71                  *             return revision.content.replace( 'foo', 'bar' );
72                  *         } )
73                  *         .then( function () {
74                  *             console.log( 'Saved! ');
75                  *         } );
76                  *
77                  * Set save parameters by returning an object instead of a string:
78                  *
79                  *     new mw.Api().edit(
80                  *         'Sandbox',
81                  *         function ( revision ) {
82                  *             return {
83                  *                 text: revision.content.replace( 'foo', 'bar' ),
84                  *                 summary: 'Replace "foo" with "bar".',
85                  *                 assert: 'bot',
86                  *                 minor: true
87                  *             };
88                  *         }
89                  *     )
90                  *     .then( function () {
91                  *         console.log( 'Saved! ');
92                  *     } );
93                  *
94                  * Transform asynchronously by returning a promise.
95                  *
96                  *     new mw.Api()
97                  *         .edit( 'Sandbox', function ( revision ) {
98                  *             return Spelling
99                  *                 .corrections( revision.content )
100                  *                 .then( function ( report ) {
101                  *                     return {
102                  *                         text: report.output,
103                  *                         summary: report.changelog
104                  *                     };
105                  *                 } );
106                  *         } )
107                  *         .then( function () {
108                  *             console.log( 'Saved! ');
109                  *         } );
110                  *
111                  * @since 1.28
112                  * @param {mw.Title|string} title Page title
113                  * @param {Function} transform Callback that prepares the edit
114                  * @param {Object} transform.revision Current revision
115                  * @param {string} transform.revision.content Current revision content
116                  * @param {string|Object|jQuery.Promise} transform.return New content, object with edit
117                  *  API parameters, or promise providing one of those.
118                  * @return {jQuery.Promise} Edit API response
119                  */
120                 edit: function ( title, transform ) {
121                         var basetimestamp, curtimestamp,
122                                 api = this;
123                         return api.get( {
124                                 action: 'query',
125                                 prop: 'revisions',
126                                 rvprop: [ 'content', 'timestamp' ],
127                                 titles: String( title ),
128                                 formatversion: '2',
129                                 curtimestamp: true
130                         } )
131                                 .then( function ( data ) {
132                                         var page, revision;
133                                         if ( !data.query || !data.query.pages ) {
134                                                 return $.Deferred().reject( 'unknown' );
135                                         }
136                                         page = data.query.pages[ 0 ];
137                                         if ( !page || page.missing ) {
138                                                 return $.Deferred().reject( 'nocreate-missing' );
139                                         }
140                                         revision = page.revisions[ 0 ];
141                                         basetimestamp = revision.timestamp;
142                                         curtimestamp = data.curtimestamp;
143                                         return transform( {
144                                                 timestamp: revision.timestamp,
145                                                 content: revision.content
146                                         } );
147                                 } )
148                                 .then( function ( params ) {
149                                         var editParams = typeof params === 'object' ? params : { text: String( params ) };
150                                         return api.postWithEditToken( $.extend( {
151                                                 action: 'edit',
152                                                 title: title,
153                                                 formatversion: '2',
155                                                 // Protect against errors and conflicts
156                                                 assert: mw.user.isAnon() ? undefined : 'user',
157                                                 basetimestamp: basetimestamp,
158                                                 starttimestamp: curtimestamp,
159                                                 nocreate: true
160                                         }, editParams ) );
161                                 } )
162                                 .then( function ( data ) {
163                                         return data.edit;
164                                 } );
165                 },
167                 /**
168                  * Post a new section to the page.
169                  *
170                  * @see #postWithEditToken
171                  * @param {mw.Title|string} title Target page
172                  * @param {string} header
173                  * @param {string} message wikitext message
174                  * @param {Object} [additionalParams] Additional API parameters, e.g. `{ redirect: true }`
175                  * @return {jQuery.Promise}
176                  */
177                 newSection: function ( title, header, message, additionalParams ) {
178                         return this.postWithEditToken( $.extend( {
179                                 action: 'edit',
180                                 section: 'new',
181                                 title: String( title ),
182                                 summary: header,
183                                 text: message
184                         }, additionalParams ) );
185                 }
186         } );
188         /**
189          * @class mw.Api
190          * @mixins mw.Api.plugin.edit
191          */
193 }( mediaWiki, jQuery ) );