User:Newslinger/Notifier.js

// // Notifier (beta)

// Notifies other talk pages of a discussion on the current page // Please provide feedback at User talk:Newslinger/Notifier

$(function {  var api, log, pageName, texts, windowManager  var dialogReady = false

var talkNamespaceRegex = /(Talk|User talk|Wikipedia|Wikipedia talk|File talk|MediaWiki talk|Template talk|Help talk|Category talk|Portal talk|Draft talk|TimedText talk|Module talk):/

function init { mw.loader.using('mediawiki.util', function {      pageName = mw.config.get('wgPageName').replace(/_/g, ' ')

if (pageName === 'Wikipedia:Reliable sources/Noticeboard' && $('body.skin-vector').length) { markHeadings } else if (pageName.search(talkNamespaceRegex) === 0) { var markLink = mw.util.addPortletLink('p-cactions', '#', 'Notifier', 'ca-notifier',         'Notify other talk pages of a discussion on this page') $(markLink).click(function (event) {         event.preventDefault          markHeadings        }) }   })  }

function initDialog { OO.inheritClass(Dialog, OO.ui.ProcessDialog)

Dialog.static.name = 'notifierDialog' Dialog.static.title = 'Notifier' Dialog.static.actions = [ {       action: 'notify', label: 'Notify', flags: ['primary', 'progressive'] }, {       label: 'Cancel', flags: 'safe' }   ]

Dialog.prototype.initialize = function { Dialog.super.prototype.initialize.call(this)

this.$notifyingLabel = $(' Notifying of discussion: ') this.$discussionName = $(' ') this.$info = $('') this.$info.append(this.$notifyingLabel, this.$discussionName)

this.targetPages = new OO.ui.MultilineTextInputWidget({rows: 5}) this.targetPagesField = new OO.ui.FieldLayout(this.targetPages, {       label: 'Pages to notify',        align: 'top',        help: 'One page per line (maximum 90 pages). Only pages in talk and project namespaces are allowed. Subject to the rate limit on your account (90 edits/minute if autoconfirmed, and 8 edits/minute if not). Edits exceeding the limit will fail.',        helpInline: true      }) this.targetPages.on('change', (function (value) { var pageCount = value.trim.split('\n').length var countLabel = ''

if (pageCount > 90) { countLabel = ' (' + pageCount + ' pages; exceeds maximum of 90)' } else if (value) { countLabel = ' (' + pageCount + ' page' + (pageCount > 1 ? 's' : '') + ')' }

this.targetPagesField.setLabel('Pages to notify' + countLabel) }).bind(this))

this.messageTitle = new OO.ui.TextInputWidget({}) this.messageTitleField = new OO.ui.FieldLayout(this.messageTitle, {       label: 'Message title',        align: 'top'      }) this.message = new OO.ui.MultilineTextInputWidget({rows: 5}) this.messageField = new OO.ui.FieldLayout(this.message, {       label: 'Message',        align: 'top',        help: 'Signature not needed. Your signature will be added if not present at the end of the message.',        helpInline: true      })

this.log = new OO.ui.MultilineTextInputWidget({       readOnly: true,        rows: 5,        value: log      }) this.logField = new OO.ui.FieldLayout(this.log, {       label: 'Log',        align: 'top'      })

this.notificationTemplate = new OO.ui.TextInputWidget({readOnly: true}) this.notificationTemplateField = new OO.ui.FieldLayout(this.notificationTemplate, {       label: 'Notification template',        align: 'top',        help: 'After notifying, paste this template into the end of the original discussion.',        helpInline: true      })

this.panel = new OO.ui.PanelLayout({       padded: true,        expanded: false      })

this.panel.$element.append(this.$info, this.targetPagesField.$element, this.messageTitleField.$element,       this.messageField.$element, this.logField.$element, this.notificationTemplateField.$element) this.$body.append(this.panel.$element) }

Dialog.prototype.getSetupProcess = function (data) { data = data || {} return Dialog.super.prototype.getSetupProcess.call(this, data) .next(function {          this.$discussionName.text(pageName + ' § ' + texts[data.id])          this.message.setValue('')        }, this) }

Dialog.prototype.getActionProcess = function (action) { if (action === 'notify') { sendMessages(this) }     return Dialog.super.prototype.getActionProcess.call(this, action) }

Dialog.prototype.getBodyHeight = function { return this.panel.$element.outerHeight(true) }

windowManager = new OO.ui.WindowManager $(document.body).append(windowManager.$element)

dialogReady = true }

function Dialog (config) { Dialog.super.call(this, config) }

function markHeadings { texts = {} var $headings = $('#mw-content-text h2:not(.toctitle h2)')

$headings.each(function (index) {     var $headline = $(this).children('.mw-headline')      var id = $headline.attr('id')      var text = $headline.contents.not($headline.children('.mw-headline-number')).text.trim

createLink($(this), id, text) texts[id] = text }) }

function createLink ($heading, id, text) { var $link = $('notify') var $leftBracket = $(' [ ') var $rightBracket = $(' ] ') var $editSection = $(' ') $link.click(function (event) {     event.preventDefault      promptNotify(id)    }) $editSection.append($leftBracket, $link, $rightBracket) $heading.append($editSection)

return $link }

function promptNotify (id) { mw.loader.using(['oojs', 'oojs-ui'], function {      if (!dialogReady) {        initDialog      }

log = 'Ready to notify'

var dialog = new Dialog windowManager.addWindows([dialog]) windowManager.openWindow(dialog, {id: id}) }) }

function sendMessages (dialog) { api = api || new mw.Api

var targetPages = dialog.targetPages.getValue.trim.split('\n').map(function (targetPage) {     return targetPage.trim    }) var messageTitle = dialog.messageTitle.getValue.trim var message = dialog.message.getValue.trim if (message.slice(-4) !==  + ) { message += ' ' + '' }

var notificationTemplate = '' dialog.notificationTemplate.setValue(notificationTemplate)

var tasks = []

$.each(targetPages, function(index, targetPage) {     addLog(dialog, 'Notifying: ' + targetPage)

if (targetPage.search(talkNamespaceRegex) != 0) { addLog(dialog, 'Failed to notify: ' + targetPage) addLog(dialog, 'Error: Pages outside of talk and project namespaces are not allowed.')

return }

var task = api.newSection(targetPage, messageTitle, message, { redirect: true }) .then(function {          addLog(dialog, 'Successfully notified: ' + targetPage)        }, function(error) {          addLog(dialog, 'Failed to notify: ' + targetPage)          addLog(dialog, 'Error: ' + error)        })

tasks.push(task) })

$.when.apply(null, tasks).then(function {      addLog(dialog, 'Finished!')    }) }

function addLog (dialog, message) { log += '\n' + message dialog.log.setValue(log) }

init }) //