From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.

// <nowiki>

// 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 = $('<div>Notifying of discussion:</div>')

      this.$discussionName = $('<div style="font-weight: bold" />')

      this.$info = $('<p />')

      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 + ' § ' + textsdata.id])

          this.message.setValue('{{slink|' + pageName + '|' + textsdata.id + '}}')

        }, 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)

      textsid = text

    })

  }



  function createLink ($heading, id, text) {

    var $link = $('<a href="#">notify</a>')

    var $leftBracket = $('<span class="mw-editsection-bracket">[</span>')

    var $rightBracket = $('<span class="mw-editsection-bracket">]</span>')

    var $editSection = $('<span class="mw-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 = '{{subst' + ':notified|' + targetPages.join('|') + '}}'

    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()

})

// </nowiki>