Skip to content

Instantly share code, notes, and snippets.

@cho45
Created February 27, 2011 13:05
Show Gist options
  • Save cho45/846162 to your computer and use it in GitHub Desktop.
Save cho45/846162 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Hatena::Diary: for writing
// @namespace http://lowreal.net/
// @include http://d.hatena.ne.jp/*gihyo/*
// @require https://gist.github.com/3239.txt#createElementFromString
// @require https://gist.github.com/3238.txt#$X
// @require https://github.com/cho45/jsdeferred/raw/master/jsdeferred.userscript.js
// ==/UserScript==
// つかいかた:
//
// gist で private gist を作る。
// はてダ詳細編集ページにいき、任意の日付で
//
// https://gist.github.com/xxxxxxxxxxxxxxxxxxxx
//
// *
// foobar
//
// とテキストエリアに入力し、保存。
// その後はその場編集モードで保存を押すたびに、gist に日付をファイル名にしてバックアップがつくられる
//
// はてなダイアリーの仕様上、1章ごとに日付を分けたほうが無難です。長く書きすぎて溢れると書いた内容が消えます。
//
(function () { with (D()) {
function retrieveDiaryContent (user, date) {
var edit = '/' + user + '/edit?date=' + date;
return http.get(edit).next(function (r) {
var m = r.responseText.match(/<textarea name="body"[\s\S]*<\/textarea>/);
if (!m) throw "can't retrieve edit body";
var div = document.createElement('div');
div.innerHTML = m[0];
var v = div.getElementsByTagName('textarea')[0].value;
return v;
});
}
function updateGist (id, filename, content) {
var d = new Deferred();
xhttp.get('https://gist.github.com/gists/' + id + '/edit').next(function (r) {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
iframe.contentDocument.writeln("<body></body>");
var form = r.responseText.match(/<form action="\/gists\/\d+[\s\S]*<\/form>/);
var div = iframe.contentDocument.createElement('div');
div.innerHTML = form;
var form = div.getElementsByTagName('form')[0];
var name = 'file_contents[' + filename + ']';
var textarea = $X('.//textarea[@name="' + name + '"]', form)[0];
if (!textarea) {
var input = iframe.contentDocument.createElement('input');
input.name = 'file_name[' + filename + ']';
input.value = filename;
form.appendChild(input);
textarea = iframe.contentDocument.createElement('textarea');
textarea.name = name;
form.appendChild(textarea);
}
form.action = 'https://gist.github.com' + form.getAttribute('action');
textarea.value = content;
iframe.contentDocument.body.appendChild(form);
iframe.addEventListener('load', function () {
setTimeout(function () {
document.body.removeChild(iframe);
iframe.removeEventListener('load', arguments.callee, false);
d.call();
}, 1000);
}, false);
form.submit();
}).
error(function (e) {
d.fail(e);
});
return d;
}
var counters = [];
var updateCounter = (function () {
var CPP = 1932; // WEB+DB full
var CPP_ = 1200;
var test = document.createElement('div');
test.appendChild(document.createTextNode(new Array(CPP+1).join('あ')));
var sections = document.querySelectorAll('#days .section');
// 実際に文字数分突っ込んで高さを計測する
sections[0].appendChild(test);
var HPP = test.offsetHeight;
sections[0].removeChild(test);
for (var i = 0, it; it = counters[i]; i++) {
it.parentNode.removeChild(it);
}
counters = [];
var height = 0;
var overall = 0;
for (var i = 0, it; it = sections[i]; i++) {
var header = it.getElementsByTagName('h3')[0];
if (!header) continue;
var count = $X('string(.)', it, String).length;
var counter = createElementFromString('<span> #{count}文字/#{pagex}-#{page}ページ</span>', {
data : { count : count, pagex : (count / CPP_).toFixed(1), page :(it.offsetHeight / HPP).toFixed(1)}
} );
header.appendChild(counter);
height += it.offsetHeight;
overall += count;
counters.push(counter);
}
var counter = createElementFromString('<div style="position:fixed;bottom:0;right:0;color:#fff;background:rgba(0,0,0,0.5);padding:1em;">' +
'#{count}文字/#{pagex}-#{page}ページ' +
'</div>', { data : { count : overall, pagex: (overall / CPP_).toFixed(1) ,page: (height / HPP).toFixed(1) } });
document.body.appendChild(counter);
counters.push(counter);
return arguments.callee;
})();
var orig = unsafeWindow.Hatena.Diary.EditInPlace.Form.prototype.completeSubmission;
unsafeWindow.Hatena.Diary.EditInPlace.Form.prototype.completeSubmission = function () {
orig.apply(this, arguments);
var date = this.section.date;
if (!date) return;
var user = unsafeWindow.Hatena.DiaryName.name;
updateCounter();
if (document.body.innerHTML.match(/https:\/\/gist.github.com\/([0-9a-f]+)/)) {
var gistid = RegExp.$1;
retrieveDiaryContent(user, date).
next(function (value) {
return updateGist(gistid, date + '.txt', value);
}).
next(function () {
console.log('done');
}).
error(function (e) {
alert(e);
});
}
};
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment