From 1605864fb5b60ad99734e6cab3100dc6689f7289 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Sat, 13 Feb 2021 00:07:02 +0000 Subject: [PATCH] mediawiki.action.edit: Convert module to packageFiles Change-Id: Ib34e55a6a26ee783e3b41659189c236d5148bf0e --- resources/Resources.php | 12 +- .../src/mediawiki.action.edit/.eslintrc.json | 5 + resources/src/mediawiki.action.edit/edit.js | 80 ++--- resources/src/mediawiki.action.edit/stash.js | 289 +++++++++--------- .../mediawiki.action.edit/watchlistExpiry.js | 43 ++- 5 files changed, 215 insertions(+), 214 deletions(-) create mode 100644 resources/src/mediawiki.action.edit/.eslintrc.json diff --git a/resources/Resources.php b/resources/Resources.php index 0d73b75dcbe..ad255d5cb79 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1160,12 +1160,14 @@ return [ ], 'mediawiki.action.edit' => [ 'targets' => [ 'desktop', 'mobile' ], - 'scripts' => [ - 'resources/src/mediawiki.action.edit/edit.js', - 'resources/src/mediawiki.action.edit/stash.js', - 'resources/src/mediawiki.action.edit/watchlistExpiry.js', + 'localBasePath' => "$IP/resources/src/mediawiki.action.edit", + 'remoteBasePath' => "$wgResourceBasePath/resources/src/mediawiki.action.edit", + 'packageFiles' => [ + 'edit.js', + 'stash.js', + 'watchlistExpiry.js', ], - 'styles' => 'resources/src/mediawiki.action.edit/edit.css', + 'styles' => 'edit.css', 'dependencies' => [ 'mediawiki.action.edit.styles', 'mediawiki.editfont.styles', diff --git a/resources/src/mediawiki.action.edit/.eslintrc.json b/resources/src/mediawiki.action.edit/.eslintrc.json new file mode 100644 index 00000000000..cfa86a9bae8 --- /dev/null +++ b/resources/src/mediawiki.action.edit/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "no-implicit-globals": "off" + } +} diff --git a/resources/src/mediawiki.action.edit/edit.js b/resources/src/mediawiki.action.edit/edit.js index 0fcc666f6b2..39b16cefdc1 100644 --- a/resources/src/mediawiki.action.edit/edit.js +++ b/resources/src/mediawiki.action.edit/edit.js @@ -1,46 +1,50 @@ /*! - * Scripts for action=edit at domready + * Scripts for action=edit as rendered by EditPage.php. */ -( function () { - 'use strict'; +'use strict'; - /** - * Fired when the editform is added to the edit page - * - * Similar to the {@link mw.hook#event-wikipage_content wikipage.content hook} - * $editForm can still be detached when this hook is fired. - * - * @event wikipage_editform - * @member mw.hook - * @param {jQuery} $editForm The most appropriate element containing the - * editform, usually #editform. - */ +/** + * Fired when the editform is added to the edit page + * + * Similar to the {@link mw.hook#event-wikipage_content wikipage.content hook} + * $editForm can still be detached when this hook is fired. + * + * @event wikipage_editform + * @member mw.hook + * @param {jQuery} $editForm The most appropriate element containing the + * editform, usually #editform. + */ - $( function () { - var wpSummary, editBox, scrollTop, $editForm, - $wpSummary = $( '#wpSummaryWidget' ); +$( function () { + var wpSummary, editBox, scrollTop, $editForm, + $wpSummary = $( '#wpSummaryWidget' ); - // The summary field might not be there, e.g. when extensions replace it - if ( $wpSummary.length ) { - wpSummary = OO.ui.infuse( $wpSummary ); + // The summary field might not be there, e.g. when extensions replace it + if ( $wpSummary.length ) { + wpSummary = OO.ui.infuse( $wpSummary ); - // Show a byte-counter to users with how many bytes are left for their edit summary. - mw.widgets.visibleCodePointLimit( wpSummary, mw.config.get( 'wgCommentCodePointLimit' ) ); + // Show a byte-counter to users with how many bytes are left for their edit summary. + mw.widgets.visibleCodePointLimit( wpSummary, mw.config.get( 'wgCommentCodePointLimit' ) ); + } + + // Restore the edit box scroll state following a preview operation, + // and set up a form submission handler to remember this state. + editBox = document.getElementById( 'wpTextbox1' ); + scrollTop = document.getElementById( 'wpScrolltop' ); + $editForm = $( '#editform' ); + mw.hook( 'wikipage.editform' ).fire( $editForm ); + if ( $editForm.length && editBox && scrollTop ) { + if ( scrollTop.value ) { + editBox.scrollTop = scrollTop.value; } + $editForm.on( 'submit', function () { + scrollTop.value = editBox.scrollTop; + } ); + } +} ); - // Restore the edit box scroll state following a preview operation, - // and set up a form submission handler to remember this state. - editBox = document.getElementById( 'wpTextbox1' ); - scrollTop = document.getElementById( 'wpScrolltop' ); - $editForm = $( '#editform' ); - mw.hook( 'wikipage.editform' ).fire( $editForm ); - if ( $editForm.length && editBox && scrollTop ) { - if ( scrollTop.value ) { - editBox.scrollTop = scrollTop.value; - } - $editForm.on( 'submit', function () { - scrollTop.value = editBox.scrollTop; - } ); - } - } ); -}() ); +if ( mw.config.get( 'wgAjaxEditStash' ) ) { + require( './stash.js' ); +} + +require( './watchlistExpiry.js' ); diff --git a/resources/src/mediawiki.action.edit/stash.js b/resources/src/mediawiki.action.edit/stash.js index ea3c0da034f..cb8cfc0a4e6 100644 --- a/resources/src/mediawiki.action.edit/stash.js +++ b/resources/src/mediawiki.action.edit/stash.js @@ -1,165 +1,158 @@ /*! * Scripts for pre-emptive edit preparing on action=edit */ +$( function () { + var idleTimeout = 3000, + api = new mw.Api(), + timer, + stashReq, + lastText, + lastSummary, + lastTextHash, + $form = $( '#editform' ), + $text = $form.find( '#wpTextbox1' ), + $summary = $form.find( '#wpSummary' ), + section = $form.find( '[name=wpSection]' ).val(), + model = $form.find( '[name=model]' ).val(), + format = $form.find( '[name=format]' ).val(), + revId = $form.find( '[name=parentRevId]' ).val(), + lastPriority = 0, + PRIORITY_LOW = 1, + PRIORITY_HIGH = 2; -( function () { - if ( !mw.config.get( 'wgAjaxEditStash' ) ) { + // We don't attempt to stash new section edits because in such cases the parser output + // varies on the edit summary (since it determines the new section's name). + if ( !$form.length || section === 'new' ) { return; } - $( function () { - var idleTimeout = 3000, - api = new mw.Api(), - timer, - stashReq, - lastText, - lastSummary, - lastTextHash, - $form = $( '#editform' ), - $text = $form.find( '#wpTextbox1' ), - $summary = $form.find( '#wpSummary' ), - section = $form.find( '[name=wpSection]' ).val(), - model = $form.find( '[name=model]' ).val(), - format = $form.find( '[name=format]' ).val(), - revId = $form.find( '[name=parentRevId]' ).val(), - lastPriority = 0, - PRIORITY_LOW = 1, - PRIORITY_HIGH = 2; + // Whether the body text content changed since the last stashEdit() + function isTextChanged() { + return lastText !== $text.textSelection( 'getContents' ); + } - // We don't attempt to stash new section edits because in such cases the parser output - // varies on the edit summary (since it determines the new section's name). - if ( !$form.length || section === 'new' ) { + // Whether the edit summary has changed since the last stashEdit() + function isSummaryChanged() { + return lastSummary !== $summary.textSelection( 'getContents' ); + } + + // Send a request to stash the edit to the API. + // If a request is in progress, abort it since its payload is stale and the API + // may limit concurrent stash parses. + function stashEdit() { + var req, params, + textChanged = isTextChanged(), + priority = textChanged ? PRIORITY_HIGH : PRIORITY_LOW; + + if ( stashReq ) { + if ( lastPriority > priority ) { + // Stash request for summary change should wait on pending text change stash + // eslint-disable-next-line no-use-before-define + stashReq.then( checkStash ); + return; + } + stashReq.abort(); + } + + // Update the "last" tracking variables + lastSummary = $summary.textSelection( 'getContents' ); + lastPriority = priority; + if ( textChanged ) { + lastText = $text.textSelection( 'getContents' ); + // Reset hash + lastTextHash = null; + } + + params = { + formatversion: 2, + action: 'stashedit', + title: mw.config.get( 'wgPageName' ), + section: section, + sectiontitle: '', + summary: lastSummary, + contentmodel: model, + contentformat: format, + baserevid: revId + }; + if ( lastTextHash ) { + params.stashedtexthash = lastTextHash; + } else { + params.text = lastText; + } + + req = api.postWithToken( 'csrf', params ); + stashReq = req; + req.then( function ( data ) { + if ( req === stashReq ) { + stashReq = null; + } + if ( data.stashedit && data.stashedit.texthash ) { + lastTextHash = data.stashedit.texthash; + } else { + // Request failed or text hash expired; + // include the text in a future stash request. + lastTextHash = null; + } + } ); + } + + // Check whether text or summary have changed and call stashEdit() + function checkStash() { + if ( !isTextChanged() && !isSummaryChanged() ) { return; } - // Whether the body text content changed since the last stashEdit() - function isTextChanged() { - return lastText !== $text.textSelection( 'getContents' ); + stashEdit(); + } + + function onKeyUp( e ) { + // Ignore keystrokes that don't modify text, like cursor movements. + // See and + // . We don't have to be exhaustive, + // because the cost of misfiring is low. + // * Key code 33-40: Page Up/Down, End, Home, arrow keys. + // * Key code 16-18: Shift, Ctrl, Alt. + if ( ( e.which >= 33 && e.which <= 40 ) || ( e.which >= 16 && e.which <= 18 ) ) { + return; } - // Whether the edit summary has changed since the last stashEdit() - function isSummaryChanged() { - return lastSummary !== $summary.textSelection( 'getContents' ); - } + clearTimeout( timer ); + timer = setTimeout( checkStash, idleTimeout ); + } - // Send a request to stash the edit to the API. - // If a request is in progress, abort it since its payload is stale and the API - // may limit concurrent stash parses. - function stashEdit() { - var req, params, - textChanged = isTextChanged(), - priority = textChanged ? PRIORITY_HIGH : PRIORITY_LOW; + function onSummaryFocus() { + // Summary typing is usually near the end of the workflow and involves less pausing. + // Re-stash more frequently in hopes of capturing the final summary before submission. + idleTimeout = 1000; + // Stash now since the text is likely the final version. The re-stashes based on the + // summary are targeted at caching edit checks that need the final summary. + checkStash(); + } - if ( stashReq ) { - if ( lastPriority > priority ) { - // Stash request for summary change should wait on pending text change stash - // eslint-disable-next-line no-use-before-define - stashReq.then( checkStash ); - return; - } - stashReq.abort(); - } + function onTextFocus() { + // User returned to the text field... reset stash rate to default + idleTimeout = 3000; + } - // Update the "last" tracking variables - lastSummary = $summary.textSelection( 'getContents' ); - lastPriority = priority; - if ( textChanged ) { - lastText = $text.textSelection( 'getContents' ); - // Reset hash - lastTextHash = null; - } - - params = { - formatversion: 2, - action: 'stashedit', - title: mw.config.get( 'wgPageName' ), - section: section, - sectiontitle: '', - summary: lastSummary, - contentmodel: model, - contentformat: format, - baserevid: revId - }; - if ( lastTextHash ) { - params.stashedtexthash = lastTextHash; - } else { - params.text = lastText; - } - - req = api.postWithToken( 'csrf', params ); - stashReq = req; - req.then( function ( data ) { - if ( req === stashReq ) { - stashReq = null; - } - if ( data.stashedit && data.stashedit.texthash ) { - lastTextHash = data.stashedit.texthash; - } else { - // Request failed or text hash expired; - // include the text in a future stash request. - lastTextHash = null; - } - } ); - } - - // Check whether text or summary have changed and call stashEdit() - function checkStash() { - if ( !isTextChanged() && !isSummaryChanged() ) { - return; - } - - stashEdit(); - } - - function onKeyUp( e ) { - // Ignore keystrokes that don't modify text, like cursor movements. - // See and - // . We don't have to be exhaustive, - // because the cost of misfiring is low. - // * Key code 33-40: Page Up/Down, End, Home, arrow keys. - // * Key code 16-18: Shift, Ctrl, Alt. - if ( ( e.which >= 33 && e.which <= 40 ) || ( e.which >= 16 && e.which <= 18 ) ) { - return; - } - - clearTimeout( timer ); - timer = setTimeout( checkStash, idleTimeout ); - } - - function onSummaryFocus() { - // Summary typing is usually near the end of the workflow and involves less pausing. - // Re-stash more frequently in hopes of capturing the final summary before submission. - idleTimeout = 1000; - // Stash now since the text is likely the final version. The re-stashes based on the - // summary are targeted at caching edit checks that need the final summary. - checkStash(); - } - - function onTextFocus() { - // User returned to the text field... reset stash rate to default - idleTimeout = 3000; - } - - $text.on( { - keyup: onKeyUp, - focus: onTextFocus, - change: checkStash - } ); - $summary.on( { - keyup: onKeyUp, - focus: onSummaryFocus, - focusout: checkStash - } ); - - if ( - // Reverts may involve use (undo) links; stash as they review the diff. - // Since the form has a pre-filled summary, stash the edit immediately. - mw.util.getParamValue( 'undo' ) !== null || - // Pressing "show changes" and "preview" also signify that the user will - // probably save the page soon - [ 'preview', 'diff' ].indexOf( $form.find( '#mw-edit-mode' ).val() ) > -1 - ) { - checkStash(); - } + $text.on( { + keyup: onKeyUp, + focus: onTextFocus, + change: checkStash } ); -}() ); + $summary.on( { + keyup: onKeyUp, + focus: onSummaryFocus, + focusout: checkStash + } ); + + if ( + // Reverts may involve use (undo) links; stash as they review the diff. + // Since the form has a pre-filled summary, stash the edit immediately. + mw.util.getParamValue( 'undo' ) !== null || + // Pressing "show changes" and "preview" also signify that the user will + // probably save the page soon + [ 'preview', 'diff' ].indexOf( $form.find( '#mw-edit-mode' ).val() ) > -1 + ) { + checkStash(); + } +} ); diff --git a/resources/src/mediawiki.action.edit/watchlistExpiry.js b/resources/src/mediawiki.action.edit/watchlistExpiry.js index 5f79ac48490..bcc6400cade 100644 --- a/resources/src/mediawiki.action.edit/watchlistExpiry.js +++ b/resources/src/mediawiki.action.edit/watchlistExpiry.js @@ -1,28 +1,25 @@ -/* +/*! * Scripts for WatchlistExpiry on action=edit */ -( function () { - 'use strict'; +'use strict'; - // Toggle the watchlist-expiry dropdown's disabled state according to the - // selected state of the watchthis checkbox. - $( function () { - var watchThisWidget, expiryWidget, - // The 'wpWatchthis' and 'wpWatchlistExpiry' fields come from EditPage.php. - watchThisNode = document.getElementById( 'wpWatchthisWidget' ), - expiryNode = document.getElementById( 'wpWatchlistExpiryWidget' ); +// Toggle the watchlist-expiry dropdown's disabled state according to the +// selected state of the watchthis checkbox. +$( function () { + var watchThisWidget, expiryWidget, + // The 'wpWatchthis' and 'wpWatchlistExpiry' fields come from EditPage.php. + watchThisNode = document.getElementById( 'wpWatchthisWidget' ), + expiryNode = document.getElementById( 'wpWatchlistExpiryWidget' ); - if ( watchThisNode && expiryNode ) { - watchThisWidget = OO.ui.infuse( watchThisNode ); - expiryWidget = OO.ui.infuse( expiryNode ); - // Set initial state to match the watchthis checkbox. - expiryWidget.setDisabled( !watchThisWidget.isSelected() ); + if ( watchThisNode && expiryNode ) { + watchThisWidget = OO.ui.infuse( watchThisNode ); + expiryWidget = OO.ui.infuse( expiryNode ); + // Set initial state to match the watchthis checkbox. + expiryWidget.setDisabled( !watchThisWidget.isSelected() ); - // Change state on every change of the watchthis checkbox. - watchThisWidget.on( 'change', function ( enabled ) { - expiryWidget.setDisabled( !enabled ); - } ); - } - } ); - -}() ); + // Change state on every change of the watchthis checkbox. + watchThisWidget.on( 'change', function ( enabled ) { + expiryWidget.setDisabled( !enabled ); + } ); + } +} );