12 posts tagged “vox”
Noticed that Vox Editing with WYSIWYG or HTML alternately does not work now. Fixed to follow a change of the JS (command translation rule: prev: command-fooBar -> fooBar now: command-foo-bar -> fooBar). But also I noticed it does not work on Firefox3 b3... or more like, Firefox3 b3 does not work fine for content-editable iframe... I'm looking for next beta.
Vox does not provide uploading tools except XP. So I wrote a script to upload photos to Vox.
- vox-upload-photo.rb (requires rubygems, mechanize, hpricot)
Vox also does not provide any public APIs. This script use the interface used by XP wizard.
I think that the script should have good GUI and Finder integration but didn't make it because I have no idea to implement it. (Automator with RubyCocoa...?)
Updated:
Sorry. Vox provides API with Atom Publishing Protocol (RFC5023). Uploading like this (Atom + Basic Auth + base64) succeeds. (this atom api is in time of draft?)
Updated:
I tried Atom/AtomPub library in Ruby atomutil (great library, Atom 1.0 compatible) and write a sample code but this does not work... Server returns 500 ( Can't call method "filename" on an undefined value at /home/comet/release-40.5/vox/lib/Vox/App/C/Atom/Asset.pm line 195. and stack trace)... I can't find differences between raw-atom and atomutil....
I updated Vox Editing with WYSIWYG or HTML alternately userscript. Now, this script just insert a button to toolbar of the composing view to run the command which is already defined in Vox JS.
Ref. Editing with WYSIWYG or HTML alternately.
Updated: Added to userscripts.org http://userscripts.org/scripts/show/17963. I'm lazy to update scripts on userscripts.org... I hope that userscripts.org updates from subversion automatically or by one-click. (updated: wrote a script...)
NUMBER GIRL is dismissed Japanese rock band. Their songs are so stoic and emotional at same time. Some of its represent sentimental emotions which is in everybody. Some of its represent social problems with many metaphor. Some of its represent the days of routine are not bad.
Of them, I love OMOIDE IN MY HEAD.
I wrote a greasemonkey script for using hatena notation at composing. Maybe this is no use.
Issues:
- pre kihou (>|| .. ||<) will be broken because Vox indents all elements.
- The original text is saved as hidden p element. This is so ugly implement. But it seems like Vox strips all comments (I first implemented with comment (<!-- -->). So I have no idea without it...
voxeditingwithtexthatena.user.js
Uses text-hatena.js for parsing. Using Markdown syntax may be easy, bacause it has javascript implementation.
Uh, I will not use this.
Vox ではてな記法を使う Greasemonkey スクリプトを書いてみました。全然使えませんが。
- pre 記法は Vox がインデントを行うため崩れます。
- オリジナルのテキストを display: none な p 要素に base64 して突っ込むため美しくないです。もともとコメントとして挿入する実装にしようと思って試したのですが、保存されなかったのでこうなってます。何かいい方法ないかな。
おれはつかわない!
I noticed Vox can link to (import from) Flickr photos directly just now... I have cross uploaded some photos to Vox and Flickr. I blew it.
But, Flickr restricts bandwidth to 100MB/month. Vox allows 2G/month. I'm torn about which I upload.
Update:
This script is now committed in CodeRepos: http://coderepos.org/share/browser/lang/javascript/userscripts/voxeditingwithwysiwygorh.user.js
I wrote a greasemonkey script for editting HTML directly on Vox composing view.
I'm sometimes not able to edit with WYSIWYG smartly. In a case like that, I want to edit HTML directly.
// ==UserScript==
// @name Vox Editing with WYSIWYG or HTML alternately
// @namespace http://lowreal.net/
// @include http://www.vox.com/compose*
// ==/UserScript==
(function () {
var iframe = $X('//iframe[contains(@src, "editor-content.html")]')[0];
var textarea = $N('textarea', {
cols:'30',
rows:'10',
style: <>
width : {iframe.offsetWidth + 'px'};
height : {iframe.offsetHeight + 'px'};
display : none;
background : #eee;
z-index : 500;
</>.replace(/\n/g, ''),
}, 'test');
iframe.parentNode.insertBefore(textarea, iframe);
var toggle = $N('div', {
style: <>
width: 3em;
text-align: center;
margin: 0.5em 0 -0.5em 0;
padding: 0 0.5em;
background: #000;
color: #fff;
z-index: 999;
</>.replace(/\n/g, '')
}, 'Toggle');
toggle.addEventListener('click', function (e) {
if (iframe.style.display == 'none') {
iframe.style.display = 'block';
textarea.style.display = 'none';
iframe.contentDocument.body.innerHTML = textarea.value;
} else {
iframe.style.display = 'none';
textarea.style.display = 'block';
textarea.value = iframe.contentDocument.body.innerHTML;
}
}, false);
var area = document.getElementById('compose-entry');
area.parentNode.insertBefore(toggle, area);
/* template functions */
function log () {
var c = unsafeWindow.console;
if (c) c.log.apply(c, arguments);
}
function $N(name, attr, childs) {
var ret = document.createElement(name);
for (k in attr) {
if (!attr.hasOwnProperty(k)) continue;
v = attr[k];
if (k == "class") {
ret.className = v;
} else {
ret.setAttribute(k, v);
}
}
switch (typeof childs) {
case "string": {
ret.appendChild(document.createTextNode(childs));
break;
}
case "object": {
for (var i = 0, len = childs.length; i < len; i++) {
var child = childs[i];
if (typeof child == "string") {
ret.appendChild(document.createTextNode(child));
} else {
ret.appendChild(child);
}
}
break;
}
}
return ret;
}
function $X(exp, context) {
if (!context) context = document;
var resolver = function (prefix) {
var o = document.createNSResolver(context)(prefix);
return o ? o : (document.contentType == "text/html") ? "" : "http://www.w3.org/1999/xhtml";
}
var exp = document.createExpression(exp, resolver);
var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
switch (result.resultType) {
case XPathResult.STRING_TYPE : return result.stringValue;
case XPathResult.NUMBER_TYPE : return result.numberValue;
case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
result = exp.evaluate(context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var ret = [];
for (var i = 0, len = result.snapshotLength; i < len ; i++) {
ret.push(result.snapshotItem(i));
}
return ret;
}
}
return null;
}
})();
を作ろうと思ったのだけど、greasemonkey スクリプト内に text-hatena.js をコピペしたところ Compose 画面で Fx が瞬間で落ちるようになってしまったので断念した。いろいろ考えられる理由がありすぎて原因を追うのが面倒くさい。毎回再起動しないといけない。
でもってそれは諦めて、常に iframe 内の innerHTML をいぢれるように textarea を配置してみたのだけど、iframe の上に textarea をおくとキャレットが表示されなくなってしまって使えない (OS X, Fx2.0)。回避法を模索中
それと、pre でソースコード挿入するとき、シンタックスハイライトをしようと思って昔作ったやつをひっぱりだしたけど、UI 実装するのが面倒くさくてまだやっていない。Vox の JS は圧縮されて読みにくいので自己実装したほうがはやいのだけど、それだと UI がちょっと変わってキモイのでどうしようとかいう悩み。
頭使わないで書くというアレが崩れそうなので深入りしないようにしよう。
After reading 【Vox使い方講座】アカウント設定で世界旅行!, you may want to change the language setting more easily.
I wrote a greasemonkey script for changing the setting on one click.
// ==UserScript==
// @name Vox Change Lang on one click
// @namespace http://lowreal.net/
// @include http://*.vox.com/*
// @exclude http://*.vox.com/*editor-content.html
// ==/UserScript==
(function () {
const SHOW_LANGS = [
'en',
'fr',
'ja',
];
var area = $N('div', {
style: [
'position: absolute',
'top: 0',
'right: 0',
'background: #000',
'color: #fff',
'padding: 0.2em 1em',
'font-size: 14px',
].join(';')
});
SHOW_LANGS.forEach(function (l) {
var ll = $N('a', {
href:'javascript:void("fumino")',
style: 'color: #fff',
}, l);
ll.addEventListener('click', function (e) {
set_lang(l);
}, false);
area.appendChild(ll);
area.appendChild(document.createTextNode(' '));
});
document.body.appendChild(area);
function params2data(params) {
var data = [];
for (name in params) {
if (!params.hasOwnProperty(name)) continue;
if (!name) continue;
params[name].forEach(function (i) {
data.push(name+'='+encodeURIComponent(i));
});
}
log(data);
data = data.join('&');
return data;
}
function set_lang(lang) {
log('set lang to ' + lang);
GM_xmlhttpRequest({
method: "GET",
url: 'http://www.vox.com/account/info',
onload: function (req) {
var t = $N('div');
t.innerHTML = req.responseText;
var params = {};
['input', 'select', 'textarea'].forEach(function (i) {
$X('.//form[@id="account-info"]//'+i, t).forEach(function (i) {
var name = i.name;
var value = i.value;
if (!params[name]) params[name] = [];
params[name].push(value);
});
});
params['locale'] = [lang];
delete params['cancel'];
log('%.o', params);
var data = params2data(params);
GM_xmlhttpRequest({
method: "POST",
url: 'http://www.vox.com/account/info',
headers : {
"Content-Type":"application/x-www-form-urlencoded"
},
data: data,
onload: function (req) {
location.reload();
}
});
}
});
}
/* template functions */
function log () {
var c = unsafeWindow.console;
if (c) c.log.apply(c, arguments);
}
function $N(name, attr, childs) {
var ret = document.createElement(name);
for (k in attr) {
if (!attr.hasOwnProperty(k)) continue;
v = attr[k];
if (k == "class") {
ret.className = v;
} else {
ret.setAttribute(k, v);
}
}
switch (typeof childs) {
case "string": {
ret.appendChild(document.createTextNode(childs));
break;
}
case "object": {
for (var i = 0, len = childs.length; i < len; i++) {
var child = childs[i];
if (typeof child == "string") {
ret.appendChild(document.createTextNode(child));
} else {
ret.appendChild(child);
}
}
break;
}
}
return ret;
}
function $X(exp, context) {
if (!context) context = document;
var resolver = function (prefix) {
var o = document.createNSResolver(context)(prefix);
return o ? o : (document.contentType == "text/html") ? "" : "http://www.w3.org/1999/xhtml";
}
var exp = document.createExpression(exp, resolver);
var result = exp.evaluate(context, XPathResult.ANY_TYPE, null);
switch (result.resultType) {
case XPathResult.STRING_TYPE : return result.stringValue;
case XPathResult.NUMBER_TYPE : return result.numberValue;
case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: {
result = exp.evaluate(context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var ret = [];
for (var i = 0, len = result.snapshotLength; i < len ; i++) {
ret.push(result.snapshotItem(i));
}
return ret;
}
}
return null;
}
})();
This shows language links on right-top of your window. (after clicked the link, wait for reloading)
タグを書くと保存時に訊いてくれるんだ。試してみれば良かった!!!