Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save appetizermonster/392d00ad336870896507d7aec1ea5a23 to your computer and use it in GitHub Desktop.
Save appetizermonster/392d00ad336870896507d7aec1ea5a23 to your computer and use it in GitHub Desktop.
A Tampermonkey Script for Bitbucket Wiki Editor Extensions
// ==UserScript==
// @name Bitbucket Wiki Editor Extensions
// @namespace http://tampermonkey.net/
// @version 0.0.3
// @downloadURL https://gist.github.com/appetizermonster/392d00ad336870896507d7aec1ea5a23/raw/Bitbucket%2520Wiki%2520Editor%2520Extensions.user.js
// @updateURL https://gist.github.com/appetizermonster/392d00ad336870896507d7aec1ea5a23/raw/Bitbucket%2520Wiki%2520Editor%2520Extensions.user.js
// @description Bitbucket Wiki Editor Extensions
// @author Heejin Lee
// @include https://bitbucket.org/*/wiki/edit/*
// @include https://bitbucket.org/*/wiki/create
// @include https://bitbucket.org/*/wiki/create/*
// @resource toastCss https://cdnjs.cloudflare.com/ajax/libs/jquery-toast-plugin/1.3.1/jquery.toast.min.css
// @require https://code.jquery.com/jquery-2.2.4.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery-toast-plugin/1.3.1/jquery.toast.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/chance/1.0.6/chance.min.js
// @grant GM_addStyle
// @grant GM_getResourceText
// ==/UserScript==
// This script currently only supports uploading image from clipboard.
const toastCss = GM_getResourceText('toastCss');
GM_addStyle(toastCss);
(function () {
'use strict';
console.log('%c + Bitbucket Wiki Editor Extensions by Heejin Lee ', 'background: #eae; color: #aa00aa');
const textEditor = document.getElementById('id_data');
_injectClipboardExtension(textEditor);
})();
function _injectClipboardExtension(textEditor) {
console.log('trying to inject clipboard extension');
textEditor.addEventListener('paste', _handleClipboardEvent);
}
let lastPasteTime_ms = 0;
function _handleClipboardEvent(e) {
const items = e.clipboardData.items;
for (let item of items) {
const isPngImage = item.type.indexOf('image/png') >= 0;
if (!isPngImage)
continue;
const elapsedFromLast_ms = Date.now() - lastPasteTime_ms;
if (elapsedFromLast_ms <= 3000) {
$.toast({
text: 'I believe you need some a break',
icon: 'warning',
stack: false
});
return;
}
_uploadImage(item.getAsFile(), chance.first() + '.png');
lastPasteTime_ms = Date.now();
}
}
function _uploadImage(file, filename) {
const formData = new FormData();
const originalForm = _parseOriginalFormData();
formData.append('csrfmiddlewaretoken', originalForm.csrfToken);
formData.append('file', file, filename);
const toast = $.toast({
text: 'Uploading Image...',
hideAfter: false,
allowToastClose: false
});
const xhr = new XMLHttpRequest();
xhr.open('POST', originalForm.action);
xhr.onload = function (e) {
const isFailure = (xhr.status !== 200);
// Close toast automatically after 1 sec
window.setTimeout(() => toast.reset(), 1000);
if (isFailure) {
toast.update({
text: 'Something went wrong',
icon: 'error',
allowToastClose: true
});
return;
}
const res = JSON.parse(xhr.response);
const _filename = res.filename;
const _href = res.href;
const pasteTemplate = '![%filename%](%href%)';
const pasteText = pasteTemplate.replace('%filename%', _filename).replace('%href%', _href);
_insertTextIntoTextEditor(pasteText);
toast.update({
text: 'Success',
icon: 'success',
allowToastClose: true
});
};
xhr.send(formData);
}
function _parseOriginalFormData() {
const formTemplate = document.getElementById('image-upload-template').text;
const action_regex = /action="(\S+)"/gi;
const csrfToken_regex = /csrfmiddlewaretoken' value='(\S+)' \/>/gi;
return {
action: action_regex.exec(formTemplate)[1],
csrfToken: csrfToken_regex.exec(formTemplate)[1]
};
}
function _insertTextIntoTextEditor(insertText) {
const textEditor = document.getElementById('id_data');
const startPos = textEditor.selectionStart;
const endPos = textEditor.selectionEnd;
const oldText = textEditor.value;
const newText = oldText.substring(0, startPos) + insertText + oldText.substring(endPos, oldText.length);
textEditor.value = newText;
const newStartPos = startPos + insertText.length;
textEditor.selectionStart = newStartPos;
textEditor.selectionEnd = newStartPos;
}
@appetizermonster
Copy link
Author

현재 이미지 붙여넣기로 생성된 텍스트는 실행 취소가 안되는 문제가 있음

@appetizermonster
Copy link
Author

auto-save

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment