둘러보기 메뉴
검색
바뀐글
임의글
개인 도구
가입하기
로그인
도움말
도움말
질문게시판
자주 묻는 질문
커뮤니티
실시간 채팅방
가입인사게시판
자유게시판
뉴스게시판
제재안게시판
최근 토론
페미위키
공지사항
개선 요청
바뀐글
임의글
파일 올리기
다면 분류 목록
특수 문서 목록
소도구:tweetbot-quick-editor.js 문서 원본 보기
이름공간
소도구
토론
주시
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
문서 정보
위키베이스 항목
행위
보기
읽기
원본 보기
역사 보기
←
소도구:tweetbot-quick-editor.js
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요.
요청한 명령은 다음 중 하나의 권한을 가진 사용자에게 제한됩니다:
사용자
,
Seeders
.
소도구
이름공간의 문서를 편집할 권한이 없습니다.
문서를 고치려면 이메일 인증 절차가 필요합니다.
사용자 환경 설정
에서 이메일 주소를 입력하고 이메일 주소 인증을 해주시기 바랍니다.
문서의 원본을 보거나 복사할 수 있습니다.
// <nowiki> // @todo api.get을 호출하면 소요되는 시간 동안 문서 내용이 바뀔 수 있음. (function (mw, $) { 'use strict'; /** * "==[[페미니즘]]=="과 같은 문자열에서 "페미니즘"을 가져오기 위한 정규식. * @constant * @type {RegExp} */ var SECTION_TITLE_REGEXP = /^=+\s*\[\[([^=\]\[]+)\]\]\s*=+$/; /** * 한줄인용이 저장되는 문서 이름. * @constant * @type {string} */ var DATA_TITLE = '페미위키:한줄인용'; /** * 링크로 포함할 문서 이름, 예를 들어 "페미니즘은 이런 저런 것이다."라는 트윗에 페미니즘 문서로 링크를 건다면 "페미니즘" * @type {string} */ var linkArticle; /** * @type {object} */ var cache = { revId: null, wikitext: null, sectionId: null, sectionWikitext: null, }; /** * @type {mw.Api} */ var api; /** * @type {TweetbotQuickEditor} */ var tweetbotQuickEditor; function main() { if (mw.config.get('wgAction') != 'view') { return; } mw.user.getRights().then(function (rights) { if (rights.indexOf('edit') < 0) { return; } linkArticle = mw.config.get('wgPageName').replace(/_/g, ' '); api = new mw.Api(); // 메뉴에 한줄인용 버튼 추가 $( mw.util.addPortletLink( 'p-cactions', mw.util.getUrl(DATA_TITLE), '한줄인용', 'p-tweetbot', '이 문서에 대한 한줄인용을 편집합니다.' ) ).on('click', onClickPortletLink); }); } /** * @param {Event} event */ function onClickPortletLink(event) { event.preventDefault(); if (!cache.revId) { // [[페:한줄인용]]]을 가져옵니다. api .get({ action: 'parse', page: DATA_TITLE, prop: 'revid|wikitext', }) .then(function (data) { storeCache({ revId: data.parse.revid, wikitext: data.parse.wikitext['*'], sectionId: null, sectionWikitext: null, }); findSectionIdAndOpenEditor(); }); return; } // 저장된 것보다 더 최신인 리비전이 있는지 확인합니다. api .get({ action: 'parse', page: DATA_TITLE, prop: 'revid', }) .then(function (data) { if (cache.revId == data.parse.revid && cache.sectionWikitext) { openEditor(cache.sectionWikitext); return; } api .get({ action: 'parse', page: DATA_TITLE, prop: 'wikitext', }) .then(function (data) { storeCache({ wikitext: data.parse.wikitext['*'], sectionId: null, sectionWikitext: null, }); findSectionIdAndOpenEditor(); }); }); } /** * * @param {object} newer */ function storeCache(newer) { var givenKeys = ['revId', 'wikitext', 'sectionId', 'sectionWikitext']; for (var key in newer) { if (givenKeys.indexOf(key) < 0) { console.error('invaild key ' + key + ' is used'); return; } cache[key] = newer[key] === null ? null : newer[key]; } } /** * */ function findSectionIdAndOpenEditor() { // 현재 보고 있는 문서에 대해 이미 작성된 한줄인용이 있는지 검사합니다. if (findSectionId()) { api .get({ action: 'parse', page: DATA_TITLE, section: cache.sectionId, prop: 'wikitext', }) .then(function (data) { storeCache({ sectionWikitext: data.parse.wikitext['*'], }); openEditor(cache.sectionWikitext); }); } else { OO.ui .confirm( linkArticle + ' 문서에 대한 한줄인용이 아직 없습니다. 추가하시겠습니까?' ) .done(function (confirmed) { if (confirmed) { openEditor('== [[' + linkArticle + ']] ==\n* '); } }); } } /** /* 현재 보고 있는 문서에 대해 이미 작성된 한줄인용이 있는지 검사합니다. */ function findSectionId() { var found = cache.wikitext.match( new RegExp( '^=+\\s*\\[\\[' + linkArticle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '\\]\\]\\s*=+$', 'm' ) ) !== null; if (found) { var titles = cache.wikitext .match(new RegExp(SECTION_TITLE_REGEXP, 'gm')) .map(function (line) { return line.match(new RegExp(SECTION_TITLE_REGEXP, 'm'))[1]; }); // sectionId는 0이 도입부이고 제목이 있는 문단은 1부터 시작합니다. storeCache({ sectionId: titles.indexOf(linkArticle) + 1, }); } return found; } /** * @param text */ function openEditor(text) { var wm = OO.ui.getWindowManager(); var editor = getTweetbotQuickEditor(); if (!wm.hasWindow(editor)) { wm.addWindows([editor]); } wm.openWindow(editor, { text: text, }); } /** * @return {TweetbotQuickEditor} */ function getTweetbotQuickEditor() { if (tweetbotQuickEditor === undefined) { tweetbotQuickEditor = new TweetbotQuickEditor(); } return tweetbotQuickEditor; } /** * 트윗을 편집하는 편집기. * * @class TweetbotQuickEditor */ function TweetbotQuickEditor(config) { TweetbotQuickEditor.super.call(this, config); } OO.inheritClass(TweetbotQuickEditor, OO.ui.ProcessDialog); TweetbotQuickEditor.static.name = 'TweetbotQuickEditor'; TweetbotQuickEditor.static.actions = [ { flags: ['primary', 'progressive', 'disabled'], label: '완료', action: 'publish', }, { flags: 'safe', label: '취소' }, ]; TweetbotQuickEditor.prototype.initialize = function () { TweetbotQuickEditor.super.prototype.initialize.call(this); this.panel = new OO.ui.PanelLayout({ padded: true, expanded: false, }); this.content = new OO.ui.FieldsetLayout(); this.editor = new OO.ui.MultilineTextInputWidget({ autosize: true, }); this.field = new OO.ui.FieldLayout(this.editor, { label: '아래 내용을 수정하고 완료를 누르세요.', align: 'top', }); this.content.addItems([this.field]); this.panel.$element.append(this.content.$element); this.$body.append(this.panel.$element); this.editor.connect(this, { change: 'onInputChange', }); }; TweetbotQuickEditor.prototype.getReadyProcess = function (data) { return TweetbotQuickEditor.super.prototype.getReadyProcess .call(this, data) .next(function () { this.editor.moveCursorToEnd(); }, this); }; TweetbotQuickEditor.prototype.onInputChange = function (value) { this.actions.setAbilities({ publish: value.length !== 0 && value !== cache.sectionWikitext, }); }; TweetbotQuickEditor.prototype.getBodyHeight = function () { return this.panel.$element.outerHeight(true); }; TweetbotQuickEditor.prototype.getSetupProcess = function (data) { data = data || {}; return TweetbotQuickEditor.super.prototype.getSetupProcess .call(this, data) .next(function () { this.editor.setValue(data.text); }, this); }; TweetbotQuickEditor.prototype.getActionProcess = function (action) { var dialog = this; var editorText = this.editor.getValue(); if (action != 'publish') return TweetbotQuickEditor.super.prototype.getActionProcess.call( this, action ); return new OO.ui.Process(function () { api .get({ action: 'parse', page: DATA_TITLE, prop: 'revid', }) .then(function (data) { if (cache.revId == data.parse.revid) { if (cache.sectionId) { edit(cache.sectionId, editorText); storeCache({ sectionWikitext: editorText, }); } else { findAndAppend(editorText); } dialog.close({ action: action }); return; } // wikitext를 가져왔을 때의 revId와 지금의 revId가 다르다면 충돌이 일어나지 않았는지 확인 api .get({ action: 'parse', page: DATA_TITLE, prop: 'wikitext', }) .then(function (data) { storeCache({ revId: data.parse.revid, wikitext: data.parse.wikitext['*'], }); // 문단이 있는지 검사 if (findSectionId()) { // 문단이 원래부터 있었거나, 없다가 생겼다면 충돌 검사 후 저장 api .get({ action: 'parse', page: DATA_TITLE, section: cache.sectionId, prop: 'wikitext', }) .then(function (data) { var sectionWikitext = data.parse.wikitext['*']; if (sectionWikitext == cache.sectionWikitext) { // 기존 내용과 같다면 편집 충돌이 없으므로 저장 edit(sectionId, editorText); storeCache({ wikitext: null, sectionWikitext: editorText, }); dialog.close({ action: action }); return; } // 충돌이므로 덮어 쓸 것인지 질문 // @todo diff 보이기 OO.ui .confirm( '작성하는 동안 다른 편집이 있었습니다. 무시하고 덮어 쓰시겠습니까?' ) .done(function (confirmed) { if (confirmed) { edit(cache.sectionId, editorText); storeCache({ sectionWikitext: editorText, }); dialog.close({ action: action }); } }); }); return; } // 문단이 원래부터 없었거나, 있다가 없어졌다면 새 문단으로 추가 api .get({ action: 'parse', page: DATA_TITLE, section: findSectionIdToInsert(), prop: 'wikitext', }) .then(function (data) { edit(id, data.parse.wikitext['*'] + '\n\n' + editorText); storeCache({ wikitext: null, sectionId: cache.sectionId + 1, sectionWikitext: editorText, }); dialog.close({ action: action }); }); }); }); }, this); }; function findAndAppend(wikitext) { var idToInsert = findSectionIdToInsert(); api .get({ action: 'parse', page: DATA_TITLE, section: idToInsert, prop: 'wikitext', }) .then(function (data) { edit(idToInsert, data.parse.wikitext['*'] + '\n\n' + wikitext); storeCache({ sectionId: idToInsert + 1, sectionWikitext: wikitext, }); }); } /** * 이 문서에 대한 한줄인용이 아직 없을 때 사전 순서 그 이전 문단 번호를 반환. */ function findSectionIdToInsert() { var titles = cache.wikitext .match(new RegExp(SECTION_TITLE_REGEXP, 'gm')) .map(function (line) { return line .match(new RegExp(SECTION_TITLE_REGEXP, 'm'))[1] .replace(' ', ''); }); var _linkArticle = linkArticle.replace(' ', ''); var id; for (id = 0; id < titles.length; id++) { if (titles[id].localeCompare(_linkArticle, 'ko') > 0) { break; } } return id; } /** * * @param {string} text */ function edit(sectionId, text) { api .edit(DATA_TITLE, function (revision) { return { section: sectionId, summary: '/*' + linkArticle + '*/', text: text, tags: 'fw-tweetbot-quick-editor', }; }) .then( function () { mw.notify('저장되었습니다.'); storeCache({ revId: null, wikitext: null, }); }, function (error) { mw.notify(error.message); } ); } main(); // </nowiki> })(mediaWiki, jQuery);
소도구:tweetbot-quick-editor.js
문서로 돌아갑니다.
다른 언어