From Chickenfoot Script Repository
include('google-docs-ui.js');
go('about:blank');
goog.require('goog.dom');
goog.require('goog.dom.classes');
goog.require('goog.dom.selection');
goog.require('goog.events.KeyCodes');
goog.require('goog.events.KeyHandler');
goog.require('goog.events.KeyHandler.EventType');
goog.require('goog.string');
goog.require('goog.style');
var dom = new goog.dom.DomHelper(document);
/**
* Finds all elements with the "editable" class and sets content-editable to
* true. Adds a key handler to these editable elements and inserts CSS to
* style the document appropriately.
* @param {function} saveFn
* @param {Document} doc
*/
function makeDivsContentEditable(saveFn, doc) {
var divs = doc.querySelectorAll('.editable');
for (var i = 0; i < divs.length; ++i) {
var div = divs[i];
div.contentEditable = true;
var html = div.innerHTML;
html = goog.string.trim(html);
div.innerHTML = html;
}
var keyHandlerEl = doc.body;
var keyHandler = new goog.events.KeyHandler(keyHandlerEl);
goog.events.listen(keyHandler,
goog.events.KeyHandler.EventType.KEY,
goog.partial(onKeyEvent, saveFn));
var stylesString = 'body { font-family: Arial; font-size: 13px }' +
'.editable { padding-bottom: 8px; outline: none }' +
'.source-code { color: green; font-family: Courier; white-space: pre}';
goog.style.installStyles(stylesString, doc.body);
}
/**
* @param {Element} contentEditableDiv
* @return {number}
*/
function getCursorPosition(contentEditableDiv) {
var dom = goog.dom.getDomHelper(contentEditableDiv);
var win = dom.getWindow();
var selection = win.getSelection();
// This assumes the selection is always inside a text node and that the
// contentEditableDiv's only child is that text node.
return selection.anchorOffset;
}
/**
* Handles a key event in the editor.
* @param {function} saveFn
* @param {goog.events.KeyEvent} e
*/
function onKeyEvent(saveFn, e) {
var keyCode = e.keyCode;
var contentEditableDiv = e.target;
var cursorPosition = getCursorPosition(contentEditableDiv);
output('keyCode: ' + e.keyCode + '; cursorPos: ' + cursorPosition);
var textNode = contentEditableDiv.firstChild;
if (textNode.nodeType != goog.dom.NodeType.TEXT) {
output('Not a text node: ' + textNode);
return;
}
if (keyCode == goog.events.KeyCodes.ENTER) {
// ctrl-enter toggles between source-code and text.
if (e.ctrlKey) {
e.preventDefault();
goog.dom.classes.toggle(contentEditableDiv, 'source-code');
return;
}
// enter at the end of the line creates a new paragraph.
if (textNode.nodeValue.length == cursorPosition) {
output('NEW LINE!');
e.preventDefault();
var dom = goog.dom.getDomHelper(contentEditableDiv);
var newDiv = dom.createElement('div');
newDiv.contentEditable = true;
newDiv.className = 'editable';
newDiv.innerHTML = ' ';
goog.dom.insertSiblingAfter(newDiv, contentEditableDiv);
newDiv.focus();
}
} else if (keyCode == goog.events.KeyCodes.UP) {
// TODO: make it possible to cursor up and down.
} else if (keyCode == goog.events.KeyCodes.DOWN) {
} else if (keyCode == goog.events.KeyCodes.S && e.ctrlKey) {
// ctrl-S saves the file.
saveFn();
}
}
document.body.innerHTML = '<div id="picker"></div>' +
'<div style="width: 600px; ' +
'position: absolute; ' +
'top: 150px; ' +
'left: 25px;">' +
'<div id="toolbar" style="height: 25px">' +
'<div id="status" style="float: right"></div>' +
'<button id="save">Save</button>' +
' <span id="title" style="font-weight: bold; font-family: Arial;"></span>' +
'</div>' +
'<div id="viewer" style="height: 800px; border: 1px solid #ccc; padding: 4px"></div>' +
'</div>';
var viewerEl = dom.$('viewer');
var viewer = new gdata.docs.ui.DocViewer(viewerEl, { stripHeadHtml: true });
var pickerEl = dom.$('picker');
new gdata.docs.ui.DocPicker(pickerEl, viewer);
function onSave(serverResponse) {
output(serverResponse);
dom.$('status').innerHTML = 'Saved at: ' + (new Date());
}
function onFailedSave(errorMessage) {
output(serverResponse);
dom.$('status').innerHTML = 'Error while saving: ' + errorMessage;
}
function save() {
dom.$('status').innerHTML = 'Saving...';
viewer.save(onSave, onFailedSave);
}
function onSaveClicked(e) {
save();
};
var postLoadProcessor = goog.partial(makeDivsContentEditable, save);
viewer.setPostLoadProcessor(postLoadProcessor);
goog.events.listen(dom.$('save'),
goog.events.EventType.CLICK,
onSaveClicked);
goog.events.listen(viewer,
gdata.docs.ui.DocViewer.EventType.DOCUMENT_LOADED,
function(e) {
dom.$('title').innerHTML =
goog.string.htmlEscape(viewer.getEntry().getTitle());
});