User:Irukaza/common.js:修订间差异

H萌娘,万物皆可H的百科全书!
跳到导航 跳到搜索
imported>=海豚=
无编辑摘要
imported>=海豚=
无编辑摘要
(未显示同一用户的63个中间版本)
第1行: 第1行:
if (mw.config.get("wgAction") === "view"&& !document.querySelector("#noteTA-lang")) {
$(() => {
       var url = new mw.Uri();
  const notificationIcon = 'https://img.moegirl.org.cn/common/thumb/f/f6/%E8%93%9D%E8%90%8C%E5%AD%97.png/233px-%E8%93%9D%E8%90%8C%E5%AD%97.png'
       var wgUserVariant = mw.config.get("wgUserVariant");
  const workerUrl = window.mw ?
    $(window).scroll(function(){
'/index.php?title=User:東東君/js/notification.js&action=raw&ctype=text/javascript' :
     if ($(this).scrollTop() > 1000) {
'notification.js'
       $("body").append('<div id="noteTA-lang" style="background: #a7a93cf0; color: white; text-align: center; padding: .17rem; position: fixed; top: 0; left: 0; right: 0; z-index: 9999;"><p> 我们鼓励您编辑 条目 ,创建账号成为本站 一员 登录后您可以建立自己的 户页并署名贡献(<a class="p4js-conversion-link mw-ui-destructive" href="www.baidu.com"> 注册 </a>|<a class="p4js-conversion-link mw-ui-destructive" href="www.baidu.com"> 登录 </a> )(<span id="noteTA-lang-disable" class="p4js-conversion-link mw-ui-destructive"> 不再提示 </span> </div>');
 
      }
  checkNotificationPermission()
    });
  main()
 
  async function main() {
   const worker = await registerService()
   const configListener = new WorkerDataListener(worker, 'config')
   const uiController = initUI({ onSaveConfig })
 
   configListener.pullData()
 
    configListener.addListener(data => {
    uiController.updateConfig(data)
   })
 
   function onSaveConfig(config) {
    worker.postMessage({ type: 'saveConfig', data: { config } })
    alert('配置已保存')
   }
  }
 
  navigator.serviceWorker.addEventListener('message', e => {
   const { type, data } = e.data
   if (type === 'sendNotification') {
    const [title, options] = data
    const link = options.data.link
    new Notification(title, options).onclick = () => window.open(link, '_blank')
   }
  })
 
  function initUI({
   onSaveConfig
  }) {
   const template = `
    <div class="widget-notification-config" style="display:none;">
     <div class="body"> 
      <fieldset>
       <legend>设置</legend>
       <form class="settings" action="javascript:void(0)">
        <label>
         <span>开启</span>
         <input type="checkbox" name="enable">
        </label>
 
        <label>
         <div>排除 条目 :</div>
         <textarea placeholder="当其中 条目发生变化时不会通知 使 换行分割" name="excludeList"></textarea>
        </label>
 
        <div class="buttonGroup">
         <button class="saveConfig"> 保存</button>
         <button class="closeModal"> 关闭</button>
        </div>
       </form>
      </fieldset>
      </div>
    </div>
   `
 
    const cssStyle = `
    <style>
     .widget-notification-config {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.2);
      font-size: 14px;
      z-index: 100;
      }
      }
  $(".noteTA-lang-changer").on("click", function(e) {
 
           var uri = new mw.Uri();
     .widget-notification-config > .body {
           var path = uri.path;
      background-color: white;
           Object.keys(map).forEach(function(s) {
      width: 300px;
             path = path.replace(new RegExp("^/" + s + "/"), "/");
      box-sizing: border-box;
           });
      padding: 10px;
           uri.path = "/" + e.target.dataset.lang + "/" + path.replace(/^\//, "");
      border-radius: 5px;
           location.replace(uri);
      border: 2px #ccc ridge;
           $("#noteTA-lang").remove();
      position: absolute;
         }).filter('[data-lang="' + wgUserVariant + '"]').addClass("mw-ui-progressive");
      top: 50%;
         $("#noteTA-lang-explainer").on("click", function() {
      left: 50%;
           //open(mw.config.get("wgServer") + mw.config.get("wgScriptPath") +,"_blank");
      transform: translate(-50%, -50%);
         }).hide();
     }
         $("#noteTA-lang-disable").on("click", function() {
 
           $("#noteTA-lang").remove();
     .widget-notification-config > .body fieldset {
           localStorage.setItem("AnnTools-noteTA-alert", "true");
      margin: 0;
         });
      padding-left: 15px;
      padding-right: 15px;
     }
 
     .widget-notification-config > .body .settings > label {
      display: block;
     }
 
     .widget-notification-config > .body .settings > label > * {
      vertical-align: middle;
     }
 
     .widget-notification-config > .body .settings textarea[name="excludeList"] {
      width: -webkit-fill-available;
      resize: none;
      margin-top: 5px;
      height: 100px;
      border: 1px #666 solid;
     }
    
     .widget-notification-config > .body .settings .buttonGroup {
      margin: 0 auto;
      margin-top: 10px;
      display: table;
     }
 
     .widget-notification-config > .body .settings .buttonGroup button {
      margin: 0 5px;
     }
    </style>
   `
 
   $('body').append(template).append(cssStyle)
 
   const rootEl = $('.widget-notification-config')
   const settingsEl = rootEl.find('.settings')
 
   // 注入按钮
   $('#p-cactions ul').append('<li id="widget-notification-showConfig"><a title="实时通知">实时通知</a></li>')
 
   // modal显示事件
   $('#widget-notification-showConfig').on('click', () => rootEl.show())
 
   // modal关闭事件
   rootEl.find('.closeModal').on('click', () => rootEl.hide())
 
   // 保存配置
   rootEl.find('.saveConfig').on('click', e => {
    const formValues = {
     enable: settingsEl.find('[name="enable"]').prop('checked'),
     listenNotification: settingsEl.find('[name="listenNotification"]').prop('checked'),
     excludeList: settingsEl.find('[name="excludeList"]').val().trim().split('\n')
    }
 
    onSaveConfig(formValues)
   })
 
   function updateConfig({ enable, listenNotification, excludeList }) {
    settingsEl.find('[name="enable"]').prop('checked', enable)
    settingsEl.find('[name="listenNotification"]').prop('checked', listenNotification)
    settingsEl.find('[name="excludeList"]').val(excludeList.join('\n'))
   }
 
   return {
    updateConfig
   }
  }
 
  function registerService() {
   return new Promise(async (resolve, reject) => {
    if (Notification === undefined || navigator.serviceWorker === undefined) {
     alert('当前浏览器不支持通知插件,请从您的用户页中移除!')
     return reject()
    }
   
    if(Notification.permission === 'default') {
     alert('点击确定关闭这条消息后,将弹出授予通知权限的窗口,届时请点击“允许”,以保证插件的正常运行。')
    }
  
    await new Promise(Notification.requestPermission)
    const status = Notification.permission
  
    if (status === 'granted') {
     if (localStorage.getItem('moegirl-widget-notification-permission-granted') !== 'true') {
      localStorage.setItem('moegirl-widget-notification-permission-granted', 'true')
      new Notification('欢迎', {
       body: '您已经成功开启实时通知功能,欢迎使用!',
       icon: notificationIcon
      })
     }
    }
  
    if (status === 'denied') {
     alert('您未能正确授予通知权限,若要继续使用,请在url栏左侧点击小锁标志开启权限,若无法设置,请从你的用户页删去此插件。')
     return reject()
    }
 
    const serviceWorkerRegistration = await navigator.serviceWorker.register(workerUrl)
    await navigator.serviceWorker.ready
    resolve(serviceWorkerRegistration.active)
   })
  }
 
  function checkNotificationPermission() {
   if (localStorage.getItem('moegirl-widget-notification-permission-granted') === 'true' && Notification.permission !== 'granted') {
    localStorage.removeItem('moegirl-widget-notification-permission-granted')
   }
  }
 
  class WorkerDataListener {
   broadcastName = ''
   worker = null
   data = null
   #incrementPullId = 0
 
   get pullEventName() { return 'get-' + this.broadcastName }
   get broadcastChannelName() { return 'channel-' + this.broadcastName }
  
   constructor(worker, broadcastName) {
    this.broadcastName = broadcastName
    this.worker = worker
    this.broadcastChannel = new BroadcastChannel(this.broadcastChannelName)
 
    this.addListener(data => this.data = data)
   }
 
   addListener(handler) {
    const usingHandler = e => {
     const { type, data, id } = e.data
     type === 'broadcast' && handler(data, id)
    }
 
    this.broadcastChannel.addEventListener('message', usingHandler)
    return () => this.broadcastChannel.removeEventListener('message', usingHandler)
   }
 
   pullData() {
    const pullId = this.#incrementPullId++
    this.worker.postMessage({ type: this.pullEventName, data: { id: pullId } })
    return pullId
   }
 
   getData() {
    return new Promise(resolve => {
     const pullId = this.pullData()
     const removeListener = this.addListener((data, id) => {
      if (id !== pullId) { return }
      resolve(data)
      removeListener()
     })
    })
   }
  }
})

2021年8月7日 (六) 11:26的版本

$(() => {
  const notificationIcon = 'https://img.moegirl.org.cn/common/thumb/f/f6/%E8%93%9D%E8%90%8C%E5%AD%97.png/233px-%E8%93%9D%E8%90%8C%E5%AD%97.png'
  const workerUrl = window.mw ?
	'/index.php?title=User:東東君/js/notification.js&action=raw&ctype=text/javascript' :
	'notification.js'
  
  checkNotificationPermission()
  main()
  
  async function main() {
    const worker = await registerService()
    const configListener = new WorkerDataListener(worker, 'config')
    const uiController = initUI({ onSaveConfig })
  
    configListener.pullData()

    configListener.addListener(data => {
      uiController.updateConfig(data)
    })
  
    function onSaveConfig(config) {
      worker.postMessage({ type: 'saveConfig', data: { config } })
      alert('配置已保存')
    }
  }

  navigator.serviceWorker.addEventListener('message', e => {
    const { type, data } = e.data
    if (type === 'sendNotification') {
      const [title, options] = data
      const link = options.data.link
      new Notification(title, options).onclick = () => window.open(link, '_blank')
    }
  })
  
  function initUI({ 
    onSaveConfig
  }) {
    const template = `
      <div class="widget-notification-config" style="display:none;">
        <div class="body">  
          <fieldset>
            <legend>设置</legend>
            <form class="settings" action="javascript:void(0)">
              <label>
                <span>开启</span>
                <input type="checkbox" name="enable">
              </label>
  
              <label>
                <div>排除条目:</div>
                <textarea placeholder="当其中的条目发生变化时不会通知,使用换行分割" name="excludeList"></textarea>
              </label>
  
              <div class="buttonGroup">
                <button class="saveConfig">保存</button>
                <button class="closeModal">关闭</button>
              </div>
            </form>
          </fieldset>
        </div>
      </div>
    `
  
    const cssStyle = `
      <style>
        .widget-notification-config {
          position: fixed;
          top: 0; 
          left: 0;
          right: 0;
          bottom: 0;
          background-color: rgba(0, 0, 0, 0.2);
          font-size: 14px;
          z-index: 100;
        }
  
        .widget-notification-config > .body {
          background-color: white;
          width: 300px;
          box-sizing: border-box;
          padding: 10px;
          border-radius: 5px;
          border: 2px #ccc ridge;
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
        }
  
        .widget-notification-config > .body fieldset {
          margin: 0;
          padding-left: 15px;
          padding-right: 15px;
        }
  
        .widget-notification-config > .body .settings > label {
          display: block;
        }
  
        .widget-notification-config > .body .settings > label > * {
          vertical-align: middle;
        }
  
        .widget-notification-config > .body .settings textarea[name="excludeList"] {
          width: -webkit-fill-available;
          resize: none;
          margin-top: 5px;
          height: 100px;
          border: 1px #666 solid;
        }
        
        .widget-notification-config > .body .settings .buttonGroup {
          margin: 0 auto;
          margin-top: 10px;
          display: table;
        }
  
        .widget-notification-config > .body .settings .buttonGroup button {
          margin: 0 5px;
        }
      </style>
    `
  
    $('body').append(template).append(cssStyle)
  
    const rootEl = $('.widget-notification-config')
    const settingsEl = rootEl.find('.settings')
  
    // 注入按钮
    $('#p-cactions ul').append('<li id="widget-notification-showConfig"><a title="实时通知">实时通知</a></li>')
  
    // modal显示事件
    $('#widget-notification-showConfig').on('click', () => rootEl.show())
  
    // modal关闭事件
    rootEl.find('.closeModal').on('click', () => rootEl.hide())
  
    // 保存配置
    rootEl.find('.saveConfig').on('click', e => {
      const formValues = {
        enable: settingsEl.find('[name="enable"]').prop('checked'),
        listenNotification: settingsEl.find('[name="listenNotification"]').prop('checked'),
        excludeList: settingsEl.find('[name="excludeList"]').val().trim().split('\n')
      }
  
      onSaveConfig(formValues)
    })
  
    function updateConfig({ enable, listenNotification, excludeList }) {
      settingsEl.find('[name="enable"]').prop('checked', enable)
      settingsEl.find('[name="listenNotification"]').prop('checked', listenNotification)
      settingsEl.find('[name="excludeList"]').val(excludeList.join('\n'))
    }
  
    return {
      updateConfig
    }
  }
  
  function registerService() {
    return new Promise(async (resolve, reject) => {
      if (Notification === undefined || navigator.serviceWorker === undefined) {
        alert('当前浏览器不支持通知插件,请从您的用户页中移除!')
        return reject()
      }
      
      if(Notification.permission === 'default') {
        alert('点击确定关闭这条消息后,将弹出授予通知权限的窗口,届时请点击“允许”,以保证插件的正常运行。')
      }
    
      await new Promise(Notification.requestPermission)
      const status = Notification.permission
    
      if (status === 'granted') {
        if (localStorage.getItem('moegirl-widget-notification-permission-granted') !== 'true') {
          localStorage.setItem('moegirl-widget-notification-permission-granted', 'true')
          new Notification('欢迎', {
            body: '您已经成功开启实时通知功能,欢迎使用!',
            icon: notificationIcon
          })
        }
      }
    
      if (status === 'denied') {
        alert('您未能正确授予通知权限,若要继续使用,请在url栏左侧点击小锁标志开启权限,若无法设置,请从你的用户页删去此插件。')
        return reject()
      }
  
      const serviceWorkerRegistration = await navigator.serviceWorker.register(workerUrl)
      await navigator.serviceWorker.ready
      resolve(serviceWorkerRegistration.active)
    })
  }

  function checkNotificationPermission() {
    if (localStorage.getItem('moegirl-widget-notification-permission-granted') === 'true' && Notification.permission !== 'granted') {
      localStorage.removeItem('moegirl-widget-notification-permission-granted')
    }
  }
  
  class WorkerDataListener {
    broadcastName = ''
    worker = null
    data = null
    #incrementPullId = 0

    get pullEventName() { return 'get-' + this.broadcastName }
    get broadcastChannelName() { return 'channel-' + this.broadcastName }
    
    constructor(worker, broadcastName) {
      this.broadcastName = broadcastName
      this.worker = worker
      this.broadcastChannel = new BroadcastChannel(this.broadcastChannelName)
  
      this.addListener(data => this.data = data)
    }
  
    addListener(handler) {
      const usingHandler = e => {
        const { type, data, id } = e.data
        type === 'broadcast' && handler(data, id)
      }

      this.broadcastChannel.addEventListener('message', usingHandler)
      return () => this.broadcastChannel.removeEventListener('message', usingHandler)
    }
  
    pullData() {
      const pullId = this.#incrementPullId++
      this.worker.postMessage({ type: this.pullEventName, data: { id: pullId } })
      return pullId
    }
  
    getData() {
      return new Promise(resolve => {
        const pullId = this.pullData()
        const removeListener = this.addListener((data, id) => {
          if (id !== pullId) { return }
          resolve(data)
          removeListener()
        })
      })
    }
  }
})