2008-03-15 03:04:59 +00:00
IMAGE _DIR = "/static/images/" ;
2008-10-24 18:51:19 +00:00
NOTEBOOK _READ _ONLY = 0 ;
NOTEBOOK _READ _WRITE = 1 ;
NOTEBOOK _READ _WRITE _FOR _OWN _NOTES = 2 ;
2008-03-15 03:04:59 +00:00
2007-09-06 21:36:39 +00:00
function Wiki ( invoker ) {
2007-07-16 20:22:38 +00:00
this . next _id = null ;
this . focused _editor = null ;
2008-11-25 00:58:59 +00:00
this . notebook = evalJSON ( getElement ( "notebook" ) . value ) ;
2007-08-29 00:50:46 +00:00
this . parent _id = getElement ( "parent_id" ) . value ; // id of the notebook containing this one
2007-08-16 01:29:18 +00:00
this . startup _notes = new Array ( ) ; // map of startup notes: note id to bool
2008-06-26 03:04:06 +00:00
this . open _editors = new Array ( ) ; // map of open notes: lowercase note title to editor
2007-09-10 20:04:46 +00:00
this . search _results _editor = null ; // editor for display of search results
2007-09-06 21:36:39 +00:00
this . invoker = invoker ;
2008-10-24 18:51:19 +00:00
this . user = evalJSON ( getElement ( "user" ) . value ) ;
2007-10-16 21:37:12 +00:00
this . rate _plan = evalJSON ( getElement ( "rate_plan" ) . value ) ;
2008-05-08 19:29:11 +00:00
this . yearly = evalJSON ( getElement ( "yearly" ) . value ) ;
2007-09-20 22:59:00 +00:00
this . storage _usage _high = false ;
2007-12-12 00:52:34 +00:00
this . invites = evalJSON ( getElement ( "invites" ) . value ) ;
2008-01-10 08:33:19 +00:00
this . invite _id = getElement ( "invite_id" ) . value ;
this . after _login = getElement ( "after_login" ) . value ;
2008-03-24 22:33:00 +00:00
this . signup _plan = getElement ( "signup_plan" ) . value ;
2008-05-28 23:05:38 +00:00
this . groups = evalJSON ( getElement ( "groups" ) . value ) ;
2008-03-11 23:50:09 +00:00
this . font _size = null ;
2008-05-12 23:27:42 +00:00
this . small _toolbar = false ;
this . large _toolbar _bottom = 0 ;
2008-10-30 22:26:27 +00:00
this . autosaver = null ;
2007-07-16 20:22:38 +00:00
2007-11-15 22:40:16 +00:00
var total _notes _count _node = getElement ( "total_notes_count" ) ;
if ( total _notes _count _node )
this . total _notes _count = parseInt ( scrapeText ( total _notes _count _node ) ) ;
else
this . total _notes _count = null ;
2008-10-27 23:23:27 +00:00
if ( getElement ( "note_tree_root_table" ) )
2008-11-25 00:58:59 +00:00
this . note _tree = new Note _tree ( this , this . notebook . object _id , this . invoker ) ;
this . recent _notes = new Recent _notes ( this , this . notebook . object _id , this . invoker ) ;
2008-04-29 00:54:08 +00:00
2007-11-17 22:55:13 +00:00
this . notebooks = evalJSON ( getElement ( "notebooks" ) . value ) ;
2008-05-19 22:16:25 +00:00
this . notebooks _by _id = { } ;
2007-11-17 22:55:13 +00:00
for ( var i in this . notebooks ) {
2008-05-20 07:51:23 +00:00
var notebook = this . notebooks [ i ] ;
if ( ! this . notebooks _by _id [ notebook . object _id ] )
this . notebooks _by _id [ notebook . object _id ] = notebook ;
2007-10-16 21:37:12 +00:00
}
2008-10-24 18:51:19 +00:00
if ( this . notebook && this . notebook . read _write != NOTEBOOK _READ _ONLY ) {
2008-10-07 23:52:05 +00:00
var unsupported _agent = null ;
var beta _agent = null ;
2008-11-12 06:38:53 +00:00
if ( /Opera/ . test ( navigator . userAgent ) )
2007-10-19 21:07:22 +00:00
unsupported _agent = "Opera" ;
2007-12-03 21:36:25 +00:00
if ( unsupported _agent )
2008-09-30 19:58:39 +00:00
this . display _message ( "Luminotes does not currently support the " + unsupported _agent + " web browser for editing. If possible, please use Firefox or Internet Explorer instead. " + unsupported _agent + " support will be added in a future release. Sorry for the inconvenience." ) ;
2008-10-07 23:52:05 +00:00
else if ( beta _agent )
this . display _message ( "Luminotes support for your web browser (" + beta _agent + ") is currently in beta. If you encounter any problems, please contact support so that they can be fixed!" ) ;
2007-10-19 21:07:22 +00:00
}
2008-11-21 01:39:20 +00:00
if ( ! this . notebook _has _tag ( this . notebook , "forum" ) )
2008-10-30 22:26:27 +00:00
this . autosaver = Autosaver ( this ) ;
2007-11-17 04:21:48 +00:00
var deleted _id = getElement ( "deleted_id" ) . value ;
2007-11-17 04:39:33 +00:00
var skip _empty _message = deleted _id ? true : false ;
2007-11-17 04:21:48 +00:00
2007-10-16 21:37:12 +00:00
// populate the wiki with startup notes
this . populate (
evalJSON ( getElement ( "startup_notes" ) . value || "null" ) ,
2007-10-30 23:05:46 +00:00
evalJSON ( getElement ( "current_notes" ) . value || "null" ) ,
2007-11-17 04:39:33 +00:00
evalJSON ( getElement ( "note_read_write" ) . value || "true" ) ,
skip _empty _message
2007-10-16 21:37:12 +00:00
) ;
2008-10-24 18:51:19 +00:00
this . display _storage _usage ( this . user . storage _bytes || "0" ) ;
2007-10-16 21:37:12 +00:00
2007-08-07 01:48:43 +00:00
connect ( this . invoker , "error_message" , this , "display_error" ) ;
2007-09-27 22:40:18 +00:00
connect ( this . invoker , "message" , this , "display_message" ) ;
2007-07-16 20:22:38 +00:00
connect ( "search_form" , "onsubmit" , this , "search" ) ;
2008-04-04 05:39:40 +00:00
connect ( "search_text" , "onfocus" , this , "search_focused" ) ;
2008-04-04 06:28:26 +00:00
connect ( "search_text" , "onblur" , this , "search_blurred" ) ;
2008-06-30 05:26:08 +00:00
connect ( "search_text" , "onkeyup" , this , "search_key_released" ) ;
2007-09-05 23:11:19 +00:00
connect ( "html" , "onclick" , this , "background_clicked" ) ;
2007-11-09 20:07:32 +00:00
connect ( "html" , "onkeydown" , this , "key_pressed" ) ;
2009-01-22 21:05:18 +00:00
connect ( window , "onresize" , this , "resize_editor" ) ;
2008-05-12 23:27:42 +00:00
connect ( window , "onresize" , this , "resize_toolbar" ) ;
2008-03-11 23:50:09 +00:00
connect ( document , "onmouseover" , this , "detect_font_resize" ) ;
2007-07-16 20:22:38 +00:00
2007-10-27 03:22:34 +00:00
var blank _note _stub = getElement ( "blank_note_stub" ) ;
if ( blank _note _stub ) {
connect ( blank _note _stub , "onmouseover" , function ( event ) {
addElementClass ( blank _note _stub , "blank_note_stub_border" ) ;
removeElementClass ( blank _note _stub , "blank_note_stub_hidden_border" ) ;
} ) ;
connect ( blank _note _stub , "onmouseout" , function ( event ) {
addElementClass ( blank _note _stub , "blank_note_stub_hidden_border" ) ;
removeElementClass ( blank _note _stub , "blank_note_stub_border" ) ;
} ) ;
connect ( blank _note _stub , "onclick" , this , "create_blank_editor" ) ;
}
2007-07-16 20:22:38 +00:00
var self = this ;
2008-03-01 00:26:06 +00:00
var top _window = window ;
2007-10-16 21:37:12 +00:00
var logout _link = getElement ( "logout_link" ) ;
if ( logout _link ) {
connect ( "logout_link" , "onclick" , function ( event ) {
2008-01-22 23:29:16 +00:00
self . save _editor ( null , false , function ( ) {
2008-03-01 00:26:06 +00:00
top _window . location = "/users/logout" ;
2008-01-22 23:29:16 +00:00
} ) ;
2007-10-16 21:37:12 +00:00
event . stop ( ) ;
} ) ;
2007-07-16 20:22:38 +00:00
}
2007-11-15 23:46:30 +00:00
var rename = evalJSON ( getElement ( "rename" ) . value ) ;
2008-10-24 18:51:19 +00:00
if ( rename && this . notebook . read _write == NOTEBOOK _READ _WRITE )
2007-11-15 23:46:30 +00:00
this . start _notebook _rename ( ) ;
2007-11-17 04:39:33 +00:00
// if a notebook was just deleted, show a message with an undo button
2008-10-24 18:51:19 +00:00
if ( deleted _id && this . notebook . read _write == NOTEBOOK _READ _WRITE ) {
2007-11-17 04:39:33 +00:00
var undo _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "undo" ,
"title" : "undo deletion"
} ) ;
var trash _link = createDOM ( "a" , {
"href" : "/notebooks/" + this . notebook . trash _id + "?parent_id=" + this . notebook . object _id
} , "trash" ) ;
var message _div = this . display _message ( "The notebook has been moved to the" , [ trash _link , ". " , undo _button ] , "notes_top" ) ;
2007-11-17 22:55:13 +00:00
connect ( undo _button , "onclick" , function ( event ) { self . undelete _notebook ( event , deleted _id ) ; } ) ;
2007-11-17 04:39:33 +00:00
}
2008-03-15 03:04:59 +00:00
var current _notebook _up = getElement ( "current_notebook_up" ) ;
if ( current _notebook _up ) {
connect ( current _notebook _up , "onmouseover" , function ( event ) { current _notebook _up . src = IMAGE _DIR + "up_arrow_hover.png" ; } ) ;
connect ( current _notebook _up , "onmouseout" , function ( event ) { current _notebook _up . src = IMAGE _DIR + "up_arrow.png" ; } ) ;
connect ( current _notebook _up , "onclick" , function ( event ) {
current _notebook _up . src = IMAGE _DIR + "up_arrow.png" ;
self . move _current _notebook _up ( event ) ;
} ) ;
}
var current _notebook _down = getElement ( "current_notebook_down" ) ;
if ( current _notebook _down ) {
connect ( current _notebook _down , "onmouseover" , function ( event ) { current _notebook _down . src = IMAGE _DIR + "down_arrow_hover.png" ; } ) ;
connect ( current _notebook _down , "onmouseout" , function ( event ) { current _notebook _down . src = IMAGE _DIR + "down_arrow.png" ; } ) ;
connect ( current _notebook _down , "onclick" , function ( event ) {
current _notebook _down . src = IMAGE _DIR + "down_arrow.png" ;
self . move _current _notebook _down ( event ) ;
} ) ;
}
2008-05-12 23:27:42 +00:00
this . resize _toolbar ( ) ;
2007-07-16 20:22:38 +00:00
}
Wiki . prototype . update _next _id = function ( result ) {
this . next _id = result . next _id ;
}
2008-02-05 19:45:11 +00:00
var KILOBYTE = 1024 ;
var MEGABYTE = 1024 * KILOBYTE ;
2008-02-18 20:08:07 +00:00
function bytes _to _megabytes ( bytes , choose _units ) {
if ( choose _units ) {
if ( bytes < KILOBYTE )
return bytes + " bytes" ;
if ( bytes < MEGABYTE )
return Math . round ( bytes / KILOBYTE ) + " KB" ;
}
2008-02-05 19:45:11 +00:00
return Math . round ( bytes / MEGABYTE ) + " MB" ;
}
2007-09-20 20:36:19 +00:00
Wiki . prototype . display _storage _usage = function ( storage _bytes ) {
2007-09-20 22:26:43 +00:00
if ( ! storage _bytes )
return ;
2007-09-20 20:36:19 +00:00
// display the user's current storage usage
2007-10-16 21:37:12 +00:00
var quota _bytes = this . rate _plan . storage _quota _bytes ;
if ( ! quota _bytes )
return ;
2007-09-20 20:36:19 +00:00
var usage _percent = Math . round ( storage _bytes / quota _bytes * 100.0 ) ;
2007-09-20 23:30:09 +00:00
if ( usage _percent > 90 ) {
2007-09-20 20:36:19 +00:00
var storage _usage _class = "storage_usage_high" ;
2007-09-20 23:25:59 +00:00
if ( this . storage _usage _high == false )
2008-01-11 09:02:14 +00:00
this . display _message (
"You are currently using " +
usage _percent +
2008-02-20 20:21:54 +00:00
"% of your available storage space. Please delete some notes or files, empty the trash, or" ,
2008-01-11 09:02:14 +00:00
[ createDOM ( "a" , { "href" : "/upgrade" } , "upgrade" ) , " your account." ]
) ;
2007-09-20 22:59:00 +00:00
this . storage _usage _high = true ;
} else if ( usage _percent > 75 ) {
2007-09-20 20:36:19 +00:00
var storage _usage _class = "storage_usage_medium" ;
2007-09-20 22:59:00 +00:00
this . storage _usage _high = false ;
} else {
2007-09-20 20:36:19 +00:00
var storage _usage _class = "storage_usage_low" ;
2007-09-20 22:59:00 +00:00
this . storage _usage _high = false ;
}
2007-09-20 20:36:19 +00:00
2008-11-17 22:45:10 +00:00
var storage _usage _area = getElement ( "storage_usage_area" ) ;
if ( ! storage _usage _area )
return ;
2007-09-20 20:36:19 +00:00
replaceChildNodes (
2008-11-17 22:45:10 +00:00
storage _usage _area ,
2007-09-20 20:36:19 +00:00
createDOM ( "div" , { "class" : storage _usage _class } ,
2008-02-05 19:45:11 +00:00
bytes _to _megabytes ( storage _bytes ) + " (" + usage _percent + "%) of " + bytes _to _megabytes ( quota _bytes ) )
2007-09-20 20:36:19 +00:00
) ;
}
2007-11-17 04:39:33 +00:00
Wiki . prototype . populate = function ( startup _notes , current _notes , note _read _write , skip _empty _message ) {
2007-11-17 22:55:13 +00:00
var self = this ;
2007-12-11 01:15:03 +00:00
// if this is the trash and the user has owner-level access, then display a list of all deleted notebooks
if ( this . notebook . owner && this . notebook . name == "trash" ) {
2007-11-17 22:55:13 +00:00
var heading _shown = false ;
var deleted _notebooks = getElement ( "deleted_notebooks" ) ;
for ( var i in this . notebooks ) {
var notebook = this . notebooks [ i ] ;
if ( ! notebook . deleted )
continue ;
if ( ! heading _shown ) {
appendChildNodes ( deleted _notebooks , createDOM ( "h4" , { } , "deleted notebooks" ) ) ;
heading _shown = true ;
}
delete _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "note_button" ,
"id" : "delete_notebook_" + notebook . object _id ,
"value" : "delete forever" ,
"title" : "delete notebook"
} ) ;
function connect _delete ( notebook _id ) {
connect ( delete _button , "onclick" , function ( event ) { self . delete _notebook _forever ( event , notebook _id ) ; } ) ;
}
connect _delete ( notebook . object _id ) ;
undelete _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "note_button" ,
"id" : "undelete_notebook_" + notebook . object _id ,
"value" : "undelete" ,
"title" : "undelete notebook"
} ) ;
function connect _undelete ( notebook _id ) {
connect ( undelete _button , "onclick" , function ( event ) { self . undelete _notebook ( event , notebook _id ) ; } ) ;
}
connect _undelete ( notebook . object _id ) ;
appendChildNodes ( deleted _notebooks , createDOM ( "div" ,
2007-11-17 23:29:22 +00:00
{ "id" : "deleted_notebook_" + notebook . object _id , "class" : "deleted_notebook_item" } ,
2007-11-17 22:55:13 +00:00
createDOM ( "span" , { } , delete _button ) ,
createDOM ( "span" , { } , undelete _button ) ,
createDOM ( "span" , { } , notebook . name )
) ) ;
}
}
2007-10-16 21:37:12 +00:00
// create an editor for each startup note in the received notebook, focusing the first one
var focus = true ;
for ( var i in startup _notes ) {
var startup _note = startup _notes [ i ] ;
this . startup _notes [ startup _note . object _id ] = true ;
2007-09-01 21:06:37 +00:00
2007-10-30 23:05:46 +00:00
// don't actually create an editor if a particular list of notes was provided in the result
if ( current _notes . length == 0 ) {
2009-01-07 20:39:48 +00:00
var static _note = getElement ( "static_note_" + startup _note . object _id ) ;
if ( ! static _note ) continue ;
var static _contents = getFirstElementByTagAndClassName ( "span" , "static_note_contents" , static _note ) ;
if ( ! static _contents ) continue ;
var contents _text = static _contents . innerHTML ;
2007-10-16 21:37:12 +00:00
var editor = this . create _editor (
startup _note . object _id ,
2007-10-30 23:05:46 +00:00
// grab this note's contents from the static notes area
2009-01-07 20:39:48 +00:00
contents _text ,
2007-10-16 21:37:12 +00:00
startup _note . deleted _from _id ,
startup _note . revision ,
2007-10-30 23:05:46 +00:00
startup _note . creation ,
2008-10-24 18:51:19 +00:00
this . notebook . read _write , false , focus , null ,
2008-10-30 23:53:42 +00:00
startup _note . user _id ,
startup _note . username
2007-10-16 21:37:12 +00:00
) ;
2007-09-01 21:06:37 +00:00
2008-06-26 03:04:06 +00:00
if ( startup _note . title )
this . open _editors [ startup _note . title . toLowerCase ( ) ] = editor ;
2007-10-16 21:37:12 +00:00
focus = false ;
}
2007-08-29 00:50:46 +00:00
}
2007-08-28 20:57:08 +00:00
2007-10-30 23:05:46 +00:00
// if particular notes were provided, then display editors for them
var focus = true ;
for ( var i in current _notes ) {
var note = current _notes [ i ] ;
2008-10-30 22:26:27 +00:00
if ( ! note _read _write )
var read _write = NOTEBOOK _READ _ONLY ;
else
var read _write = this . notebook . read _write ;
2009-01-09 22:54:51 +00:00
var static _note = getElement ( "static_note_" + note . object _id ) ;
2009-01-07 20:39:48 +00:00
if ( ! static _note ) continue ;
var static _contents = getFirstElementByTagAndClassName ( "span" , "static_note_contents" , static _note ) ;
if ( ! static _contents ) continue ;
var contents _text = static _contents . innerHTML ;
2007-10-16 21:37:12 +00:00
this . create _editor (
note . object _id ,
2009-01-07 20:39:48 +00:00
contents _text ,
2007-10-16 21:37:12 +00:00
note . deleted _from _id ,
note . revision ,
2007-10-30 23:05:46 +00:00
note . creation ,
2008-10-30 22:26:27 +00:00
read _write , false , focus , null ,
2008-10-30 23:53:42 +00:00
note . user _id ,
note . username
2007-10-16 21:37:12 +00:00
) ;
2007-10-30 23:05:46 +00:00
focus = false ;
}
2007-08-07 01:48:43 +00:00
2007-11-17 04:39:33 +00:00
if ( startup _notes . length == 0 && current _notes . length == 0 && ! skip _empty _message )
2007-10-16 21:37:12 +00:00
this . display _empty _message ( ) ;
2007-08-07 01:48:43 +00:00
2007-10-16 21:37:12 +00:00
var empty _trash _link = getElement ( "empty_trash_link" ) ;
if ( empty _trash _link )
connect ( empty _trash _link , "onclick" , function ( event ) { self . delete _all _editors ( event ) ; } ) ;
2007-08-07 01:48:43 +00:00
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write != NOTEBOOK _READ _ONLY ) {
2007-07-16 20:22:38 +00:00
connect ( window , "onunload" , function ( event ) { self . editor _focused ( null , true ) ; } ) ;
2008-10-30 22:26:27 +00:00
connect ( "newNote" , "onclick" , this , "create_blank_editor" ) ;
2007-10-25 23:19:57 +00:00
connect ( "createLink" , "onclick" , this , "toggle_link_button" ) ;
2008-10-27 23:23:27 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _WRITE )
connect ( "attachFile" , "onclick" , this , "toggle_attach_button" ) ;
2007-07-16 20:22:38 +00:00
connect ( "bold" , "onclick" , function ( event ) { self . toggle _button ( event , "bold" ) ; } ) ;
connect ( "italic" , "onclick" , function ( event ) { self . toggle _button ( event , "italic" ) ; } ) ;
2007-08-27 21:01:42 +00:00
connect ( "underline" , "onclick" , function ( event ) { self . toggle _button ( event , "underline" ) ; } ) ;
2008-05-14 00:07:02 +00:00
connect ( "strikethrough" , "onclick" , function ( event ) { self . toggle _button ( event , "strikethrough" ) ; } ) ;
2008-12-11 07:21:44 +00:00
connect ( "font" , "onclick" , this , "toggle_font_button" ) ;
2007-11-30 01:43:06 +00:00
connect ( "title" , "onclick" , function ( event ) { self . toggle _button ( event , "title" ) ; } ) ;
2007-07-16 20:22:38 +00:00
connect ( "insertUnorderedList" , "onclick" , function ( event ) { self . toggle _button ( event , "insertUnorderedList" ) ; } ) ;
connect ( "insertOrderedList" , "onclick" , function ( event ) { self . toggle _button ( event , "insertOrderedList" ) ; } ) ;
2007-10-25 23:19:57 +00:00
2008-05-12 23:27:42 +00:00
this . make _image _button ( "newNote" , "new_note" ) ;
2007-10-25 23:19:57 +00:00
this . make _image _button ( "createLink" , "link" ) ;
2008-10-27 23:23:27 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _WRITE )
this . make _image _button ( "attachFile" , "attach" ) ;
2007-10-25 23:19:57 +00:00
this . make _image _button ( "bold" ) ;
this . make _image _button ( "italic" ) ;
this . make _image _button ( "underline" ) ;
2008-05-14 00:07:02 +00:00
this . make _image _button ( "strikethrough" ) ;
2008-12-11 07:21:44 +00:00
this . make _image _button ( "font" ) ;
2007-10-25 23:19:57 +00:00
this . make _image _button ( "title" ) ;
this . make _image _button ( "insertUnorderedList" , "bullet_list" ) ;
this . make _image _button ( "insertOrderedList" , "numbered_list" ) ;
2007-07-16 20:22:38 +00:00
// grab the next available object id
this . invoker . invoke ( "/next_id" , "POST" , null ,
function ( result ) { self . update _next _id ( result ) ; }
) ;
}
2008-07-29 23:38:35 +00:00
var save _button = getElement ( "save_button" ) ;
if ( save _button ) {
connect ( save _button , "onclick" , function ( event ) {
self . save _editor ( null ) ;
} ) ;
save _button . disabled = true ;
}
2008-09-18 06:39:11 +00:00
var export _link = getElement ( "export_link" ) ;
if ( export _link ) {
connect ( export _link , "onclick" , function ( event ) {
2008-09-30 06:09:44 +00:00
self . save _editor ( null ) ;
self . export _clicked ( ) ;
2008-09-18 06:39:11 +00:00
event . stop ( ) ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
} ) ;
}
2007-11-15 01:30:45 +00:00
2008-08-08 23:39:53 +00:00
var import _link = getElement ( "import_link" ) ;
if ( import _link ) {
connect ( import _link , "onclick" , function ( event ) {
self . import _clicked ( ) ;
event . stop ( ) ;
} ) ;
}
2007-11-15 01:30:45 +00:00
var rename _notebook _link = getElement ( "rename_notebook_link" ) ;
if ( rename _notebook _link ) {
connect ( rename _notebook _link , "onclick" , function ( event ) {
self . start _notebook _rename ( ) ;
event . stop ( ) ;
} ) ;
}
var notebook _header _name = getElement ( "notebook_header_name" ) ;
if ( notebook _header _name ) {
connect ( notebook _header _name , "onclick" , function ( event ) {
self . start _notebook _rename ( ) ;
event . stop ( ) ;
} ) ;
}
2007-11-17 04:21:48 +00:00
2007-11-17 23:29:22 +00:00
var delete _notebook _link = getElement ( "delete_notebook_link" ) ;
if ( delete _notebook _link ) {
connect ( delete _notebook _link , "onclick" , function ( event ) {
2007-11-17 04:21:48 +00:00
self . delete _notebook ( ) ;
event . stop ( ) ;
} ) ;
}
2007-12-11 01:15:03 +00:00
var share _notebook _link = getElement ( "share_notebook_link" ) ;
if ( share _notebook _link ) {
connect ( share _notebook _link , "onclick" , function ( event ) {
2008-05-03 04:29:23 +00:00
self . load _editor ( "share this notebook" , "null" , null , null , null , getElement ( "notes_top" ) ) ;
2007-12-11 01:15:03 +00:00
event . stop ( ) ;
} ) ;
}
2008-04-18 23:54:09 +00:00
2008-05-08 03:05:35 +00:00
var settings _link = getElement ( "settings_link" ) ;
if ( settings _link ) {
connect ( settings _link , "onclick" , function ( event ) {
self . load _editor ( "account settings" , "null" , null , null , null , getElement ( "notes_top" ) ) ;
event . stop ( ) ;
} ) ;
}
2008-04-18 23:54:09 +00:00
var declutter _link = getElement ( "declutter_link" ) ;
if ( declutter _link ) {
connect ( declutter _link , "onclick" , function ( event ) {
self . declutter _clicked ( ) ;
event . stop ( ) ;
} ) ;
}
2008-06-22 05:13:52 +00:00
var new _notebook _button = getElement ( "new_notebook" ) ;
if ( new _notebook _button ) {
connect ( new _notebook _button , "onclick" , function ( event ) {
self . invoker . invoke ( "/notebooks/create" , "POST" ) ;
event . stop ( ) ;
} ) ;
this . make _image _button ( "new_notebook" , "new_note" , true ) ;
}
2008-11-14 20:34:06 +00:00
var new _note _tree _link _button = getElement ( "new_note_tree_link" ) ;
if ( new _note _tree _link _button ) {
connect ( new _note _tree _link _button , "onclick" , function ( event ) {
2008-11-15 00:51:35 +00:00
self . clear _pulldowns ( ) ;
2008-11-14 20:34:06 +00:00
if ( self . note _tree )
self . note _tree . start _link _add ( ) ;
event . stop ( ) ;
} ) ;
this . make _image _button ( "new_note_tree_link" , "new_note" , true ) ;
}
2007-07-16 20:22:38 +00:00
}
2007-09-05 23:11:19 +00:00
Wiki . prototype . background _clicked = function ( event ) {
2008-06-14 06:26:48 +00:00
var tag _name = event . target ( ) . tagName . toLowerCase ( ) ;
if ( tag _name == "input" || tag _name == "label" )
return ;
this . clear _pulldowns ( ) ;
2007-09-05 23:11:19 +00:00
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . create _blank _editor = function ( event ) {
if ( event ) event . stop ( ) ;
2008-10-30 22:26:27 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _WRITE _FOR _OWN _NOTES &&
( ! this . user . username || this . user . username == "anonymous" ) ) {
2008-11-12 23:21:40 +00:00
this . display _message ( 'Please login first. No account? Click "sign up" to get a free account.' ) ;
2008-10-30 22:26:27 +00:00
return ;
}
2007-10-27 03:22:34 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-08-30 20:39:41 +00:00
// if we're within the trash, don't allow new note creation
if ( this . notebook . name == "trash" ) {
this . display _error ( "You can't create notes in the trash." ) ;
return ;
}
2007-07-16 20:22:38 +00:00
// if there is already a blank editor, then highlight it and bail
2009-01-22 23:30:17 +00:00
if ( Editor . shared _iframe && Editor . shared _iframe . editor && Editor . shared _iframe . editor . empty ( ) ) {
2009-01-24 20:25:48 +00:00
Editor . shared _iframe . editor . highlight ( ) ;
2009-01-22 23:30:17 +00:00
return ;
2007-07-16 20:22:38 +00:00
}
2008-10-30 23:53:42 +00:00
var editor = this . create _editor ( undefined , undefined , undefined , undefined , undefined , this . notebook . read _write , true , true , null , this . user . object _id , this . user . username ) ;
2007-10-19 20:24:16 +00:00
this . increment _total _notes _count ( ) ;
2008-04-09 23:31:30 +00:00
signal ( this , "note_added" , editor ) ;
2007-07-16 20:22:38 +00:00
}
2008-05-03 04:29:23 +00:00
Wiki . prototype . load _editor = function ( note _title , note _id , revision , previous _revision , link , position _after ) {
2007-09-02 03:51:31 +00:00
if ( this . notebook . name == "trash" && ! revision ) {
2007-11-09 06:49:26 +00:00
this . display _message ( "If you'd like to use this note, try undeleting it first." , undefined , position _after ) ;
2007-08-30 20:39:41 +00:00
return ;
}
2007-08-15 00:18:30 +00:00
// if a link is given with an open link pulldown, then ignore the note title given and use the
// one from the pulldown instead
2007-08-16 19:55:11 +00:00
if ( link ) {
var pulldown = link . pulldown ;
var pulldown _title = undefined ;
2008-06-27 23:11:09 +00:00
if ( pulldown && pulldown . title _field ) {
2007-08-16 19:55:11 +00:00
pulldown _title = strip ( pulldown . title _field . value ) ;
if ( pulldown _title )
note _title = pulldown _title ;
2008-04-15 20:59:27 +00:00
// only use the pulldown title if it has changed from the note's original title
if ( pulldown _title == note _title )
pulldown _title = undefined ;
2007-08-16 19:55:11 +00:00
}
2007-08-15 00:18:30 +00:00
2007-10-22 23:17:56 +00:00
if ( link . target )
link . removeAttribute ( "target" ) ;
2007-08-16 22:27:58 +00:00
}
2007-09-06 08:27:41 +00:00
// if the note corresponding to the link's id is already open, highlight it and bail, but only if
// we didn't pull a title from an open link pulldown
if ( ! pulldown _title ) {
2009-01-12 22:19:32 +00:00
var editor = editor _by _id ( note _id , revision ) ;
2007-09-06 08:27:41 +00:00
2009-01-12 22:19:32 +00:00
if ( editor ) {
editor . highlight ( ) ;
2007-09-06 08:27:41 +00:00
if ( link )
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?note_id=" + note _id ;
2007-09-06 08:27:41 +00:00
return ;
}
2007-08-16 01:29:18 +00:00
}
2007-09-07 23:46:01 +00:00
// if there's not a valid destination note id, then load by title instead of by id
2007-08-16 01:29:18 +00:00
var self = this ;
2007-09-07 23:46:01 +00:00
if ( pulldown _title || note _id == undefined || note _id == "new" || note _id == "null" ) {
2008-06-26 03:04:06 +00:00
var lower _note _title = note _title . toLowerCase ( ) ;
2007-09-10 20:04:46 +00:00
// if the note_title corresponds to a "magic" note's title, then dynamically highlight or create the note
2008-06-26 03:04:06 +00:00
if ( lower _note _title == "search results" ) {
var editor = this . open _editors [ lower _note _title ] ;
2007-09-10 20:04:46 +00:00
if ( editor ) {
editor . highlight ( ) ;
return ;
}
this . display _search _results ( ) ;
return ;
}
2008-06-26 03:04:06 +00:00
if ( lower _note _title == "share this notebook" ) {
var editor = this . open _editors [ lower _note _title ] ;
2007-12-11 01:15:03 +00:00
if ( editor ) {
editor . highlight ( ) ;
return ;
}
this . share _notebook ( ) ;
return ;
}
2008-06-26 03:04:06 +00:00
if ( lower _note _title == "account settings" ) {
var editor = this . open _editors [ lower _note _title ] ;
2008-05-08 03:05:35 +00:00
if ( editor ) {
editor . highlight ( ) ;
return ;
}
this . display _settings ( ) ;
return ;
}
2007-09-05 23:44:34 +00:00
2007-09-05 19:54:04 +00:00
// but if the note corresponding to the link's title is already open, highlight it and bail
if ( ! revision ) {
2008-06-26 03:04:06 +00:00
var editor = this . open _editors [ lower _note _title ] ;
2007-09-05 19:54:04 +00:00
if ( editor ) {
editor . highlight ( ) ;
if ( link )
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?note_id=" + editor . id ;
2007-09-05 19:54:04 +00:00
return ;
}
}
2008-11-17 21:33:21 +00:00
// if the notebook is a forum, then instead of opening a new post, display an error message
if ( this . notebook _has _tag ( this . notebook , "forum" ) ) {
2008-10-30 22:26:27 +00:00
this . display _message ( "No such forum post! (A forum link must point to another post in this discussion or an external web page.)" ) ;
return ;
}
2007-08-14 04:13:49 +00:00
this . invoker . invoke (
"/notebooks/load_note_by_title" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-08-14 04:13:49 +00:00
"note_title" : note _title ,
"revision" : revision
} ,
2007-11-09 06:49:26 +00:00
function ( result ) { self . parse _loaded _editor ( result , note _title , revision , link , position _after ) ; }
2007-08-14 04:13:49 +00:00
) ;
return ;
}
2008-11-17 21:33:21 +00:00
// if the notebook is a forum, maintain displayed note order by opening an existing note on its own page
if ( this . notebook _has _tag ( this . notebook , "forum" ) ) {
2008-10-30 22:26:27 +00:00
window . location = window . location . protocol + '//' + window . location . host + window . location . pathname + '?note_id=' + note _id ;
return ;
}
2007-07-16 20:22:38 +00:00
this . invoker . invoke (
2007-07-17 01:21:31 +00:00
"/notebooks/load_note" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-07-31 22:53:57 +00:00
"note_id" : note _id ,
2008-05-03 04:29:23 +00:00
"revision" : revision ,
"previous_revision" : previous _revision
2007-07-16 20:22:38 +00:00
} ,
2007-11-09 06:49:26 +00:00
function ( result ) { self . parse _loaded _editor ( result , note _title , revision , link , position _after ) ; }
2007-07-16 20:22:38 +00:00
) ;
}
2008-08-01 22:50:49 +00:00
Wiki . prototype . resolve _link = function ( note _title , link , force , callback ) {
2007-08-16 22:27:58 +00:00
// if the title looks like a URL, then make it a link to an external site
2008-01-08 23:33:25 +00:00
if ( /^\w+:\/\// . test ( note _title ) )
var title _looks _like _url = true ;
else
var title _looks _like _url = false ;
2007-10-22 23:17:56 +00:00
if ( link && link . target )
link . removeAttribute ( "target" ) ;
2007-08-16 22:27:58 +00:00
2008-05-08 03:05:35 +00:00
if ( note _title == "search results" || note _title == "share this notebook" || note _title == "account settings" ) {
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?" + queryString (
2007-09-07 23:03:12 +00:00
[ "title" , "note_id" ] ,
[ note _title , "null" ]
) ;
2007-09-10 20:04:46 +00:00
if ( callback ) {
2007-12-11 01:15:03 +00:00
if ( note _title == "search results" )
2007-09-10 20:04:46 +00:00
callback ( "current search results" ) ;
2008-05-08 03:05:35 +00:00
else if ( note _title == "share this notebook" )
2007-12-11 01:15:03 +00:00
callback ( "share this notebook with others" ) ;
2008-05-08 03:05:35 +00:00
else
callback ( "account settings" ) ;
2007-09-10 20:04:46 +00:00
}
2007-09-07 23:03:12 +00:00
return ;
}
2007-08-16 01:29:18 +00:00
var id = parse _query ( link ) . note _id ;
// if the link already has a valid-looking id, it's already resolved, so bail
2008-08-01 22:50:49 +00:00
if ( ! force && id != undefined && id != "new" && id != "null" ) {
if ( callback )
callback ( null ) ;
2007-08-16 01:29:18 +00:00
return ;
2008-08-01 22:50:49 +00:00
}
2007-07-16 20:22:38 +00:00
2007-08-14 04:13:49 +00:00
if ( note _title . length == 0 )
return ;
2007-08-16 01:29:18 +00:00
// if the note corresponding to the link's title is already open, resolve the link and bail
2008-06-26 03:04:06 +00:00
var editor = this . open _editors [ note _title . toLowerCase ( ) ] ;
2007-08-16 01:29:18 +00:00
if ( editor ) {
2007-10-22 23:17:56 +00:00
if ( link )
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?note_id=" + editor . id ;
2007-08-16 01:29:18 +00:00
if ( callback )
2007-12-30 21:55:25 +00:00
callback ( editor . summarize ( ) ) ;
2007-08-16 01:29:18 +00:00
return ;
}
2007-08-14 04:13:49 +00:00
var self = this ;
2007-11-27 21:28:25 +00:00
if ( callback ) {
this . invoker . invoke (
"/notebooks/load_note_by_title" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-11-27 21:28:25 +00:00
"note_title" : note _title ,
"summarize" : true
} ,
function ( result ) {
if ( result && result . note ) {
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + self . notebook . object _id + "?note_id=" + result . note . object _id ;
2008-01-08 23:33:25 +00:00
} else if ( title _looks _like _url ) {
link . target = "_new" ;
link . href = note _title ;
callback ( "web link" ) ;
return ;
2007-11-27 21:28:25 +00:00
} else {
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + self . notebook . object _id + "?" + queryString (
2007-11-27 21:28:25 +00:00
[ "title" , "note_id" ] ,
[ note _title , "null" ]
) ;
}
callback ( ( result && result . note ) ? result . note . summary : null ) ;
}
) ;
return ;
}
2007-07-16 20:22:38 +00:00
this . invoker . invoke (
2007-11-27 21:28:25 +00:00
"/notebooks/lookup_note_id" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-07-17 01:21:31 +00:00
"note_title" : note _title
2007-07-16 20:22:38 +00:00
} ,
2007-08-14 04:13:49 +00:00
function ( result ) {
2007-11-27 21:28:25 +00:00
if ( result && result . note _id ) {
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + self . notebook . object _id + "?note_id=" + result . note _id ;
2008-01-08 23:33:25 +00:00
} else if ( title _looks _like _url ) {
link . target = "_new" ;
link . href = note _title ;
2007-08-16 01:29:18 +00:00
} else {
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + self . notebook . object _id + "?" + queryString (
2007-08-16 01:29:18 +00:00
[ "title" , "note_id" ] ,
[ note _title , "null" ]
) ;
}
2007-08-14 04:13:49 +00:00
}
2007-07-16 20:22:38 +00:00
) ;
}
2007-11-09 06:49:26 +00:00
Wiki . prototype . parse _loaded _editor = function ( result , note _title , requested _revision , link , position _after ) {
2007-10-22 23:17:56 +00:00
if ( result . note _id _in _trash ) {
var undelete _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "undelete" ,
"title" : "undelete note"
} ) ;
var trash _link = createDOM ( "a" , {
"href" : "/notebooks/" + this . notebook . trash _id + "?parent_id=" + this . notebook . object _id
} , "trash" ) ;
2007-11-09 06:49:26 +00:00
var message _div = this . display _message ( "That note is in the" , [ trash _link , ". " , undelete _button ] , position _after )
2007-10-22 23:17:56 +00:00
var self = this ;
2007-11-09 06:49:26 +00:00
connect ( undelete _button , "onclick" , function ( event ) { self . undelete _editor _via _undelete ( event , result . note _id _in _trash , message _div ) ; } ) ;
2007-10-22 23:17:56 +00:00
return ;
}
2007-07-17 01:21:31 +00:00
if ( result . note ) {
2007-07-31 22:53:57 +00:00
var id = result . note . object _id ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
if ( requested _revision )
id += " " + requested _revision ;
var actual _revision = result . note . revision ;
2007-10-30 23:05:46 +00:00
var actual _creation = result . note . creation ;
2007-07-17 01:21:31 +00:00
var note _text = result . note . contents ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
var deleted _from _id = result . note . deleted ;
2008-10-24 18:51:19 +00:00
var user _id = result . note . user _id ;
2008-10-30 23:53:42 +00:00
var username = result . note . username ;
2007-07-16 20:22:38 +00:00
} else {
2008-01-08 23:33:25 +00:00
// if the title looks like a URL, then make it a link to an external site
if ( /^\w+:\/\// . test ( note _title ) ) {
link . target = "_new" ;
link . href = note _title ;
window . open ( link . href ) ;
return ;
}
2007-07-16 20:22:38 +00:00
var id = null ;
2007-07-17 01:21:31 +00:00
var note _text = "<h3>" + note _title ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
var deleted _from _id = null ;
var actual _revision = null ;
2007-10-30 23:05:46 +00:00
var actual _creation = null ;
2008-10-24 18:51:19 +00:00
var user _id = null ;
2008-10-30 23:53:42 +00:00
var username = null ;
2007-10-19 20:24:16 +00:00
this . increment _total _notes _count ( ) ;
2007-07-16 20:22:38 +00:00
}
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
if ( requested _revision )
2007-07-31 22:53:57 +00:00
var read _write = false ; // show previous revisions as read-only
else
2007-10-16 21:37:12 +00:00
var read _write = this . notebook . read _write ;
2007-07-31 22:53:57 +00:00
2008-04-13 22:29:50 +00:00
var self = this ;
2009-01-12 22:49:45 +00:00
var editor = this . create _editor ( id , note _text , deleted _from _id , actual _revision , actual _creation , read _write , true , true , position _after , user _id , username ) ;
2008-04-30 02:51:56 +00:00
if ( ! requested _revision )
connect ( editor , "init_complete" , function ( ) { signal ( self , "note_added" , editor ) ; } ) ;
2007-09-05 18:49:28 +00:00
id = editor . id ;
2007-08-14 20:34:31 +00:00
// if a link that launched this editor was provided, update it with the created note's id
if ( link && id )
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?note_id=" + id ;
2007-07-16 20:22:38 +00:00
}
2008-10-30 23:53:42 +00:00
Wiki . prototype . create _editor = function ( id , note _text , deleted _from _id , revision , creation , read _write , highlight , focus , position _after , user _id , username ) {
2007-07-16 20:22:38 +00:00
var self = this ;
2008-05-18 08:07:15 +00:00
var dirty = false ;
2008-10-27 23:34:12 +00:00
var own _notes _only = false ;
2008-05-18 08:07:15 +00:00
2008-10-24 18:51:19 +00:00
if ( read _write == NOTEBOOK _READ _ONLY )
read _write = false ;
else if ( read _write == NOTEBOOK _READ _WRITE )
read _write = true ;
else if ( read _write == NOTEBOOK _READ _WRITE _FOR _OWN _NOTES ) {
2008-10-27 23:23:27 +00:00
own _notes _only = true ;
2008-10-28 21:07:49 +00:00
if ( user _id == this . user . object _id && this . user . username && this . user . username != "anonymous" )
2008-10-24 18:51:19 +00:00
read _write = true ;
else
read _write = false ;
}
2007-07-16 20:22:38 +00:00
if ( isUndefinedOrNull ( id ) ) {
2007-10-16 21:37:12 +00:00
if ( this . notebook . read _write ) {
2007-07-16 20:22:38 +00:00
id = this . next _id ;
2008-05-18 08:07:15 +00:00
dirty = true ;
2007-07-16 20:22:38 +00:00
this . invoker . invoke ( "/next_id" , "POST" , null ,
function ( result ) { self . update _next _id ( result ) ; }
) ;
} else {
id = 0 ;
}
}
2007-07-31 22:53:57 +00:00
// for read-only notes within read-write notebooks, tack the revision timestamp onto the start of the note text
2008-10-24 18:51:19 +00:00
if ( ! read _write && this . notebook . read _write == NOTEBOOK _READ _WRITE && revision ) {
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
var short _revision = this . brief _revision ( revision ) ;
2008-07-11 21:41:48 +00:00
var note _id = id . split ( ' ' ) [ 0 ] ;
note _text = '<p>Previous revision from ' + short _revision + '</p>' +
'<form id="revert_form" target="/notebooks/revert_note">' +
2008-11-25 00:58:59 +00:00
'<input type="hidden" name="notebook_id" value="' + this . notebook . object _id + '">' +
2008-07-11 21:41:48 +00:00
'<input type="hidden" name="note_id" value="' + note _id + '">' +
'<input type="hidden" name="revision" value="' + revision + '">' +
2008-07-12 00:12:52 +00:00
'<input type="submit" class="button" value="revert to this revision" title="Roll back to this earlier version of the note.">' +
2008-07-11 21:41:48 +00:00
'</form>' + note _text ;
2007-07-31 22:53:57 +00:00
}
2008-10-30 23:16:26 +00:00
if ( creation ) {
2008-11-10 20:32:52 +00:00
var note _id = id . split ( ' ' ) [ 0 ] ;
note _text = this . make _byline ( username , creation , note _id ) + note _text ;
2007-10-30 23:05:46 +00:00
}
2007-07-17 01:21:31 +00:00
var startup = this . startup _notes [ id ] ;
2008-11-25 00:58:59 +00:00
var editor = new Editor ( id , this . notebook . object _id , note _text , deleted _from _id , revision , read _write , startup , highlight , focus , position _after , dirty , own _notes _only ) ;
2009-01-07 00:20:04 +00:00
if ( focus )
this . editor _focused ( editor ) ;
2007-07-16 20:22:38 +00:00
2007-10-16 21:37:12 +00:00
if ( this . notebook . read _write ) {
2007-07-16 20:22:38 +00:00
connect ( editor , "state_changed" , this , "editor_state_changed" ) ;
2007-08-16 01:29:18 +00:00
connect ( editor , "title_changed" , this , "editor_title_changed" ) ;
2007-07-16 20:22:38 +00:00
connect ( editor , "key_pressed" , this , "editor_key_pressed" ) ;
connect ( editor , "delete_clicked" , function ( event ) { self . delete _editor ( event , editor ) } ) ;
2007-08-07 01:48:43 +00:00
connect ( editor , "undelete_clicked" , function ( event ) { self . undelete _editor _via _trash ( event , editor ) } ) ;
2007-07-26 01:18:41 +00:00
connect ( editor , "changes_clicked" , function ( event ) { self . toggle _editor _changes ( event , editor ) } ) ;
2007-07-16 20:22:38 +00:00
connect ( editor , "options_clicked" , function ( event ) { self . toggle _editor _options ( event , editor ) } ) ;
connect ( editor , "focused" , this , "editor_focused" ) ;
2008-06-13 22:55:19 +00:00
connect ( editor , "mouse_hovered" , function ( target ) { self . editor _mouse _hovered ( editor , target ) } ) ;
2007-07-16 20:22:38 +00:00
}
connect ( editor , "load_editor" , this , "load_editor" ) ;
connect ( editor , "hide_clicked" , function ( event ) { self . hide _editor ( event , editor ) } ) ;
2008-06-02 21:16:35 +00:00
connect ( editor , "submit_form" , function ( form ) { self . submit _form ( form ) ; } ) ;
connect ( editor , "button_clicked" , function ( editor , button ) { self . editor _button _clicked ( editor , button ) ; } ) ;
2007-07-16 20:22:38 +00:00
2007-11-09 06:49:26 +00:00
this . clear _pulldowns ( ) ;
2007-09-05 18:49:28 +00:00
return editor ;
2007-07-16 20:22:38 +00:00
}
2009-01-22 21:05:18 +00:00
Wiki . prototype . resize _editor = function ( ) {
2009-01-22 21:30:00 +00:00
if ( Editor . shared _frame && Editor . shared _iframe . editor )
2009-01-22 21:05:18 +00:00
Editor . shared _iframe . editor . resize ( ) ;
2007-11-29 20:15:37 +00:00
}
2008-05-12 23:27:42 +00:00
Wiki . prototype . resize _toolbar = function ( ) {
var last _toolbar _button = getElement ( "insertOrderedList" ) ;
var current _toolbar _bottom = getElementPosition ( last _toolbar _button ) . y + getElementDimensions ( last _toolbar _button ) . h ;
var viewport _size = getViewportDimensions ( ) ;
var VIEWPORT _WIDTH _THRESHOLD = 1000 ;
// if the toolbar is large and the bottom of the toolbar is outside of the viewport or the
// viewport is too narrow, then make the toolbar smaller
if ( ! this . small _toolbar && ( current _toolbar _bottom > viewport _size . h || viewport _size . w < VIEWPORT _WIDTH _THRESHOLD ) ) {
this . large _toolbar _bottom = current _toolbar _bottom ;
this . small _toolbar = true ;
this . update _toolbar ( ) ;
// otherwise, if the toolbar is small and making the toolbar large would still fit within the
// viewport and the viewport is wide, then make the toolbar large again
} else if ( this . small _toolbar && this . large _toolbar _bottom <= viewport _size . h && viewport _size . w >= VIEWPORT _WIDTH _THRESHOLD ) {
if ( ! this . small _toolbar ) return ; // it's already big, so bail
this . small _toolbar = false ;
this . update _toolbar ( ) ;
}
}
2008-03-11 23:50:09 +00:00
Wiki . prototype . detect _font _resize = function ( ) {
if ( ! window . getComputedStyle ) return ;
var style = window . getComputedStyle ( getElement ( "content" ) , null ) ;
if ( ! style ) return ;
if ( style . fontSize == this . font _size )
return ;
this . font _size = style . fontSize ;
2009-01-22 21:05:18 +00:00
this . resize _editor ( ) ;
2008-03-11 23:50:09 +00:00
}
2008-03-11 00:48:37 +00:00
Wiki . prototype . editor _state _changed = function ( editor , link _clicked ) {
2007-07-16 20:22:38 +00:00
this . update _toolbar ( ) ;
2008-03-11 00:48:37 +00:00
if ( ! link _clicked )
this . display _link _pulldown ( editor ) ;
2008-05-13 22:52:20 +00:00
2008-07-29 23:38:35 +00:00
if ( editor . dirty ( ) ) {
var save _button = getElement ( "save_button" ) ;
if ( save _button && save _button . disabled ) {
save _button . disabled = false ;
save _button . value = "save" ;
}
}
2008-05-13 22:52:20 +00:00
signal ( this , "note_state_changed" , editor ) ;
2007-08-14 04:13:49 +00:00
}
2007-08-16 01:29:18 +00:00
Wiki . prototype . editor _title _changed = function ( editor , old _title , new _title ) {
2008-06-26 03:04:06 +00:00
if ( old _title )
delete this . open _editors [ old _title . toLowerCase ( ) ] ;
2007-08-16 01:29:18 +00:00
2007-10-22 20:52:04 +00:00
if ( new _title != null && ! editor . empty ( ) ) {
2008-06-26 03:04:06 +00:00
if ( new _title )
this . open _editors [ new _title . toLowerCase ( ) ] = editor ;
2008-04-09 23:31:30 +00:00
signal ( this , "note_renamed" , editor , new _title ) ;
2007-10-22 20:52:04 +00:00
}
2007-08-16 01:29:18 +00:00
}
2008-06-13 22:55:19 +00:00
Wiki . prototype . display _link _pulldown = function ( editor , link , ephemeral ) {
2008-02-19 21:15:09 +00:00
this . clear _messages ( ) ;
2007-09-04 21:37:48 +00:00
if ( ! editor . read _write ) {
this . clear _pulldowns ( ) ;
return ;
}
2007-08-30 20:17:10 +00:00
if ( ! link )
link = editor . find _link _at _cursor ( ) ;
2007-08-14 04:13:49 +00:00
2008-06-27 23:11:09 +00:00
// if there's no link at the current cursor location, bail
if ( ! link ) {
2007-08-14 04:13:49 +00:00
this . clear _pulldowns ( ) ;
return ;
}
2007-08-16 01:29:18 +00:00
var pulldown = link . pulldown ;
2008-06-27 23:11:09 +00:00
var query = parse _query ( link ) ;
var title = link _title ( link , query ) ;
// display a Suggest_pulldown once something is typed for the link title, as long as the link
// doesn't yet have a note_id
if ( ! pulldown && title . length > 0 && query . note _id == "new" ) {
this . clear _pulldowns ( ) ;
var self = this ;
2009-01-23 22:55:57 +00:00
var suggest _pulldown = new Suggest _pulldown ( this , this . notebook . object _id , this . invoker , link , editor . holder , title , editor . document ) ;
2008-06-27 23:11:09 +00:00
connect ( suggest _pulldown , "suggestion_selected" , function ( note ) {
self . update _link _with _suggestion ( editor , link , note )
} ) ;
return ;
}
// if there is a link but it was just started, bail
if ( link == editor . link _started && ! pulldown ) {
this . clear _pulldowns ( ) ;
return ;
}
if ( pulldown ) {
// if a Suggest_pulldown is open for the link, update the pulldown and bail
if ( pulldown . update _suggestions ) {
pulldown . update _suggestions ( title ) ;
return ;
// otherwise, just update the pulldown's position
} else {
pulldown . update _position ( ) ;
}
}
2007-08-14 04:13:49 +00:00
2008-06-13 22:55:19 +00:00
var link _contains _image = getElementsByTagAndClassName ( "img" , null , link ) ;
2007-08-14 04:13:49 +00:00
// if the cursor is now on a link, display a link pulldown if there isn't already one open
2008-06-13 22:55:19 +00:00
if ( link _title ( link ) . length > 0 || link _contains _image ) {
2007-08-14 04:13:49 +00:00
if ( ! pulldown ) {
this . clear _pulldowns ( ) ;
2008-02-18 20:08:07 +00:00
// display a different pulldown depending on whether the link is a note link or a file link
2008-02-05 19:45:11 +00:00
if ( link . target || ! /\/files\// . test ( link . href ) )
2008-11-25 00:58:59 +00:00
new Link _pulldown ( this , this . notebook . object _id , this . invoker , editor , link , ephemeral ) ;
2008-02-19 20:25:35 +00:00
else {
if ( /\/files\/new$/ . test ( link . href ) )
2008-11-25 00:58:59 +00:00
new Upload _pulldown ( this , this . notebook . object _id , this . invoker , editor , link , ephemeral ) ;
2008-02-19 20:25:35 +00:00
else
2008-11-25 00:58:59 +00:00
new File _link _pulldown ( this , this . notebook . object _id , this . invoker , editor , link , ephemeral ) ;
2008-02-19 20:25:35 +00:00
}
2007-08-14 04:13:49 +00:00
}
}
2007-07-16 20:22:38 +00:00
}
2008-06-27 23:11:09 +00:00
Wiki . prototype . update _link _with _suggestion = function ( editor , link , note ) {
link . innerHTML = note . title ;
// manually position the text cursor at the end of the link title
2009-01-22 23:30:17 +00:00
editor . position _cursor _after ( link ) ;
2008-06-27 23:11:09 +00:00
2008-11-25 00:58:59 +00:00
link . href = "/notebooks/" + this . notebook . object _id + "?note_id=" + note . object _id ;
2008-06-27 23:11:09 +00:00
link . pulldown . shutdown ( ) ;
link . pulldown = null ;
editor . focus ( ) ;
editor . end _link ( ) ;
this . display _link _pulldown ( editor , link ) ;
}
2008-03-29 08:31:34 +00:00
Wiki . prototype . editor _focused = function ( editor , synchronous ) {
2009-01-13 20:35:41 +00:00
if ( this . focused _editor && this . focused _editor != editor ) {
2009-01-12 22:19:32 +00:00
this . focused _editor . blur ( ) ;
2009-01-13 20:35:41 +00:00
this . clear _pulldowns ( ) ;
2007-07-16 20:22:38 +00:00
2009-01-23 06:33:32 +00:00
// if there is no focused editor anymore, release the iframe of the previously focused editor
if ( editor == null )
this . focused _editor . release _iframe ( ) ;
2009-01-22 23:30:17 +00:00
// if the formerly focused editor is completely empty, then remove it as the user leaves it and switches to this editor
if ( this . focused _editor . empty ( ) ) {
signal ( this , "note_removed" , this . focused _editor . id ) ;
this . focused _editor . shutdown ( ) ;
this . decrement _total _notes _count ( ) ;
this . display _empty _message ( ) ;
} else {
// when switching editors, save the one being left
this . save _editor ( null , null , null , synchronous ) ;
2007-07-16 20:22:38 +00:00
}
}
2009-01-22 22:23:07 +00:00
this . focused _editor = editor ;
this . update _toolbar ( ) ;
2009-01-23 06:33:32 +00:00
2007-07-16 20:22:38 +00:00
}
2008-11-10 20:32:52 +00:00
Wiki . prototype . make _byline = function ( username , creation , note _id ) {
2008-10-30 23:53:42 +00:00
if ( username == "anonymous" )
username = "admin" ;
2008-10-30 23:16:26 +00:00
if ( username )
var by = ' by ' + username ;
else
var by = '' ;
if ( creation )
var timestamp = ' on ' + this . brief _revision ( creation ) ;
else
var timestamp = '' ;
2008-11-10 20:32:52 +00:00
return '<p class="byline small_text">Posted' + by + timestamp +
' | <a href="' + window . location . pathname + '?note_id=' + note _id + '" target="_top">permalink</a>' ;
2008-10-30 23:16:26 +00:00
}
2008-06-13 22:55:19 +00:00
Wiki . prototype . editor _mouse _hovered = function ( editor , target ) {
2008-06-16 23:22:50 +00:00
var pulldowns = getElementsByTagAndClassName ( "div" , "pulldown" ) ;
// if the mouse is hovering over a link, and no pulldowns are open, open a link pulldown
if ( target . nodeName == "A" && pulldowns . length == 0 )
2008-06-13 22:55:19 +00:00
this . display _link _pulldown ( editor , target , true ) ;
// the mouse is hovering over something else, so clear all ephemeral pulldowns
else
this . clear _pulldowns ( true ) ;
}
2007-11-09 20:07:32 +00:00
Wiki . prototype . key _pressed = function ( event ) {
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _ONLY )
2007-11-12 11:26:10 +00:00
return ;
2007-11-09 20:07:32 +00:00
var code = event . key ( ) . code ;
if ( event . modifier ( ) . ctrl ) {
2008-12-03 23:11:49 +00:00
// ctrl-m: make a new note
if ( code == 77 )
2007-11-09 20:07:32 +00:00
this . create _blank _editor ( event ) ;
}
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . editor _key _pressed = function ( editor , event ) {
2008-11-10 20:32:52 +00:00
if ( editor . document && editor . read _write ) {
var byline = getFirstElementByTagAndClassName ( "p" , "byline" , editor . document ) ;
if ( byline ) {
removeElement ( byline ) ;
editor . resize ( ) ;
}
}
2007-07-16 20:22:38 +00:00
var code = event . key ( ) . code ;
2008-07-12 21:24:00 +00:00
2007-07-16 20:22:38 +00:00
if ( event . modifier ( ) . ctrl ) {
2008-10-03 06:02:08 +00:00
// ctrl-backtick: message with frame HTML contents (for debugging)
2007-07-16 20:22:38 +00:00
if ( code == 192 || code == 96 ) {
2008-10-03 06:02:08 +00:00
this . display _message ( editor . contents ( ) ) ;
2007-07-16 20:22:38 +00:00
event . stop ( ) ;
// ctrl-b: bold
} else if ( code == 66 ) {
this . toggle _button ( event , "bold" ) ;
// ctrl-i: italic
} else if ( code == 73 ) {
this . toggle _button ( event , "italic" ) ;
2007-08-27 21:01:42 +00:00
// ctrl-u: underline
} else if ( code == 85 ) {
this . toggle _button ( event , "underline" ) ;
2008-05-14 00:07:02 +00:00
// ctrl-s: strikethrough
} else if ( code == 83 ) {
this . toggle _button ( event , "strikethrough" ) ;
2007-08-27 21:09:39 +00:00
// ctrl-period: unordered list
} else if ( code == 190 ) {
2007-07-16 20:22:38 +00:00
this . toggle _button ( event , "insertUnorderedList" ) ;
2007-11-09 20:07:32 +00:00
// ctrl-1: ordered list
2007-07-16 20:22:38 +00:00
} else if ( code == 49 ) {
this . toggle _button ( event , "insertOrderedList" ) ;
2007-11-09 20:07:32 +00:00
// ctrl-l: link
2007-07-18 20:28:42 +00:00
} else if ( code == 76 ) {
2007-07-16 20:22:38 +00:00
this . toggle _link _button ( event ) ;
2008-12-03 23:11:49 +00:00
// ctrl-m: make a new note
} else if ( code == 77 ) {
2007-07-16 20:22:38 +00:00
this . create _blank _editor ( event ) ;
2007-07-17 01:21:31 +00:00
// ctrl-h: hide note
2007-07-16 20:22:38 +00:00
} else if ( code == 72 ) {
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
if ( ! editor . deleted _from _id )
2007-09-05 18:57:50 +00:00
this . hide _editor ( event ) ;
2007-07-17 01:21:31 +00:00
// ctrl-d: delete note
2007-07-16 20:22:38 +00:00
} else if ( code == 68 ) {
this . delete _editor ( event ) ;
}
2008-07-03 23:56:17 +00:00
// shift-tab: outdent
} else if ( event . modifier ( ) . shift && code == 9 ) {
2008-07-12 21:24:00 +00:00
// ignore shift-tab here if a Suggest_pulldown is open
var link = editor . find _link _at _cursor ( ) ;
2008-07-12 21:24:23 +00:00
if ( link && link . pulldown && link . pulldown . visible && link . pulldown . visible ( ) )
2008-07-12 21:24:00 +00:00
return ;
2008-07-03 23:56:17 +00:00
editor . exec _command ( "outdent" ) ;
event . stop ( ) ;
// tab: outdent
} else if ( code == 9 ) {
2008-07-12 21:24:00 +00:00
// ignore tab here if a Suggest_pulldown is open
var link = editor . find _link _at _cursor ( ) ;
2008-07-12 21:24:23 +00:00
if ( link && link . pulldown && link . pulldown . visible && link . pulldown . visible ( ) )
2008-07-12 21:24:00 +00:00
return ;
2008-07-03 23:56:17 +00:00
editor . exec _command ( "indent" ) ;
event . stop ( ) ;
// IE: hitting space while making a link shouldn't end the link
} else if ( code == 32 && editor . document . selection && editor . state _enabled ( "a" ) ) {
var range = editor . document . selection . createRange ( ) ;
range . text = " " ;
2007-07-16 20:22:38 +00:00
event . stop ( ) ;
2008-06-29 22:19:59 +00:00
// IE: hitting backspace while making a link shouldn't end the link
2008-06-29 22:25:09 +00:00
} else if ( code == 8 && editor . document . selection ) {
2008-06-29 22:19:59 +00:00
var range = editor . document . selection . createRange ( ) ;
range . moveStart ( "character" , - 1 ) ;
2008-12-04 00:27:01 +00:00
if ( range . text != "" ) {
range . text = "" ;
event . stop ( ) ;
}
2007-07-16 20:22:38 +00:00
}
}
2008-06-22 05:13:52 +00:00
Wiki . prototype . get _toolbar _image _dir = function ( always _small ) {
2008-05-12 23:27:42 +00:00
var toolbar _image _dir = IMAGE _DIR + "toolbar/" ;
2008-06-22 05:13:52 +00:00
if ( always _small || this . small _toolbar )
2008-05-12 23:27:42 +00:00
toolbar _image _dir += "small/" ;
return toolbar _image _dir ;
}
Wiki . prototype . resize _toolbar _button = function ( button ) {
var SMALL _BUTTON _SIZE = 20 ;
var LARGE _BUTTON _SIZE = 40 ;
var button _size = getElementDimensions ( button ) ;
2008-06-22 05:13:52 +00:00
if ( this . small _toolbar || button . always _small ) {
2008-05-12 23:27:42 +00:00
if ( button _size . w == SMALL _BUTTON _SIZE ) return false ;
setElementDimensions ( button , { "w" : SMALL _BUTTON _SIZE , "h" : SMALL _BUTTON _SIZE } ) ;
} else {
if ( button _size . w == LARGE _BUTTON _SIZE ) return false ;
setElementDimensions ( button , { "w" : LARGE _BUTTON _SIZE , "h" : LARGE _BUTTON _SIZE } ) ;
}
return true ;
}
2008-06-22 05:13:52 +00:00
Wiki . prototype . make _image _button = function ( name , filename _prefix , always _small ) {
2007-10-25 23:19:57 +00:00
var button = getElement ( name ) ;
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = this . get _toolbar _image _dir ( always _small ) ;
2007-10-25 23:19:57 +00:00
if ( ! filename _prefix )
filename _prefix = name ;
2008-05-12 23:27:42 +00:00
button . name = name ;
2007-10-25 23:19:57 +00:00
button . filename _prefix = filename _prefix ;
2008-06-22 05:13:52 +00:00
button . always _small = always _small ;
2007-10-25 23:19:57 +00:00
2008-05-12 23:27:42 +00:00
this . resize _toolbar _button ( button ) ;
this . connect _image _button ( button ) ;
}
Wiki . prototype . connect _image _button = function ( button , filename _prefix ) {
var self = this ;
2007-10-25 23:19:57 +00:00
connect ( button , "onmouseover" , function ( event ) {
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = self . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
if ( /_down/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_hover.png" ;
2007-10-25 23:19:57 +00:00
} ) ;
connect ( button , "onmouseout" , function ( event ) {
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = self . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
if ( /_down/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button.png" ;
2007-10-25 23:19:57 +00:00
} ) ;
2008-11-14 20:34:06 +00:00
if ( button . name == "newNote" || button . name == "new_notebook" || button . name == "new_note_tree_link" ) {
2007-10-25 23:19:57 +00:00
connect ( button , "onmousedown" , function ( event ) {
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = self . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down.png" ;
2007-10-25 23:19:57 +00:00
} ) ;
connect ( button , "onmouseup" , function ( event ) {
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = self . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button.png" ;
2007-10-25 23:19:57 +00:00
} ) ;
}
}
Wiki . prototype . down _image _button = function ( name ) {
var button = getElement ( name ) ;
2008-10-27 23:23:27 +00:00
if ( ! button )
return ;
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = this . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
2008-05-13 04:02:31 +00:00
if ( ! this . resize _toolbar _button ( button ) && /_down/ . test ( button . src ) )
2007-10-31 21:03:06 +00:00
return ;
2007-10-25 23:19:57 +00:00
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down.png" ;
2007-10-25 23:19:57 +00:00
}
Wiki . prototype . up _image _button = function ( name ) {
var button = getElement ( name ) ;
2008-10-27 23:23:27 +00:00
if ( ! button )
return ;
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = this . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
2008-05-13 04:02:31 +00:00
if ( ! this . resize _toolbar _button ( button ) && ! /_down/ . test ( button . src ) )
2007-10-31 21:03:06 +00:00
return ;
2007-10-25 23:19:57 +00:00
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button.png" ;
2007-10-25 23:19:57 +00:00
}
Wiki . prototype . toggle _image _button = function ( name ) {
var button = getElement ( name ) ;
2008-10-27 23:23:27 +00:00
if ( ! button )
return ;
2008-06-22 05:13:52 +00:00
var toolbar _image _dir = this . get _toolbar _image _dir ( button . always _small ) ;
2007-10-25 23:19:57 +00:00
if ( /_down/ . test ( button . src ) ) {
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button.png" ;
this . resize _toolbar _button ( button ) ;
2007-10-25 23:19:57 +00:00
return false ;
} else {
if ( /_hover/ . test ( button . src ) )
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down_hover.png" ;
2007-10-25 23:19:57 +00:00
else
2008-05-12 23:27:42 +00:00
button . src = toolbar _image _dir + button . filename _prefix + "_button_down.png" ;
this . resize _toolbar _button ( button ) ;
2007-10-25 23:19:57 +00:00
return true ;
}
}
2007-11-30 01:43:06 +00:00
Wiki . prototype . toggle _button = function ( event , button _id ) {
2007-07-16 20:22:38 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-07-31 22:53:57 +00:00
if ( this . focused _editor && this . focused _editor . read _write ) {
2007-07-16 20:22:38 +00:00
this . focused _editor . focus ( ) ;
2007-11-30 01:43:06 +00:00
if ( button _id == "title" )
this . focused _editor . exec _command ( "h3" ) ;
else
this . focused _editor . exec _command ( button _id ) ;
2007-07-16 20:22:38 +00:00
this . focused _editor . resize ( ) ;
2007-11-30 01:43:06 +00:00
this . toggle _image _button ( button _id ) ;
2007-07-16 20:22:38 +00:00
}
event . stop ( ) ;
}
2007-11-30 01:00:03 +00:00
Wiki . prototype . update _button = function ( button _id , state _name , node _names ) {
2008-05-14 08:00:51 +00:00
if ( state _name && node _names && this . focused _editor . state _enabled ( state _name , node _names ) )
2007-10-25 23:19:57 +00:00
this . down _image _button ( button _id ) ;
2007-07-16 20:22:38 +00:00
else
2007-10-25 23:19:57 +00:00
this . up _image _button ( button _id ) ;
2007-07-16 20:22:38 +00:00
}
Wiki . prototype . update _toolbar = function ( ) {
2008-05-14 08:00:51 +00:00
var node _names = null ;
var link = null ;
2008-06-09 20:32:27 +00:00
// a read-only notebook doesn't have a visible toolbar
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _ONLY )
2008-06-09 20:32:27 +00:00
return ;
2008-05-14 08:00:51 +00:00
if ( this . focused _editor ) {
node _names = this . focused _editor . current _node _names ( ) ;
link = this . focused _editor . find _link _at _cursor ( ) ;
}
2007-11-30 01:00:03 +00:00
2008-05-12 23:27:42 +00:00
this . update _button ( "newNote" ) ;
2007-11-30 01:00:03 +00:00
this . update _button ( "bold" , "b" , node _names ) ;
this . update _button ( "italic" , "i" , node _names ) ;
this . update _button ( "underline" , "u" , node _names ) ;
2008-05-14 00:07:02 +00:00
this . update _button ( "strikethrough" , "strike" , node _names ) ;
2008-12-11 07:21:44 +00:00
this . update _button ( "font" , "font" , node _names ) ;
2007-11-30 01:00:03 +00:00
this . update _button ( "title" , "h3" , node _names ) ;
this . update _button ( "insertUnorderedList" , "ul" , node _names ) ;
this . update _button ( "insertOrderedList" , "ol" , node _names ) ;
2008-02-01 19:17:10 +00:00
if ( link ) {
// determine whether the link is a note link or a file link
if ( link . target || ! /\/files\// . test ( link . href ) ) {
this . down _image _button ( "createLink" ) ;
this . up _image _button ( "attachFile" ) ;
} else {
this . up _image _button ( "createLink" ) ;
this . down _image _button ( "attachFile" ) ;
}
} else {
this . up _image _button ( "createLink" ) ;
this . up _image _button ( "attachFile" ) ;
}
2007-07-16 20:22:38 +00:00
}
Wiki . prototype . toggle _link _button = function ( event ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-08-30 20:17:10 +00:00
var link = null ;
2007-07-16 20:22:38 +00:00
2007-07-31 22:53:57 +00:00
if ( this . focused _editor && this . focused _editor . read _write ) {
2007-07-16 20:22:38 +00:00
this . focused _editor . focus ( ) ;
2007-10-25 23:19:57 +00:00
if ( this . toggle _image _button ( "createLink" ) )
2007-11-27 21:28:25 +00:00
link = this . focused _editor . start _link ( ) ;
2007-07-16 20:22:38 +00:00
else
2007-08-30 20:17:10 +00:00
link = this . focused _editor . end _link ( ) ;
2007-08-14 04:13:49 +00:00
2008-03-10 23:15:33 +00:00
if ( link && link . parentNode != null ) {
2007-11-27 21:28:25 +00:00
var self = this ;
2008-08-01 22:50:49 +00:00
this . resolve _link ( link _title ( link ) , link , false , function ( summary ) {
2007-11-27 21:28:25 +00:00
self . display _link _pulldown ( self . focused _editor , link ) ;
} ) ;
} else {
this . display _link _pulldown ( this . focused _editor ) ;
}
2007-07-16 20:22:38 +00:00
}
event . stop ( ) ;
}
2008-01-31 21:52:32 +00:00
Wiki . prototype . toggle _attach _button = function ( event ) {
if ( this . focused _editor && this . focused _editor . read _write ) {
this . focused _editor . focus ( ) ;
2008-02-19 20:25:35 +00:00
if ( this . toggle _image _button ( "attachFile" ) )
2008-02-22 23:03:10 +00:00
var link = this . focused _editor . start _file _link ( ) ;
2008-02-19 20:25:35 +00:00
else
2008-02-22 23:03:10 +00:00
var link = this . focused _editor . end _link ( ) ;
2008-01-31 21:52:32 +00:00
2008-02-19 20:25:35 +00:00
// if a pulldown is already open, then just close it
2008-01-31 21:52:32 +00:00
var pulldown _id = "upload_" + this . focused _editor . id ;
var existing _div = getElement ( pulldown _id ) ;
2008-02-19 20:25:35 +00:00
if ( ! existing _div ) {
pulldown _id = "file_link_" + this . focused _editor . id ;
existing _div = getElement ( pulldown _id ) ;
}
2008-01-31 21:52:32 +00:00
if ( existing _div ) {
existing _div . pulldown . shutdown ( ) ;
2008-06-27 23:11:09 +00:00
existing _div . pulldown = null ;
2008-01-31 21:52:32 +00:00
return ;
}
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2008-11-25 00:58:59 +00:00
new Upload _pulldown ( this , this . notebook . object _id , this . invoker , this . focused _editor , link ) ;
2008-01-31 21:52:32 +00:00
}
event . stop ( ) ;
}
2008-12-11 07:21:44 +00:00
Wiki . prototype . toggle _font _button = function ( event ) {
if ( this . focused _editor && this . focused _editor . read _write ) {
this . focused _editor . focus ( ) ;
// if a pulldown is already open, then just close it
var existing _div = getElement ( "font_pulldown" ) ;
if ( existing _div ) {
this . up _image _button ( "font" ) ;
existing _div . pulldown . shutdown ( ) ;
existing _div . pulldown = null ;
return ;
}
this . down _image _button ( "font" ) ;
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
new Font _pulldown ( this , this . notebook . object _id , this . invoker , event . target ( ) , this . focused _editor ) ;
}
event . stop ( ) ;
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . hide _editor = function ( event , editor ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-10-19 20:24:16 +00:00
if ( editor == this . focused _editor )
this . focused _editor = null ;
2009-01-23 00:54:56 +00:00
if ( this . focused _editor )
2009-01-23 06:33:32 +00:00
this . editor _focused ( null ) ;
2007-10-19 20:24:16 +00:00
2007-07-16 20:22:38 +00:00
if ( ! editor ) {
editor = this . focused _editor ;
this . focused _editor = null ;
}
if ( editor ) {
2008-03-12 01:06:50 +00:00
var id = editor . id ;
2007-10-19 20:24:16 +00:00
// if the editor to hide is completely empty, then simply remove it
2009-01-22 23:30:17 +00:00
if ( editor . empty ( ) ) {
2008-04-09 23:31:30 +00:00
signal ( this , "note_removed" , editor . id ) ;
2007-10-19 20:24:16 +00:00
editor . shutdown ( ) ;
this . decrement _total _notes _count ( ) ;
2008-05-06 05:47:31 +00:00
this . display _empty _message ( ) ;
2007-10-19 20:24:16 +00:00
} else {
// before hiding an editor, save it
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write != NOTEBOOK _READ _ONLY && editor . read _write ) {
2008-05-06 05:47:31 +00:00
var self = this ;
this . save _editor ( editor , false , function ( ) {
editor . shutdown ( ) ;
self . display _empty _message ( ) ;
} ) ;
2008-05-06 05:50:49 +00:00
} else {
editor . shutdown ( ) ;
2008-05-06 05:52:14 +00:00
this . display _empty _message ( ) ;
2008-05-06 05:47:31 +00:00
}
2007-10-19 20:24:16 +00:00
}
2007-07-16 20:22:38 +00:00
}
event . stop ( ) ;
}
Wiki . prototype . delete _editor = function ( event , editor ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2009-01-23 00:54:56 +00:00
if ( this . focused _editor )
2009-01-23 06:33:32 +00:00
this . editor _focused ( null ) ;
2009-01-23 00:54:56 +00:00
2007-07-16 20:22:38 +00:00
if ( ! editor ) {
editor = this . focused _editor ;
this . focused _editor = null ;
}
2008-01-22 23:29:16 +00:00
if ( ! editor ) {
event . stop ( ) ;
return ;
}
2007-07-16 20:22:38 +00:00
2008-01-22 23:29:16 +00:00
if ( this . startup _notes [ editor . id ] )
delete this . startup _notes [ editor . id ] ;
2007-08-07 01:48:43 +00:00
2008-01-22 23:29:16 +00:00
var self = this ;
this . save _editor ( editor , false , function ( ) {
2008-10-24 18:51:19 +00:00
if ( self . notebook . read _write != NOTEBOOK _READ _ONLY && editor . read _write ) {
2008-01-22 23:29:16 +00:00
self . invoker . invoke ( "/notebooks/delete_note" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : self . notebook . object _id ,
2007-07-17 01:21:31 +00:00
"note_id" : editor . id
2007-09-20 22:26:43 +00:00
} , function ( result ) { self . display _storage _usage ( result . storage _bytes ) ; } ) ;
2007-07-16 20:22:38 +00:00
}
2008-01-22 23:29:16 +00:00
if ( editor == self . focused _editor )
self . focused _editor = null ;
2007-07-16 20:22:38 +00:00
2009-01-22 23:30:17 +00:00
if ( self . notebook . trash _id && ! editor . empty ( ) ) {
2007-08-23 23:56:42 +00:00
var undo _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "undo" ,
"title" : "undo deletion"
} ) ;
2007-09-05 07:34:59 +00:00
var trash _link = createDOM ( "a" , {
2008-01-22 23:29:16 +00:00
"href" : "/notebooks/" + self . notebook . trash _id + "?parent_id=" + self . notebook . object _id
2007-09-05 07:34:59 +00:00
} , "trash" ) ;
2009-01-23 22:55:57 +00:00
var message _div = self . display _message ( "The note has been moved to the" , [ trash _link , ". " , undo _button ] , editor . holder ) ;
2007-11-09 06:49:26 +00:00
connect ( undo _button , "onclick" , function ( event ) { self . undelete _editor _via _undo ( event , editor , message _div ) ; } ) ;
2007-08-23 23:56:42 +00:00
}
2007-07-16 20:22:38 +00:00
2008-04-09 23:31:30 +00:00
signal ( self , "note_removed" , editor . id ) ;
2007-10-22 20:52:04 +00:00
2007-08-23 23:56:42 +00:00
editor . shutdown ( ) ;
2008-01-22 23:29:16 +00:00
self . decrement _total _notes _count ( ) ;
self . display _empty _message ( ) ;
2008-04-15 19:40:36 +00:00
} , false , true ) ;
2007-08-07 01:48:43 +00:00
event . stop ( ) ;
}
Wiki . prototype . undelete _editor _via _trash = function ( event , editor ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
if ( ! editor ) {
editor = this . focused _editor ;
this . focused _editor = null ;
}
if ( editor ) {
if ( this . startup _notes [ editor . id ] )
delete this . startup _notes [ editor . id ] ;
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write != NOTEBOOK _READ _ONLY && editor . read _write ) {
2007-09-20 22:26:43 +00:00
var self = this ;
2007-08-07 01:48:43 +00:00
this . invoker . invoke ( "/notebooks/undelete_note" , "POST" , {
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
"notebook_id" : editor . deleted _from _id ,
2007-08-07 01:48:43 +00:00
"note_id" : editor . id
2007-09-20 22:26:43 +00:00
} , function ( result ) { self . display _storage _usage ( result . storage _bytes ) ; } ) ;
2007-08-07 01:48:43 +00:00
}
if ( editor == this . focused _editor )
this . focused _editor = null ;
2008-04-09 23:31:30 +00:00
signal ( this , "note_removed" , editor . id ) ;
2007-10-22 20:52:04 +00:00
2007-08-07 01:48:43 +00:00
editor . shutdown ( ) ;
2007-10-19 20:24:16 +00:00
this . decrement _total _notes _count ( ) ;
2007-09-05 18:49:28 +00:00
this . display _empty _message ( ) ;
2007-08-07 01:48:43 +00:00
}
event . stop ( ) ;
}
2007-11-09 06:49:26 +00:00
Wiki . prototype . undelete _editor _via _undo = function ( event , editor , position _after ) {
2007-08-07 01:48:43 +00:00
if ( editor ) {
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write != NOTEBOOK _READ _ONLY && editor . read _write ) {
2007-09-20 22:26:43 +00:00
var self = this ;
2007-08-07 01:48:43 +00:00
this . invoker . invoke ( "/notebooks/undelete_note" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-08-07 01:48:43 +00:00
"note_id" : editor . id
2008-04-15 20:22:06 +00:00
} , function ( result ) {
self . display _storage _usage ( result . storage _bytes ) ;
self . clear _messages ( ) ;
self . clear _pulldowns ( ) ;
2008-11-15 01:01:55 +00:00
self . startup _notes [ editor . id ] = true ;
self . increment _total _notes _count ( ) ;
self . load _editor ( "Note not found." , editor . id , null , null , null , position _after ) ;
2008-04-15 20:22:06 +00:00
} ) ;
2007-08-07 01:48:43 +00:00
}
}
2007-07-16 20:22:38 +00:00
event . stop ( ) ;
}
2007-11-09 06:54:45 +00:00
Wiki . prototype . undelete _editor _via _undelete = function ( event , note _id , position _after ) {
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write != NOTEBOOK _READ _ONLY ) {
2007-10-22 23:17:56 +00:00
var self = this ;
this . invoker . invoke ( "/notebooks/undelete_note" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-10-22 23:17:56 +00:00
"note_id" : note _id
2008-04-15 20:22:06 +00:00
} , function ( result ) {
self . display _storage _usage ( result . storage _bytes ) ;
self . clear _messages ( ) ;
self . clear _pulldowns ( ) ;
2008-11-15 01:01:55 +00:00
self . startup _notes [ note _id ] = true ;
self . increment _total _notes _count ( ) ;
self . load _editor ( "Note not found." , note _id , null , null , null , position _after ) ;
2008-04-15 20:22:06 +00:00
} ) ;
2007-10-22 23:17:56 +00:00
}
event . stop ( ) ;
}
2007-11-17 22:55:13 +00:00
Wiki . prototype . undelete _notebook = function ( event , notebook _id ) {
2007-11-17 04:21:48 +00:00
this . invoker . invoke ( "/notebooks/undelete" , "POST" , {
2007-11-17 04:31:19 +00:00
"notebook_id" : notebook _id
2007-11-17 04:21:48 +00:00
} ) ;
event . stop ( ) ;
}
2007-10-22 23:17:56 +00:00
2007-08-23 23:56:42 +00:00
Wiki . prototype . compare _versions = function ( event , editor , previous _revision ) {
this . clear _pulldowns ( ) ;
2008-05-03 04:29:23 +00:00
// display a diff between the two revisions for examination by the user
2009-01-23 22:55:57 +00:00
this . load _editor ( editor . title , editor . id , editor . revision , previous _revision , editor . closed ? null : editor . holder ) ;
2007-08-23 23:56:42 +00:00
}
2008-04-15 19:40:36 +00:00
Wiki . prototype . save _editor = function ( editor , fire _and _forget , callback , synchronous , suppress _save _signal ) {
2007-07-16 20:22:38 +00:00
if ( ! editor )
editor = this . focused _editor ;
2007-07-26 01:18:41 +00:00
var self = this ;
2009-01-22 23:30:17 +00:00
if ( editor && editor . read _write && ! editor . empty ( ) && ! editor . closed && editor . dirty ( ) ) {
2008-11-06 00:13:26 +00:00
editor . scrape _title ( ) ;
2007-07-17 01:21:31 +00:00
this . invoker . invoke ( "/notebooks/save_note" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-07-17 01:21:31 +00:00
"note_id" : editor . id ,
2007-07-16 20:22:38 +00:00
"contents" : editor . contents ( ) ,
2007-08-23 23:56:42 +00:00
"startup" : editor . startup ,
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
"previous_revision" : editor . revision ? editor . revision : "None"
2007-09-20 22:26:43 +00:00
} , function ( result ) {
self . update _editor _revisions ( result , editor ) ;
self . display _storage _usage ( result . storage _bytes ) ;
2008-03-05 02:56:58 +00:00
editor . mark _clean ( ) ;
2008-05-06 20:27:10 +00:00
2008-07-29 23:38:35 +00:00
var save _button = getElement ( "save_button" ) ;
2008-11-21 20:56:06 +00:00
if ( save _button && self . focused _editor && ! self . focused _editor . dirty ( ) ) {
2008-07-29 23:38:35 +00:00
save _button . disabled = true ;
save _button . value = "saved" ;
}
2008-05-06 20:27:10 +00:00
if ( editor . startup )
self . startup _notes [ editor . id ] = true ;
else if ( self . startup _notes [ editor . id ] )
delete self . startup _notes [ editor . id ] ;
2008-11-17 21:33:21 +00:00
// special case to rename a forum notebook when its first note is renamed
2008-11-18 06:59:57 +00:00
if ( result . rank == 0 && self . notebook _has _tag ( self . notebook , "forum" ) )
2008-10-30 22:26:27 +00:00
self . end _notebook _rename ( editor . title , true ) ;
2008-01-22 23:29:16 +00:00
if ( callback )
callback ( ) ;
2008-04-15 19:40:36 +00:00
if ( ! suppress _save _signal )
signal ( self , "note_saved" , editor ) ;
2008-03-29 08:31:34 +00:00
} , null , synchronous , fire _and _forget ) ;
2008-01-22 23:29:16 +00:00
} else {
2008-07-30 02:05:34 +00:00
var save _button = getElement ( "save_button" ) ;
2008-11-21 20:56:06 +00:00
if ( save _button && this . focused _editor && ! this . focused _editor . dirty ( ) ) {
2008-07-30 02:05:34 +00:00
save _button . disabled = true ;
save _button . value = "saved" ;
}
2008-01-22 23:29:16 +00:00
if ( callback )
callback ( ) ;
2007-07-26 01:18:41 +00:00
}
}
Wiki . prototype . update _editor _revisions = function ( result , editor ) {
2007-08-23 23:56:42 +00:00
// if there's not a newly saved revision, then the contents are unchanged, so bail
if ( ! result . new _revision )
return ;
2007-07-26 01:18:41 +00:00
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
var client _previous _revision = editor . revision ;
2008-01-04 04:45:43 +00:00
editor . revision = result . new _revision . revision ;
2007-08-23 23:56:42 +00:00
// if the server's idea of the previous revision doesn't match the client's, then someone has
// gone behind our back and saved the editor's note from another window
2008-01-22 23:29:16 +00:00
if ( result . previous _revision && result . previous _revision . revision != client _previous _revision ) {
2007-08-23 23:56:42 +00:00
var compare _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "compare versions" ,
"title" : "compare your version with the modified version"
} ) ;
2008-01-04 21:50:11 +00:00
this . display _error (
'Your changes to the note titled "' + editor . title +
2008-07-11 22:02:28 +00:00
'" have overwritten changes made in another window by ' + ( result . previous _revision . username || 'you' ) + '.' ,
2009-01-23 22:55:57 +00:00
[ compare _button ] , editor . holder
2008-01-04 21:50:11 +00:00
) ;
2007-08-23 23:56:42 +00:00
var self = this ;
connect ( compare _button , "onclick" , function ( event ) {
2008-01-04 04:45:43 +00:00
self . compare _versions ( event , editor , result . previous _revision . revision ) ;
2007-08-23 23:56:42 +00:00
} ) ;
2008-01-04 04:45:43 +00:00
if ( ! editor . user _revisions || editor . user _revisions . length == 0 )
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
return ;
2008-01-04 04:45:43 +00:00
editor . user _revisions . push ( result . previous _revision ) ;
2007-07-16 20:22:38 +00:00
}
2007-08-23 23:56:42 +00:00
// add the new revision to the editor's revisions list
2008-01-04 04:45:43 +00:00
if ( ! editor . user _revisions || editor . user _revisions . length == 0 )
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
return ;
2008-01-04 04:45:43 +00:00
editor . user _revisions . push ( result . new _revision ) ;
2007-07-16 20:22:38 +00:00
}
2008-06-02 21:16:35 +00:00
Wiki . prototype . submit _form = function ( form ) {
2008-06-04 03:19:07 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2008-06-02 21:16:35 +00:00
var self = this ;
var args = { }
var url = form . getAttribute ( "target" ) ;
var callback = null ;
if ( url == "/users/signup" ) {
args [ "invite_id" ] = this . invite _id ;
args [ "rate_plan" ] = this . signup _plan ;
args [ "yearly" ] = this . yearly ;
} else if ( url == "/users/login" ) {
args [ "invite_id" ] = this . invite _id ;
2008-07-26 00:05:13 +00:00
args [ "after_login" ] = this . after _login ;
2008-06-02 21:16:35 +00:00
} else if ( url == "/users/send_invites" ) {
callback = function ( result ) {
if ( ! result . invites ) return ;
self . invites = result . invites ;
self . share _notebook ( ) ;
}
} else if ( url == "/users/update_settings" ) {
2008-06-02 21:19:34 +00:00
callback = function ( result ) {
2008-10-24 18:51:19 +00:00
self . user . email _address = result . email _address || "" ;
2008-06-02 21:19:34 +00:00
self . display _message ( "Your account settings have been updated." ) ;
}
2008-06-06 21:46:29 +00:00
} else if ( url == "/users/signup_group_member" ) {
callback = function ( result ) {
var group _id = getFirstElementByTagAndClassName ( "input" , "group_id" , form ) . value ;
self . invoker . invoke ( "/groups/load_users" , "GET" , {
"group_id" : group _id
} , function ( result ) {
self . display _group _settings ( result ) ;
} ) ;
}
2008-07-11 21:41:48 +00:00
} else if ( url == "/notebooks/revert_note" ) {
callback = function ( result ) {
2009-01-12 22:19:32 +00:00
var editor = editor _by _id ( form . note _id . value ) ;
2008-07-11 21:41:48 +00:00
2009-01-12 22:19:32 +00:00
if ( editor ) {
2008-07-11 21:41:48 +00:00
self . update _editor _revisions ( result , editor ) ;
editor . mark _clean ( ) ;
if ( result . new _revision ) {
2009-01-13 21:38:35 +00:00
if ( editor . document && editor . document . body )
editor . document . body . innerHTML = result . contents ;
else if ( editor . div )
editor . div . innerHTML = result . contents ;
2008-07-11 21:41:48 +00:00
editor . resize ( ) ;
2008-07-12 00:12:52 +00:00
editor . scrape _title ( ) ;
2008-07-11 21:41:48 +00:00
}
2008-09-08 22:44:24 +00:00
editor . highlight ( ) ;
2008-07-11 21:41:48 +00:00
signal ( self , "note_saved" , editor ) ;
}
2009-01-13 21:38:35 +00:00
if ( result . new _revision )
self . display _message ( "The note has been reverted to an earlier revision." , [ ] ,
2009-01-23 22:55:57 +00:00
editor && editor . holder || null ) ;
2009-01-13 21:38:35 +00:00
else
self . display _message ( "The note is already at that revision." , [ ] ,
2009-01-23 22:55:57 +00:00
editor && editor . holder || null ) ;
2009-01-13 21:38:35 +00:00
2008-07-11 21:41:48 +00:00
self . display _storage _usage ( result . storage _bytes ) ;
}
2008-06-02 21:16:35 +00:00
}
this . invoker . invoke ( url , "POST" , args , callback , form ) ;
}
Wiki . prototype . editor _button _clicked = function ( editor , button ) {
2008-06-04 03:19:07 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2008-06-03 02:53:39 +00:00
var self = this ;
2008-06-02 21:16:35 +00:00
if ( hasElementClass ( button , "revoke_button" ) ) {
var invite _id = button . id . split ( "_" ) . pop ( ) ;
this . invoker . invoke ( "/users/revoke_invite" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2008-06-02 21:16:35 +00:00
"invite_id" : invite _id
} , function ( result ) {
if ( ! result . invites ) return ;
self . invites = result . invites ;
self . share _notebook ( ) ;
} ) ;
2008-06-03 02:53:39 +00:00
} else if ( hasElementClass ( button , "admin_button" ) ) {
var group _id = button . id . split ( "_" ) . pop ( ) ;
this . invoker . invoke ( "/groups/load_users" , "GET" , {
"group_id" : group _id
} , function ( result ) {
self . display _group _settings ( result ) ;
} ) ;
2008-06-04 03:19:07 +00:00
} else if ( hasElementClass ( button , "remove_user_button" ) ) {
var id _pieces = button . id . split ( "_" ) ;
var group _id = id _pieces . pop ( ) ;
var user _id = id _pieces . pop ( ) ;
this . invoker . invoke ( "/users/remove_group" , "POST" , {
"user_id_to_remove" : user _id ,
"group_id" : group _id
} , function ( result ) {
self . invoker . invoke ( "/groups/load_users" , "GET" , {
"group_id" : group _id
} , function ( result ) {
self . display _group _settings ( result ) ;
} ) ;
} ) ;
2008-06-02 21:16:35 +00:00
}
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . search = function ( event ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
var self = this ;
2007-08-17 22:26:02 +00:00
this . invoker . invoke ( "/notebooks/search" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id
2007-08-17 22:26:02 +00:00
} ,
2007-09-10 20:04:46 +00:00
function ( result ) { self . display _search _results ( result ) ; } ,
2007-07-16 20:22:38 +00:00
"search_form"
) ;
event . stop ( ) ;
}
2008-04-04 05:39:40 +00:00
Wiki . prototype . search _focused = function ( event ) {
var search _text = getElement ( "search_text" ) ;
if ( search _text . value == 'search' )
search _text . value = '' ;
}
2008-04-04 06:28:26 +00:00
Wiki . prototype . search _blurred = function ( event ) {
var search _text = getElement ( "search_text" ) ;
if ( search _text . value == '' )
search _text . value = 'search' ;
}
2008-06-30 05:26:08 +00:00
Wiki . prototype . search _key _released = function ( event ) {
var search _text = getElement ( "search_text" ) ;
var self = this ;
if ( search _text . pulldown ) {
search _text . pulldown . update _suggestions ( search _text . value ) ;
} else if ( event . key ( ) . code != 13 ) {
2008-11-25 00:58:59 +00:00
search _text . pulldown = new Suggest _pulldown ( this . wiki , this . notebook . object _id , this . invoker , search _text , null , search _text . value , search _text ) ;
2008-06-30 05:26:08 +00:00
connect ( search _text . pulldown , "suggestion_selected" , function ( note ) {
self . load _search _suggestion ( note )
} ) ;
}
}
Wiki . prototype . load _search _suggestion = function ( note ) {
var search _text = getElement ( "search_text" ) ;
search _text . value = note . title ;
this . load _editor ( note . title , note . object _id ) ;
if ( search _text . pulldown ) {
search _text . pulldown . shutdown ( ) ;
search _text . pulldown = null ;
}
}
2008-11-17 21:33:21 +00:00
Wiki . prototype . notebook _has _tag = function ( notebook , tag _name , tag _value ) {
// determine whether the given notebook has a tag with tag_name, and (optionally) tag_value
for ( var i in notebook . tags ) {
var tag = notebook . tags [ i ] ;
if ( tag . name == tag _name ) {
if ( tag _value && tag . value != tag _value )
return false ;
return true ;
}
}
return false ;
}
2007-09-10 20:04:46 +00:00
Wiki . prototype . display _search _results = function ( result ) {
2007-07-16 20:22:38 +00:00
// if there are no search results, indicate that and bail
2007-09-10 20:04:46 +00:00
if ( ! result || result . notes . length == 0 ) {
2007-11-09 06:49:26 +00:00
this . display _message ( "No matching notes." , undefined , getElement ( "notes_top" ) ) ;
2007-07-16 20:22:38 +00:00
return ;
}
2008-05-19 22:16:25 +00:00
// create a "magic" search results note. but first close any open search results notes
2007-09-10 20:04:46 +00:00
if ( this . search _results _editor )
this . search _results _editor . shutdown ( ) ;
2008-11-17 21:33:21 +00:00
if ( this . notebook _has _tag ( this . notebook , "forum" ) )
2008-10-31 22:55:08 +00:00
var notebook _word = "discussion" ;
else
var notebook _word = "notebook" ;
2007-09-10 20:04:46 +00:00
var list = createDOM ( "span" , { } ) ;
2008-05-19 22:16:25 +00:00
var other _notebooks _section = false ;
2007-09-10 20:04:46 +00:00
for ( var i in result . notes ) {
var note = result . notes [ i ]
if ( ! note . title ) continue ;
2007-11-02 20:19:53 +00:00
if ( note . contents . length == 0 ) {
2007-11-27 21:28:25 +00:00
var summary = "empty note" ;
2007-09-10 20:04:46 +00:00
} else {
2007-11-27 21:28:25 +00:00
var summary = note . summary ;
2007-11-02 20:19:53 +00:00
2007-11-27 21:28:25 +00:00
// if the summary appears not to end with a complete sentence, add "..."
if ( ! /[?!.]\s*$/ . test ( summary ) )
summary = summary + " <b>...</b>" ;
2007-09-10 20:04:46 +00:00
}
2007-11-27 21:28:25 +00:00
var summary _span = createDOM ( "span" ) ;
2008-04-29 20:53:39 +00:00
summary _span . setAttribute ( "class" , "search_results_summary" ) ;
2007-11-27 21:28:25 +00:00
summary _span . innerHTML = summary ;
2007-11-02 20:19:53 +00:00
2008-05-19 22:16:25 +00:00
// when a link is clicked for a note from a notebook other than the current one, open it in a
// new window
var link _attributes = { "href" : "/notebooks/" + note . notebook _id + "?note_id=" + note . object _id } ;
2008-11-25 00:58:59 +00:00
if ( note . notebook _id != this . notebook . object _id ) {
2008-05-19 22:16:25 +00:00
link _attributes [ "target" ] = "_new" ;
if ( ! other _notebooks _section ) {
other _notebooks _section = true ;
if ( i == 0 )
2008-10-31 22:55:08 +00:00
appendChildNodes ( list , createDOM ( "p" , { } , "No matching notes in this " + notebook _word + "." ) ) ;
2008-05-19 22:16:25 +00:00
2008-10-31 22:55:08 +00:00
appendChildNodes ( list , createDOM ( "hr" ) , createDOM ( "h4" , { } , "other " + notebook _word + "s" ) ) ;
2008-05-19 22:16:25 +00:00
}
}
var notebook = this . notebooks _by _id [ note . notebook _id ] ;
2007-09-10 20:04:46 +00:00
appendChildNodes ( list ,
createDOM ( "p" , { } ,
2008-05-19 22:16:25 +00:00
createDOM ( "a" , link _attributes , note . title ) ,
other _notebooks _section && notebook && createDOM ( "span" , { "class" : "small_text" } , " (" , notebook . name , ")" ) || null ,
2007-09-10 20:04:46 +00:00
createDOM ( "br" ) ,
2007-11-27 21:28:25 +00:00
summary _span
2007-09-10 20:04:46 +00:00
)
) ;
2007-07-16 20:22:38 +00:00
}
2007-09-10 20:04:46 +00:00
2007-11-09 06:49:26 +00:00
this . search _results _editor = this . create _editor ( "search_results" , "<h3>search results</h3>" + list . innerHTML , undefined , undefined , undefined , false , true , true , getElement ( "notes_top" ) ) ;
2007-07-16 20:22:38 +00:00
}
2007-12-11 01:15:03 +00:00
Wiki . prototype . share _notebook = function ( ) {
this . clear _pulldowns ( ) ;
var share _notebook _frame = getElement ( "note_share_notebook" ) ;
2007-12-13 20:26:32 +00:00
if ( share _notebook _frame )
share _notebook _frame . editor . shutdown ( ) ;
2007-12-11 01:15:03 +00:00
2008-01-26 00:37:38 +00:00
var collaborators _label = createDOM ( "label" ,
{ "for" : "collaborators_radio" , "class" : "radio_label" , "title" : "Collaborators may view and edit this notebook." } ,
2007-12-11 01:15:03 +00:00
"collaborators"
) ;
2008-01-26 00:37:38 +00:00
var viewers _label = createDOM ( "label" ,
{ "for" : "viewers_radio" , "class" : "radio_label" , "title" : "Viewers may only view this notebook." } ,
2007-12-11 01:15:03 +00:00
"viewers"
) ;
2008-01-26 00:37:38 +00:00
var owners _label = createDOM ( "label" ,
{ "for" : "owners_radio" , "class" : "radio_label" , "title" : "Owners may view, edit, rename, delete, and invite people to this notebook." } ,
2007-12-11 01:15:03 +00:00
"owners"
) ;
var collaborators _radio = createDOM ( "input" ,
{ "type" : "radio" , "id" : "collaborators_radio" , "name" : "access" , "value" : "collaborator" , "checked" : "true" }
) ;
var viewers _radio = createDOM ( "input" ,
{ "type" : "radio" , "id" : "viewers_radio" , "name" : "access" , "value" : "viewer" }
) ;
var owners _radio = createDOM ( "input" ,
{ "type" : "radio" , "id" : "owners_radio" , "name" : "access" , "value" : "owner" }
)
2007-12-11 02:58:31 +00:00
if ( this . rate _plan . notebook _collaboration ) {
var access _area = createDOM ( "p" , { "id" : "access_choices" } ,
createDOM ( "p" , { } , "Invite these people as:" ) ,
2008-08-08 23:39:53 +00:00
createDOM ( "table" , { "id" : "access_table" , "class" : "radio_table" } ,
2007-12-11 02:58:31 +00:00
createDOM ( "tr" , { } ,
2008-01-26 00:37:38 +00:00
createDOM ( "td" , { } , collaborators _radio , collaborators _label ) ,
createDOM ( "td" , { } , viewers _radio , viewers _label ) ,
createDOM ( "td" , { } , owners _radio , owners _label )
2007-12-11 02:58:31 +00:00
)
)
) ;
} else {
var access _area = createDOM ( "p" , { } ,
createDOM ( "b" , { } , "Note: " ) ,
2007-12-11 05:52:33 +00:00
"These people will only be able to " , createDOM ( "i" , "view" ) , " your notebook. " ,
"If you'd like them to be able to " , createDOM ( "i" , "edit" ) ,
" your notebook as well, please " ,
2007-12-11 02:58:31 +00:00
createDOM ( "a" , { "href" : "/upgrade" , "target" : "_new" } , "upgrade" ) ,
" your account." ,
createDOM ( "input" , { "type" : "hidden" , "name" : "access" , "value" : "viewer" } )
) ;
}
2007-12-13 20:26:32 +00:00
var invite _area = createDOM ( "p" , { "id" : "invite_area" } ) ;
2007-12-13 22:29:57 +00:00
this . display _invites ( invite _area ) ;
2007-12-12 00:52:34 +00:00
2007-12-11 01:15:03 +00:00
var div = createDOM ( "div" , { } ,
2008-05-31 00:10:57 +00:00
createDOM ( "form" , { "id" : "invite_form" , "target" : "/users/send_invites" } ,
2008-11-25 00:58:59 +00:00
createDOM ( "input" , { "type" : "hidden" , "name" : "notebook_id" , "value" : this . notebook . object _id } ) ,
2007-12-11 01:15:03 +00:00
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "people to invite" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "textarea" ,
{ "name" : "email_addresses" , "class" : "textarea_field" , "cols" : "40" , "rows" : "4" , "wrap" : "off" }
)
) ,
createDOM ( "p" , { } , "Please separate email addresses with commas, spaces, or the enter key." ) ,
2007-12-11 02:58:31 +00:00
access _area ,
2007-12-11 01:15:03 +00:00
createDOM ( "p" , { } ,
createDOM ( "input" ,
{ "type" : "submit" , "name" : "invite_button" , "id" : "invite_button" , "class" : "button" , "value" : "send invites" }
)
2007-12-12 00:52:34 +00:00
) ,
invite _area
2008-01-06 00:12:18 +00:00
) ,
createDOM ( "div" , { } ,
createDOM (
2008-11-25 00:58:59 +00:00
"a" , { "href" : "/notebooks/" + this . notebook . object _id + "?preview=viewer" , "target" : "_new" } ,
2008-01-06 00:12:18 +00:00
"Preview this notebook as a viewer."
)
) ,
this . rate _plan . notebook _collaboration ? createDOM ( "div" , { } ,
createDOM (
2008-11-25 00:58:59 +00:00
"a" , { "href" : "/notebooks/" + this . notebook . object _id + "?preview=collaborator" , "target" : "_new" } ,
2008-01-06 00:12:18 +00:00
"Preview this notebook as a collaborator."
)
) : null
2007-12-11 01:15:03 +00:00
) ;
this . create _editor ( "share_notebook" , "<h3>share this notebook</h3>" + div . innerHTML , undefined , undefined , undefined , false , true , true , getElement ( "notes_top" ) ) ;
}
2007-12-13 22:29:57 +00:00
Wiki . prototype . display _invites = function ( invite _area ) {
2007-12-13 20:26:32 +00:00
if ( ! this . invites || this . invites . length == 0 )
return ;
2007-12-13 22:29:57 +00:00
var collaborators = createDOM ( "div" , { "id" : "collaborators" } ) ;
var viewers = createDOM ( "div" , { "id" : "viewers" } ) ;
var owners = createDOM ( "div" , { "id" : "owners" } ) ;
var self = this ;
2007-12-13 20:26:32 +00:00
2008-01-04 04:45:43 +00:00
var addresses = new Array ( ) ;
2007-12-13 20:26:32 +00:00
for ( var i in this . invites ) {
var invite = this . invites [ i ] ;
2008-01-04 04:45:43 +00:00
2008-01-06 22:22:46 +00:00
// if there are multiple invites for a given email address, only display those that are
// redeemed
if ( addresses [ invite . email _address ] == true && ! invite . redeemed _user _id )
2008-01-04 04:45:43 +00:00
continue ;
2007-12-13 22:29:57 +00:00
var revoke _button = createDOM ( "input" , {
"type" : "button" ,
"id" : "revoke_" + invite . object _id ,
2008-06-02 21:16:35 +00:00
"class" : "revoke_button button" ,
2007-12-13 22:29:57 +00:00
"value" : " x " ,
"title" : "revoke this person's notebook access"
} ) ;
2007-12-27 22:16:47 +00:00
var add _invite _to = null ;
2007-12-13 20:26:32 +00:00
if ( invite . owner ) {
2007-12-27 22:16:47 +00:00
add _invite _to = owners ;
2007-12-13 20:26:32 +00:00
} else {
if ( invite . read _write )
2007-12-27 22:16:47 +00:00
add _invite _to = collaborators ;
2007-12-13 20:26:32 +00:00
else
2007-12-27 22:16:47 +00:00
add _invite _to = viewers ;
2007-12-13 20:26:32 +00:00
}
2007-12-27 22:16:47 +00:00
appendChildNodes (
2008-06-03 23:12:35 +00:00
add _invite _to , createDOM ( "div" , { "class" : "invite indented" } ,
2008-07-18 22:01:09 +00:00
invite . email _address , " " ,
createDOM ( "span" , { "class" : "invite_status" } ,
invite . redeemed _username ? "(invite accepted by " + invite . redeemed _username + ")" : "(waiting for invite to be accepted)"
) ,
" " , revoke _button ,
! invite . redeemed _username && createDOM ( "span" , { } ,
createDOM ( "br" ) ,
createDOM ( "span" , { "class" : "invite_link_area" } ,
"invite link: " + location . protocol + "//" + location . host + "/i/" + invite . object _id
)
) || ""
)
2007-12-27 22:16:47 +00:00
) ;
2008-01-04 04:45:43 +00:00
addresses [ invite . email _address ] = true ;
2007-12-13 20:26:32 +00:00
}
var div = createDOM ( "div" ) ;
if ( collaborators . childNodes . length > 0 ) {
2007-12-13 22:29:57 +00:00
var p = createDOM ( "p" ) ;
appendChildNodes ( p , createDOM ( "b" , { } , "collaborators" ) ) ;
appendChildNodes ( p , collaborators ) ;
appendChildNodes ( div , p ) ;
2007-12-13 20:26:32 +00:00
}
if ( viewers . childNodes . length > 0 ) {
2007-12-13 22:29:57 +00:00
var p = createDOM ( "p" ) ;
appendChildNodes ( p , createDOM ( "b" , { } , "viewers" ) ) ;
appendChildNodes ( p , viewers ) ;
appendChildNodes ( div , p ) ;
2007-12-13 20:26:32 +00:00
}
if ( owners . childNodes . length > 0 ) {
2007-12-13 22:29:57 +00:00
var p = createDOM ( "p" ) ;
appendChildNodes ( p , createDOM ( "b" , { } , "owners" ) ) ;
appendChildNodes ( p , owners ) ;
appendChildNodes ( div , p ) ;
2007-12-13 20:26:32 +00:00
}
replaceChildNodes ( invite _area , div ) ;
}
2008-05-08 03:05:35 +00:00
Wiki . prototype . display _settings = function ( ) {
this . clear _pulldowns ( ) ;
var settings _frame = getElement ( "note_settings" ) ;
if ( settings _frame ) {
settings _frame . editor . highlight ( ) ;
return ;
}
2008-06-03 23:12:35 +00:00
var group _list = createDOM ( "div" ) ;
2008-05-28 23:05:38 +00:00
2008-05-08 03:05:35 +00:00
var div = createDOM ( "div" , { } ,
2008-05-31 00:10:57 +00:00
createDOM ( "form" , { "id" : "settings_form" , "target" : "/users/update_settings" } ,
2008-05-08 03:05:35 +00:00
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "email address" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "text" , "name" : "email_address" , "id" : "email_address" , "class" : "text_field" ,
2008-10-24 18:51:19 +00:00
"size" : "30" , "maxlength" : "60" , "value" : this . user . email _address || "" }
2008-05-08 03:05:35 +00:00
)
) ,
createDOM ( "p" , { } ,
createDOM ( "input" ,
{ "type" : "submit" , "name" : "settings_button" , "id" : "settings_button" , "class" : "button" , "value" : "save settings" }
)
) ,
2008-05-28 23:05:38 +00:00
createDOM ( "p" , { "class" : "small_text" } ,
2008-05-08 03:05:35 +00:00
"Your email address will " ,
createDOM ( "a" , { "href" : "/privacy" , "target" : "_new" } , "never be shared" ) ,
". It will only be used for password resets, contacting you about account problems, and the from address in any invite emails you send."
)
2008-05-08 03:37:24 +00:00
) ,
2008-05-30 22:25:12 +00:00
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "group membership" ) ,
createDOM ( "br" , { } ) ,
group _list
) ,
2008-05-08 03:37:24 +00:00
createDOM ( "p" , { } ,
createDOM (
"a" , { "href" : "/pricing" , "target" : "_top" } ,
"Upgrade, downgrade, or cancel your account."
)
2008-05-08 03:05:35 +00:00
)
) ;
2008-05-30 22:25:12 +00:00
for ( var i in this . groups ) {
var group = this . groups [ i ] ;
2008-06-03 23:12:35 +00:00
var item = createDOM ( "div" , { "class" : "indented" } ) ;
2008-05-30 22:25:12 +00:00
appendChildNodes ( group _list , item ) ;
2008-06-03 02:53:39 +00:00
appendChildNodes ( item , group . name ) ;
2008-05-30 22:25:12 +00:00
if ( group . admin ) {
2008-06-03 02:53:39 +00:00
appendChildNodes ( item , createDOM ( "input" , {
"id" : "admin_" + group . object _id ,
"class" : "admin_button button" ,
"type" : "button" ,
"value" : "admin" ,
"title" : "administer this group's users"
} ) ) ;
2008-05-30 22:25:12 +00:00
}
}
if ( this . groups . length == 0 ) {
2008-06-06 21:49:28 +00:00
var item = createDOM ( "div" , { "class" : "indented" } , "You're not a member of any groups." ) ;
2008-05-30 22:25:12 +00:00
appendChildNodes ( group _list , item ) ;
}
2008-05-08 03:05:35 +00:00
this . create _editor ( "settings" , "<h3>account settings</h3>" + div . innerHTML , undefined , undefined , undefined , false , true , true , getElement ( "notes_top" ) ) ;
}
2008-05-30 22:25:12 +00:00
Wiki . prototype . display _group _settings = function ( result ) {
2008-06-04 03:19:07 +00:00
this . clear _pulldowns ( ) ;
2008-06-03 02:53:39 +00:00
var group _frame = getElement ( "note_group_" + result . group . object _id ) ;
2008-06-04 03:19:07 +00:00
if ( group _frame )
group _frame . editor . shutdown ( ) ;
2008-06-03 02:53:39 +00:00
2008-06-03 23:12:35 +00:00
var admin _list = createDOM ( "div" ) ;
var user _list = createDOM ( "div" ) ;
2008-06-03 02:53:39 +00:00
var div = createDOM ( "div" , { } ,
2008-06-03 23:12:35 +00:00
createDOM ( "form" , { "id" : "group_settings_form" , "target" : "/groups/update_settings" } ,
createDOM ( "input" ,
2008-06-06 21:46:29 +00:00
{ "type" : "hidden" , "name" : "group_id" , "class" : "group_id" , "value" : result . group . object _id }
2008-06-03 23:12:35 +00:00
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "group name" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "text" , "name" : "group_name" , "id" : "group_name" , "class" : "text_field" ,
"size" : "30" , "maxlength" : "100" , "value" : result . group . name }
)
) ,
createDOM ( "p" , { } ,
createDOM ( "input" ,
{ "type" : "submit" , "name" : "group_settings_button" , "id" : "group_settings_button" , "class" : "button" , "value" : "save settings" }
)
)
) ,
createDOM ( "h3" , { } , "create group member" ) ,
createDOM ( "form" , { "id" : "create_user_form" , "target" : "/users/signup_group_member" } ,
createDOM ( "input" ,
2008-06-06 21:46:29 +00:00
{ "type" : "hidden" , "name" : "group_id" , "class" : "group_id" , "value" : result . group . object _id }
2008-06-03 23:12:35 +00:00
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "new username" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "text" , "name" : "username" , "id" : "username" , "class" : "text_field" ,
"size" : "30" , "maxlength" : "60" }
)
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "password" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "password" , "name" : "password" , "id" : "password" , "class" : "text_field" ,
"size" : "30" , "maxlength" : "60" }
)
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "password" ) , " (again)" ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "password" , "name" : "password_repeat" , "id" : "password_repeat" , "class" : "text_field" ,
"size" : "30" , "maxlength" : "60" }
)
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "email address" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "input" ,
{ "type" : "text" , "name" : "email_address" , "id" : "email_address" , "class" : "text_field" ,
"size" : "30" , "maxlength" : "60" }
)
) ,
createDOM ( "p" , { } ,
createDOM ( "input" ,
{ "type" : "submit" , "name" : "create_user_button" , "id" : "create_user_button" , "class" : "button" , "value" : "create member" }
)
)
2008-06-04 03:19:07 +00:00
) ,
createDOM ( "h3" , { } , "group members" ) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "admins" ) ,
createDOM ( "br" , { } ) ,
admin _list
) ,
createDOM ( "p" , { } ,
createDOM ( "b" , { } , "members" ) ,
createDOM ( "br" , { } ) ,
user _list
2008-06-03 02:53:39 +00:00
)
) ;
for ( var i in result . admin _users ) {
var user = result . admin _users [ i ] ;
2008-06-03 23:12:35 +00:00
appendChildNodes ( admin _list , createDOM ( "div" , { "class" : "indented" } , user . username ) ) ;
2008-06-03 02:53:39 +00:00
}
if ( result . admin _users . length == 0 )
2008-06-03 23:12:35 +00:00
appendChildNodes ( admin _list , createDOM ( "div" , { "class" : "indented" } , "This group has no admin users." ) ) ;
2008-06-03 02:53:39 +00:00
for ( var i in result . other _users ) {
var user = result . other _users [ i ] ;
2008-06-03 23:12:35 +00:00
appendChildNodes ( user _list , createDOM ( "div" , { "class" : "indented" } , user . username ,
createDOM ( "input" , {
"type" : "button" ,
2008-06-04 03:19:07 +00:00
"id" : "remove_user_" + user . object _id + "_" + result . group . object _id ,
2008-06-03 23:12:35 +00:00
"class" : "remove_user_button button" ,
"value" : " x " ,
"title" : "remove this user from the group"
} )
) ) ;
2008-06-03 02:53:39 +00:00
}
if ( result . other _users . length == 0 )
2008-06-03 23:12:35 +00:00
appendChildNodes ( user _list , createDOM ( "div" , { "class" : "indented" } , "This group has no members." ) ) ;
2008-06-03 02:53:39 +00:00
2008-06-03 23:12:35 +00:00
this . create _editor ( "group_" + result . group . object _id , "<h3>group admin settings</h3>" + div . innerHTML , undefined , undefined , undefined , false , true , true , getElement ( "note_settings" ) ) ;
2008-05-30 22:25:12 +00:00
}
2008-08-08 23:39:53 +00:00
Wiki . prototype . display _import _notebook = function ( result ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
var import _frame = getElement ( "note_import" ) ;
if ( import _frame )
import _frame . editor . shutdown ( ) ;
var form = createDOM ( "form" , { "id" : "import_notebook_form" , "target" : "/notebooks/import_csv" } ,
createDOM ( "input" ,
{ "type" : "hidden" , "name" : "file_id" , "value" : result . file _id }
)
) ;
appendChildNodes ( form , createDOM ( "p" , { } , "Here are the first few lines of the file:" ) ) ;
var tbody = createDOM ( "tbody" , { } ) ;
var table = createDOM ( "table" , { "id" : "import_notebook_table" } , tbody ) ;
appendChildNodes ( form , table ) ;
for ( var i in result . rows ) {
var row = result . rows [ i ] ;
var row _node = createDOM ( "tr" , { } ) ;
for ( var j in row ) {
var element = row [ j ] ;
appendChildNodes ( row _node , createDOM ( "td" , { } , element ) ) ;
}
appendChildNodes ( tbody , row _node ) ;
}
var contents _select = createDOM ( "select" , { "name" : "content_column" } ) ;
var column _number = 1 ;
for ( i in result . rows [ 0 ] ) {
var element = result . rows [ 0 ] [ i ] ;
appendChildNodes ( contents _select , createDOM ( "option" , { "value" : i } , "column " + column _number + " - " + element ) ) ;
column _number += 1 ;
}
appendChildNodes ( form , createDOM ( "p" , { "target" : "/notebooks/import" } ,
createDOM ( "b" , { } , "Which column contains the note contents text?" ) ,
createDOM ( "br" , { } ) ,
contents _select
) ) ;
var titles _select = createDOM ( "select" , { "name" : "title_column" } ) ;
column _number = 1 ;
2008-08-09 08:05:12 +00:00
appendChildNodes ( titles _select , createDOM ( "option" , { "value" : "None" } , "There is no title column." ) ) ;
2008-08-08 23:39:53 +00:00
for ( i in result . rows [ 0 ] ) {
var element = result . rows [ 0 ] [ i ] ;
appendChildNodes ( titles _select , createDOM ( "option" , { "value" : i } , "column " + column _number + " - " + element ) ) ;
column _number += 1 ;
}
appendChildNodes ( form , createDOM ( "p" , { } ,
createDOM ( "b" , { } , "Which column contains the note titles (if any)?" ) ,
createDOM ( "br" , { } ) ,
titles _select
) ) ;
var plaintext _label = createDOM ( "label" ,
{ "for" : "plaintext_radio" , "class" : "radio_label" , "title" : "The note contents are just plain text." } ,
"plain text"
) ;
var html _label = createDOM ( "label" ,
{ "for" : "html_radio" , "class" : "radio_label" , "title" : "The note contents are formatted as HTML." } ,
"HTML"
) ;
var plaintext _radio = createDOM ( "input" ,
{ "type" : "radio" , "id" : "plaintext_radio" , "name" : "plaintext" , "value" : "True" , "checked" : "true" }
) ;
var html _radio = createDOM ( "input" ,
{ "type" : "radio" , "id" : "html_radio" , "name" : "plaintext" , "value" : "False" }
) ;
appendChildNodes ( form , createDOM ( "p" , { } ,
createDOM ( "b" , { } , "Should the note contents be treated as plain text or HTML?" ) ,
createDOM ( "br" , { } ) ,
createDOM ( "table" , { "id" : "plaintext_table" , "class" : "radio_table" } ,
createDOM ( "tr" , { } ,
createDOM ( "td" , { } , plaintext _radio , plaintext _label ) ,
createDOM ( "td" , { } , html _radio , html _label )
)
)
) ) ;
appendChildNodes ( form , createDOM ( "p" , { } ,
createDOM ( "input" ,
{ "type" : "submit" , "name" : "import_button" , "id" : "import_button" , "class" : "button" , "value" : "import notebook" }
)
) ) ;
var div = createDOM ( "div" , { } ,
createDOM ( "p" , { } , "Almost done. I just need a little information about your file before I can complete the import and create a new notebook." ) ,
2008-08-12 05:53:01 +00:00
form ,
createDOM ( "p" , { } , "Once you begin the import, it may take several seconds to complete." )
2008-08-08 23:39:53 +00:00
) ;
this . create _editor ( "import" , "<h3>import a notebook</h3>" + div . innerHTML , undefined , undefined , undefined , false , true , true , undefined ) ;
}
2008-04-18 23:54:09 +00:00
Wiki . prototype . declutter _clicked = function ( ) {
var header = getElement ( "header" ) ;
if ( header )
addElementClass ( header , "undisplayed" ) ;
var link _area _holder = getElement ( "link_area_holder" ) ;
if ( link _area _holder )
addElementClass ( link _area _holder , "undisplayed" ) ;
2008-07-30 23:49:50 +00:00
var note _tree _area = getElement ( "note_tree_area" ) ;
if ( note _tree _area )
addElementClass ( note _tree _area , "undisplayed" ) ;
2008-04-18 23:54:09 +00:00
var clutter _link = getElement ( "clutter_link" ) ;
if ( clutter _link ) {
removeElementClass ( clutter _link , "undisplayed" ) ;
} else {
clutter _link = createDOM (
"a" ,
{ "href" : "#" , "id" : "clutter_link" , "title" : "Return to the full view of your notebook." } ,
"show it all"
) ;
appendChildNodes ( "link_area" , createDOM ( "div" , { "class" : "link_area_item" } , clutter _link ) ) ;
var self = this ;
connect ( clutter _link , "onclick" , function ( event ) {
self . clutter _clicked ( ) ;
event . stop ( ) ;
} ) ;
}
}
Wiki . prototype . clutter _clicked = function ( ) {
var header = getElement ( "header" ) ;
if ( header )
removeElementClass ( header , "undisplayed" ) ;
var link _area _holder = getElement ( "link_area_holder" ) ;
if ( link _area _holder )
removeElementClass ( link _area _holder , "undisplayed" ) ;
2008-07-30 23:49:50 +00:00
var note _tree _area = getElement ( "note_tree_area" ) ;
if ( note _tree _area )
removeElementClass ( note _tree _area , "undisplayed" ) ;
2008-04-18 23:54:09 +00:00
var clutter _link = getElement ( "clutter_link" ) ;
if ( clutter _link )
addElementClass ( clutter _link , "undisplayed" ) ;
}
2008-03-15 03:04:59 +00:00
Wiki . prototype . move _current _notebook _up = function ( event ) {
var current _notebook = getElement ( "current_notebook_wrapper" ) ;
var sibling _notebook = current _notebook ;
// find the previous sibling notebook node
do {
var sibling _notebook = sibling _notebook . previousSibling ;
} while ( sibling _notebook && sibling _notebook . className != "link_area_item" ) ;
removeElement ( current _notebook ) ;
if ( sibling _notebook )
// move the current notebook up before the previous notebook node
insertSiblingNodesBefore ( sibling _notebook , current _notebook ) ;
// if the current notebook is the first one, wrap it around to the bottom of the list
else {
var notebooks _area = getElement ( "notebooks_area" ) ;
appendChildNodes ( notebooks _area , current _notebook ) ;
}
var self = this ;
this . invoker . invoke ( "/notebooks/move_up" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id
2008-03-15 03:04:59 +00:00
} ) ;
}
Wiki . prototype . move _current _notebook _down = function ( event ) {
var current _notebook = getElement ( "current_notebook_wrapper" ) ;
var sibling _notebook = current _notebook ;
// find the next sibling notebook node
do {
var sibling _notebook = sibling _notebook . nextSibling ;
} while ( sibling _notebook && sibling _notebook . className != "link_area_item" ) ;
removeElement ( current _notebook ) ;
if ( sibling _notebook )
// move the current notebook down after the previous notebook node
insertSiblingNodesAfter ( sibling _notebook , current _notebook ) ;
// if the current notebook is the last one, wrap it around to the top of the list
else {
var notebooks _area _title = getElement ( "notebooks_area_title" ) ;
insertSiblingNodesAfter ( notebooks _area _title , current _notebook ) ;
}
var self = this ;
this . invoker . invoke ( "/notebooks/move_down" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id
2008-03-15 03:04:59 +00:00
} ) ;
}
2007-11-09 06:49:26 +00:00
Wiki . prototype . display _message = function ( text , nodes , position _after ) {
2007-07-16 20:22:38 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-08-07 01:48:43 +00:00
var inner _div = DIV ( { "class" : "message_inner" } , text + " " ) ;
2007-09-05 07:34:59 +00:00
for ( var i in nodes )
appendChildNodes ( inner _div , nodes [ i ] ) ;
2007-08-07 01:48:43 +00:00
2007-12-13 22:29:57 +00:00
var ok _button = createDOM ( "input" , {
2007-09-20 23:25:59 +00:00
"type" : "button" ,
"class" : "message_button" ,
"value" : "ok" ,
2007-09-20 23:34:34 +00:00
"title" : "dismiss this message"
2007-09-20 23:25:59 +00:00
} ) ;
appendChildNodes ( inner _div , ok _button ) ;
connect ( ok _button , "onclick" , this . clear _messages ) ;
2007-07-16 20:22:38 +00:00
var div = DIV ( { "class" : "message" } , inner _div ) ;
2007-09-05 07:34:59 +00:00
div . nodes = nodes ;
2008-07-31 22:50:25 +00:00
div . init _time = new Date ( ) ;
2007-08-07 01:48:43 +00:00
2007-11-09 06:49:26 +00:00
if ( position _after )
insertSiblingNodesAfter ( position _after , div )
else if ( this . focused _editor )
2009-01-23 22:55:57 +00:00
insertSiblingNodesAfter ( this . focused _editor . holder , div )
2007-11-09 06:49:26 +00:00
else
appendChildNodes ( "notes" , div ) ;
2008-03-11 10:40:43 +00:00
this . scroll _to ( div ) ;
2008-03-03 21:11:01 +00:00
2007-11-09 06:49:26 +00:00
return div ;
2007-08-07 01:48:43 +00:00
}
2007-11-09 06:49:26 +00:00
Wiki . prototype . display _error = function ( text , nodes , position _after ) {
2007-08-07 01:48:43 +00:00
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
2007-08-21 21:25:59 +00:00
// remove all empty editors, some of which might exist due to a problem reaching the server
var iframes = getElementsByTagAndClassName ( "iframe" , "note_frame" ) ;
for ( var i in iframes ) {
var editor = iframes [ i ] . editor ;
if ( editor . empty ( ) )
editor . shutdown ( ) ;
}
2007-08-23 23:56:42 +00:00
var inner _div = DIV ( { "class" : "error_inner" } , text + " " ) ;
2007-09-05 07:34:59 +00:00
for ( var i in nodes )
appendChildNodes ( inner _div , nodes [ i ] ) ;
2007-08-23 23:56:42 +00:00
2007-09-20 23:25:59 +00:00
ok _button = createDOM ( "input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "ok" ,
2007-09-20 23:34:34 +00:00
"title" : "dismiss this message"
2007-09-20 23:25:59 +00:00
} ) ;
appendChildNodes ( inner _div , ok _button ) ;
connect ( ok _button , "onclick" , this . clear _messages ) ;
2007-08-07 01:48:43 +00:00
var div = DIV ( { "class" : "error" } , inner _div ) ;
2007-09-05 07:34:59 +00:00
div . nodes = nodes ;
2008-07-31 22:50:25 +00:00
div . init _time = new Date ( ) ;
2007-08-23 23:56:42 +00:00
2007-11-09 06:49:26 +00:00
if ( position _after )
insertSiblingNodesAfter ( position _after , div )
else if ( this . focused _editor )
2009-01-23 22:55:57 +00:00
insertSiblingNodesAfter ( this . focused _editor . holder , div )
2007-11-09 06:49:26 +00:00
else
appendChildNodes ( "notes" , div ) ;
2008-03-11 10:40:43 +00:00
this . scroll _to ( div ) ;
2008-03-03 21:11:01 +00:00
2007-11-09 06:49:26 +00:00
return div ;
2007-07-16 20:22:38 +00:00
}
2008-03-11 10:40:43 +00:00
Wiki . prototype . scroll _to = function ( node ) {
// if the message is already completely on-screen, then there's no need to scroll
var viewport _position = getViewportPosition ( ) ;
if ( getElementPosition ( node ) . y < viewport _position . y ||
getElementPosition ( node ) . y + getElementDimensions ( node ) . h > viewport _position . y + getViewportDimensions ( ) . h )
2008-07-29 21:52:23 +00:00
new ScrollTo ( node , { "duration" : 0.25 } ) ;
2008-03-11 10:40:43 +00:00
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . clear _messages = function ( ) {
var results = getElementsByTagAndClassName ( "div" , "message" ) ;
2007-08-07 01:48:43 +00:00
for ( var i in results ) {
var result = results [ i ] ;
2008-07-31 22:50:25 +00:00
// only close the message if it's been open at least a quarter second
if ( new Date ( ) - result . init _time < 250 )
continue
2008-07-31 03:38:20 +00:00
blindUp ( result , options = { "duration" : 0.25 , afterFinish : function ( ) {
2007-08-07 01:48:43 +00:00
try {
2007-09-05 07:34:59 +00:00
for ( var j in result . nodes )
disconnectAll ( result . nodes [ j ] ) ;
2007-08-07 01:48:43 +00:00
removeElement ( result ) ;
} catch ( e ) { }
} } ) ;
}
2007-11-12 10:48:37 +00:00
var results = getElementsByTagAndClassName ( "div" , "error" ) ;
for ( var i in results ) {
var result = results [ i ] ;
2008-07-31 22:50:25 +00:00
if ( new Date ( ) - result . init _time < 250 )
continue
2008-07-31 03:38:20 +00:00
blindUp ( result , options = { "duration" : 0.25 , afterFinish : function ( ) {
2007-11-12 10:48:37 +00:00
try {
removeElement ( result ) ;
} catch ( e ) { }
} } ) ;
}
2007-07-16 20:22:38 +00:00
}
2008-06-13 22:55:19 +00:00
Wiki . prototype . clear _pulldowns = function ( ephemeral _only ) {
2007-07-16 20:22:38 +00:00
var results = getElementsByTagAndClassName ( "div" , "pulldown" ) ;
for ( var i in results ) {
var result = results [ i ] ;
2007-08-30 20:17:10 +00:00
2008-08-13 20:02:07 +00:00
if ( ! result . pulldown )
continue ;
2008-07-31 22:50:25 +00:00
// only close the pulldown if it's been open at least a quarter second
if ( new Date ( ) - result . pulldown . init _time < 250 )
continue
if ( ephemeral _only && ! result . pulldown . ephemeral )
continue ;
2008-06-13 22:55:19 +00:00
2008-07-31 22:50:25 +00:00
result . pulldown . shutdown ( ) ;
result . pulldown = null ;
2007-07-16 20:22:38 +00:00
}
}
2007-09-01 21:06:37 +00:00
Wiki . prototype . delete _all _editors = function ( event ) {
this . clear _messages ( ) ;
this . clear _pulldowns ( ) ;
this . startup _notes = new Array ( ) ;
2008-10-24 18:51:19 +00:00
if ( this . notebook . read _write == NOTEBOOK _READ _WRITE ) {
2007-09-20 22:26:43 +00:00
var self = this ;
2007-09-01 21:06:37 +00:00
this . invoker . invoke ( "/notebooks/delete_all_notes" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id
2007-09-20 22:26:43 +00:00
} , function ( result ) { self . display _storage _usage ( result . storage _bytes ) ; } ) ;
2007-09-01 21:06:37 +00:00
}
this . focused _editor = null ;
var iframes = getElementsByTagAndClassName ( "iframe" , "note_frame" ) ;
for ( var i in iframes ) {
var editor = iframes [ i ] . editor ;
editor . shutdown ( ) ;
}
2007-10-19 20:24:16 +00:00
this . zero _total _notes _count ( ) ;
2008-10-27 23:23:27 +00:00
var note _tree _root _table = getElement ( "note_tree_root_table" ) ;
if ( note _tree _root _table )
removeElement ( note _tree _root _table ) ;
2007-11-18 23:06:51 +00:00
this . display _empty _message ( true ) ;
2007-09-01 21:06:37 +00:00
event . stop ( ) ;
}
2007-11-18 23:06:51 +00:00
Wiki . prototype . display _empty _message = function ( replace _messages ) {
if ( ! replace _messages ) {
// if there are any messages already open, bail
var messages = getElementsByTagAndClassName ( "div" , "message" ) ;
if ( messages . length > 0 ) return false ;
2007-11-15 22:40:16 +00:00
2007-11-18 23:06:51 +00:00
// if there are any errors open, bail
var errors = getElementsByTagAndClassName ( "div" , "error" ) ;
if ( errors . length > 0 ) return false ;
}
2007-11-15 22:40:16 +00:00
2007-09-05 18:49:28 +00:00
// if there are any open editors, bail
2009-01-22 21:30:00 +00:00
if ( Editor . shared _frame && Editor . shared _frame . editor && ! Editor . shared _frame . editor . closed )
return false ;
if ( getElementsByTagAndClassName ( "div" , "static_note_div" ) . length > 0 )
return false ;
2007-09-05 18:49:28 +00:00
2007-11-15 22:40:16 +00:00
if ( ! this . total _notes _count ) {
if ( this . parent _id )
2007-11-17 22:55:13 +00:00
this . display _message ( "There are no notes in the trash." )
2007-11-15 22:40:16 +00:00
else
this . display _message ( "This notebook is empty." ) ;
return true ;
}
2008-04-16 01:20:56 +00:00
if ( ! replace _messages )
2008-03-11 04:52:23 +00:00
return true ;
2007-11-15 22:40:16 +00:00
return false ;
2007-09-05 18:49:28 +00:00
}
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
DATE _PATTERN = /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d).(\d+)[+-](\d\d:?\d\d)/ ;
2007-07-31 22:53:57 +00:00
Wiki . prototype . brief _revision = function ( revision ) {
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
var matches = DATE _PATTERN . exec ( revision ) ;
return new Date ( Date . UTC (
matches [ 1 ] , // year
matches [ 2 ] - 1 , // month (zero-based)
matches [ 3 ] , // day
matches [ 4 ] , // hour
matches [ 5 ] , // minute
matches [ 6 ] , // second
matches [ 7 ] * 0.001 // milliseconds
) ) . toLocaleString ( ) ;
2007-10-19 20:24:16 +00:00
}
Wiki . prototype . increment _total _notes _count = function ( ) {
2007-11-15 22:40:16 +00:00
if ( this . total _notes _count == null ) return ;
this . total _notes _count += 1 ;
replaceChildNodes ( "total_notes_count" , this . total _notes _count ) ;
2008-04-29 00:54:08 +00:00
signal ( this , "total_notes_count_updated" , this . total _notes _count ) ;
2007-10-19 20:24:16 +00:00
}
Wiki . prototype . decrement _total _notes _count = function ( ) {
2007-11-15 22:40:16 +00:00
if ( this . total _notes _count == null ) return ;
this . total _notes _count -= 1 ;
replaceChildNodes ( "total_notes_count" , this . total _notes _count ) ;
2008-04-29 00:54:08 +00:00
signal ( this , "total_notes_count_updated" , this . total _notes _count ) ;
2007-10-19 20:24:16 +00:00
}
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
2007-10-19 20:24:16 +00:00
Wiki . prototype . zero _total _notes _count = function ( ) {
2007-11-15 22:40:16 +00:00
if ( this . total _notes _count == null ) return ;
this . total _notes _count = 0 ;
replaceChildNodes ( "total_notes_count" , this . total _notes _count ) ;
2008-04-29 00:54:08 +00:00
signal ( this , "total_notes_count_updated" , this . total _notes _count ) ;
2007-07-31 22:53:57 +00:00
}
2008-09-18 06:39:11 +00:00
Wiki . prototype . export _clicked = function ( ) {
var pulldown _id = "export_pulldown" ;
var existing _div = getElement ( pulldown _id ) ;
if ( existing _div ) {
existing _div . pulldown . shutdown ( ) ;
existing _div . pulldown = null ;
return ;
}
2008-11-25 00:58:59 +00:00
new Export _pulldown ( this , this . notebook . object _id , this . invoker , getElement ( "export_link" ) ) ;
2008-09-18 06:39:11 +00:00
}
2008-08-08 23:39:53 +00:00
Wiki . prototype . import _clicked = function ( ) {
var pulldown _id = "import_pulldown" ;
var existing _div = getElement ( pulldown _id ) ;
if ( existing _div ) {
existing _div . pulldown . shutdown ( ) ;
existing _div . pulldown = null ;
return ;
}
2008-11-25 00:58:59 +00:00
new Import _pulldown ( this , this . notebook . object _id , this . invoker , getElement ( "import_link" ) ) ;
2008-08-08 23:39:53 +00:00
}
2007-11-15 01:30:45 +00:00
Wiki . prototype . start _notebook _rename = function ( ) {
this . clear _pulldowns ( ) ;
// if a renaming is already in progress, end the renaming instead of starting one
var notebook _name _field = getElement ( "notebook_name_field" ) ;
if ( notebook _name _field ) {
this . end _notebook _rename ( ) ;
return ;
}
2007-12-05 22:52:37 +00:00
var div = createDOM ( "div" ) ;
div . innerHTML = this . notebook . name ;
var notebook _name = scrapeText ( div ) ;
2007-11-15 01:30:45 +00:00
notebook _name _field = createDOM (
"input" , {
"type" : "text" ,
2007-12-05 22:55:23 +00:00
"value" : notebook _name ,
2007-11-15 01:30:45 +00:00
"id" : "notebook_name_field" ,
"name" : "notebook_name_field" ,
"size" : "30" ,
"maxlength" : "100" ,
"class" : "text_field"
}
) ;
var ok _button = createDOM (
"input" , {
"type" : "button" ,
"class" : "message_button" ,
2008-11-14 20:34:06 +00:00
"value" : "rename" ,
"title" : "rename this notebook"
2007-11-15 01:30:45 +00:00
}
) ;
var rename _form = createDOM (
"form" , { "id" : "rename_form" } , notebook _name _field , ok _button
) ;
2008-12-11 07:21:44 +00:00
replaceChildNodes ( "notebook_header_name" , rename _form ) ;
2007-11-15 01:30:45 +00:00
var self = this ;
connect ( rename _form , "onsubmit" , function ( event ) {
self . end _notebook _rename ( ) ;
event . stop ( ) ;
} ) ;
connect ( ok _button , "onclick" , function ( event ) {
self . end _notebook _rename ( ) ;
event . stop ( ) ;
} ) ;
2008-12-27 09:28:38 +00:00
connect ( notebook _name _field , "onclick" , function ( event ) {
event . stop ( ) ;
} ) ;
2007-11-15 01:30:45 +00:00
notebook _name _field . focus ( ) ;
notebook _name _field . select ( ) ;
}
2008-10-30 22:26:27 +00:00
Wiki . prototype . end _notebook _rename = function ( new _notebook _name , prevent _rename _on _click ) {
if ( ! new _notebook _name )
new _notebook _name = getElement ( "notebook_name_field" ) . value ;
2007-11-15 01:30:45 +00:00
// if the new name is blank or reserved, don't actually rename the notebook
if ( /^\s*$/ . test ( new _notebook _name ) )
new _notebook _name = this . notebook . name ;
2007-11-15 22:55:57 +00:00
if ( /^\s*Luminotes/ . test ( new _notebook _name ) || /^\s*trash\s*$/ . test ( new _notebook _name ) ) {
2007-11-15 01:30:45 +00:00
new _notebook _name = this . notebook . name ;
this . display _error ( "That notebook name is not available. Please try a different one." ) ;
}
// rename the notebook in the header
2008-10-30 22:26:27 +00:00
if ( prevent _rename _on _click ) {
var notebook _header _name = createDOM (
"span" , { } ,
createDOM ( "strong" , { } , new _notebook _name )
) ;
replaceChildNodes ( "notebook_header_area" , notebook _header _name ) ;
} else {
var notebook _header _name = createDOM (
"span" ,
{ "id" : "notebook_header_name" , "title" : "Rename this notebook." } ,
createDOM ( "strong" , { } , new _notebook _name )
) ;
replaceChildNodes ( "notebook_header_area" , notebook _header _name ) ;
2007-11-15 01:30:45 +00:00
2008-10-30 22:26:27 +00:00
var self = this ;
connect ( notebook _header _name , "onclick" , function ( event ) {
self . start _notebook _rename ( ) ;
event . stop ( ) ;
} ) ;
}
2007-11-15 01:30:45 +00:00
// rename the notebook link on the right side of the page
2008-10-30 22:26:27 +00:00
var notebook _link = getElement ( "notebook_" + this . notebook . object _id ) ;
if ( notebook _link ) {
replaceChildNodes ( notebook _link , document . createTextNode ( new _notebook _name ) ) ;
}
2007-11-15 01:30:45 +00:00
2008-04-24 20:32:43 +00:00
// rename the notebook within the rss link (if any)
var notebook _rss _link = getElement ( "notebook_rss_link" ) ;
if ( notebook _rss _link ) {
divider = "?rss¬ebook_name=" ;
pieces = notebook _rss _link . href . split ( divider ) ;
notebook _rss _link . href = pieces [ 0 ] + divider + escape ( new _notebook _name ) ;
}
2007-11-15 01:30:45 +00:00
// if the name has changed, then send the new name to the server
if ( new _notebook _name == this . notebook . name )
return ;
this . notebook . name = new _notebook _name ;
this . invoker . invoke ( "/notebooks/rename" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
2007-11-15 01:30:45 +00:00
"name" : new _notebook _name
} ) ;
}
2007-11-17 04:21:48 +00:00
Wiki . prototype . delete _notebook = function ( ) {
2008-01-22 23:29:16 +00:00
if ( this . focused _editor ) {
var self = this ;
this . save _editor ( this . focused _editor , false , function ( ) {
self . invoker . invoke ( "/notebooks/delete" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : self . notebook . object _id
2008-01-22 23:29:16 +00:00
} ) ;
} )
return ;
}
2007-11-17 04:39:33 +00:00
2007-11-17 04:21:48 +00:00
this . invoker . invoke ( "/notebooks/delete" , "POST" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id
2007-11-17 04:21:48 +00:00
} ) ;
}
2007-11-17 22:55:13 +00:00
Wiki . prototype . delete _notebook _forever = function ( event , notebook _id ) {
var deleted _notebook _node = getElement ( "deleted_notebook_" + notebook _id ) ;
if ( ! deleted _notebook _node ) return ;
for ( var i in deleted _notebook _node . childNodes ) {
var child = deleted _notebook _node . childNodes [ i ] ;
disconnectAll ( child ) ;
}
removeElement ( deleted _notebook _node ) ;
2007-11-17 23:29:22 +00:00
var items = getElementsByTagAndClassName ( "div" , "deleted_notebook_item" ) ;
if ( items . length == 0 )
removeElement ( "deleted_notebooks" ) ;
2007-11-19 22:03:04 +00:00
var self = this ;
2007-11-17 23:29:22 +00:00
this . invoker . invoke ( "/notebooks/delete_forever" , "POST" , {
2007-11-17 22:55:13 +00:00
"notebook_id" : notebook _id
2007-11-19 22:03:04 +00:00
} , function ( result ) { self . display _storage _usage ( result . storage _bytes ) ; } ) ;
2007-11-17 22:55:13 +00:00
event . stop ( ) ;
}
2007-07-26 01:18:41 +00:00
Wiki . prototype . toggle _editor _changes = function ( event , editor ) {
// if the pulldown is already open, then just close it
var pulldown _id = "changes_" + editor . id ;
var existing _div = getElement ( pulldown _id ) ;
if ( existing _div ) {
existing _div . pulldown . shutdown ( ) ;
2008-06-27 23:11:09 +00:00
existing _div . pulldown = null ;
2007-07-26 01:18:41 +00:00
return ;
}
event . stop ( ) ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
2007-10-11 11:29:42 +00:00
// if there's already a cached revision list, or the editor doesn't have a revision yet, then
// display the changes pulldown and bail
2008-01-04 04:45:43 +00:00
if ( ( editor . user _revisions && editor . user _revisions . length > 0 ) || ! editor . revision ) {
2008-11-25 00:58:59 +00:00
new Changes _pulldown ( this , this . notebook . object _id , this . invoker , editor ) ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
return ;
}
// otherwise, load the revision list for this note from the server
var self = this ;
this . invoker . invoke (
"/notebooks/load_note_revisions" , "GET" , {
2008-11-25 00:58:59 +00:00
"notebook_id" : this . notebook . object _id ,
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
"note_id" : editor . id
} ,
function ( result ) {
2008-01-04 04:45:43 +00:00
editor . user _revisions = result . revisions ;
2008-11-25 00:58:59 +00:00
new Changes _pulldown ( self , self . notebook . object _id , self . invoker , editor ) ;
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
}
) ;
2007-07-26 01:18:41 +00:00
}
2007-07-16 20:22:38 +00:00
Wiki . prototype . toggle _editor _options = function ( event , editor ) {
// if the pulldown is already open, then just close it
2007-07-20 22:41:20 +00:00
var pulldown _id = "options_" + editor . id ;
var existing _div = getElement ( pulldown _id ) ;
2007-07-16 20:22:38 +00:00
if ( existing _div ) {
existing _div . pulldown . shutdown ( ) ;
2008-06-27 23:11:09 +00:00
existing _div . pulldown = null ;
2007-07-16 20:22:38 +00:00
return ;
}
2008-11-25 00:58:59 +00:00
new Options _pulldown ( this , this . notebook . object _id , this . invoker , editor ) ;
2007-07-20 22:41:20 +00:00
event . stop ( ) ;
}
2007-09-06 21:36:39 +00:00
connect ( window , "onload" , function ( event ) { new Wiki ( new Invoker ( ) ) ; } ) ;
2007-07-20 22:41:20 +00:00
2008-06-13 22:55:19 +00:00
function Pulldown ( wiki , notebook _id , pulldown _id , anchor , relative _to , ephemeral ) {
2007-07-31 22:53:57 +00:00
this . wiki = wiki ;
2007-07-16 20:22:38 +00:00
this . notebook _id = notebook _id ;
2007-07-20 22:41:20 +00:00
this . div = createDOM ( "div" , { "id" : pulldown _id , "class" : "pulldown" } ) ;
2007-07-16 20:22:38 +00:00
this . div . pulldown = this ;
2007-08-30 20:17:10 +00:00
this . init _time = new Date ( ) ;
2007-08-14 04:13:49 +00:00
this . anchor = anchor ;
this . relative _to = relative _to ;
2008-06-13 22:55:19 +00:00
this . ephemeral = ephemeral ;
2007-08-14 04:13:49 +00:00
2007-07-16 20:22:38 +00:00
addElementClass ( this . div , "invisible" ) ;
appendChildNodes ( document . body , this . div ) ;
2008-06-13 22:55:19 +00:00
if ( this . ephemeral ) {
// when the mouse cursor is moved into the pulldown, it becomes non-ephemeral (in other words,
2008-12-03 23:42:08 +00:00
// it will no longer disappear in a few seconds). but as soon as the mouse leaves, it becomes
// ephemeral again
2008-06-13 22:55:19 +00:00
var self = this ;
connect ( this . div , "onmouseover" , function ( event ) {
self . ephemeral = false ;
} ) ;
2008-12-03 23:42:08 +00:00
connect ( this . div , "onmouseout" , function ( event ) {
self . ephemeral = true ;
} ) ;
2008-06-13 22:55:19 +00:00
}
2007-08-14 04:13:49 +00:00
}
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init = function ( ) {
Pulldown . prototype . update _position . call ( this ) ;
removeElementClass ( this . div , "invisible" ) ;
}
2008-06-30 05:26:08 +00:00
function calculate _position ( node , anchor , relative _to , always _left _align ) {
2008-06-14 06:26:48 +00:00
var anchor _dimensions = getElementDimensions ( anchor ) ;
2008-10-08 21:56:01 +00:00
// if the anchor's first child is larger (vertically) than its parent, then use it as the anchor
if ( anchor . firstChild ) {
try {
var child _dimensions = getElementDimensions ( anchor . firstChild ) ;
2008-10-09 06:44:25 +00:00
if ( child _dimensions . h > anchor _dimensions . h + 4 ) {
2008-10-08 21:56:01 +00:00
anchor = anchor . firstChild ;
anchor _dimensions = child _dimensions ;
}
} catch ( e ) { }
2008-06-14 06:26:48 +00:00
}
2007-08-14 04:13:49 +00:00
// position the pulldown under the anchor
var position = getElementPosition ( anchor ) ;
2008-10-07 00:56:41 +00:00
// in WebKit, work around a bug in which children/grandchildren/etc of relatively positioned
2008-10-07 21:52:32 +00:00
// elements inside of fixed position elements have an incorrect position
2008-10-07 00:56:41 +00:00
if ( WEBKIT ) {
var parent _node = anchor . parentNode ;
2008-10-07 21:52:32 +00:00
var found _fixed _parent = false ;
2008-10-07 00:56:41 +00:00
while ( parent _node ) {
2008-10-07 21:52:32 +00:00
if ( getStyle ( parent _node , "position" ) == "fixed" )
found _fixed _parent = true ;
else if ( found _fixed _parent && getStyle ( parent _node , "position" ) == "relative" ) {
2008-10-07 00:56:41 +00:00
position . x -= parent _node . offsetLeft ;
position . y -= parent _node . offsetTop ;
break ;
}
parent _node = parent _node . parentNode ;
}
}
2007-08-14 04:13:49 +00:00
if ( relative _to ) {
var relative _pos = getElementPosition ( relative _to ) ;
if ( relative _pos ) {
position . x += relative _pos . x ;
position . y += relative _pos . y ;
2007-08-15 20:35:02 +00:00
2008-06-19 00:14:07 +00:00
// adjust the vertical position based on how far the page has scrolled
position . y -= getElement ( "html" ) . scrollTop ;
2007-08-14 04:13:49 +00:00
}
}
2008-06-16 22:07:17 +00:00
var node _dimensions = getElementDimensions ( node ) ;
// if the position is on the right half of the page, then align the right edge of the node with
// the right edge of the anchor
2008-06-30 05:26:08 +00:00
if ( ! always _left _align && position . x > getViewportDimensions ( ) . w * 0.5 ) {
2008-06-16 22:07:17 +00:00
if ( node _dimensions )
position . x = position . x - node _dimensions . w + anchor _dimensions . w ;
}
2008-06-14 06:26:48 +00:00
// if we still don't have a height, move the position down a bit by an arbitrary amount
2007-08-14 04:13:49 +00:00
if ( anchor _dimensions . h == 0 )
position . y += 8 ;
else
position . y += anchor _dimensions . h + 4 ;
return position ;
}
2008-06-30 05:26:08 +00:00
Pulldown . prototype . update _position = function ( always _left _align ) {
var position = calculate _position ( this . div , this . anchor , this . relative _to , always _left _align ) ;
2007-08-14 04:13:49 +00:00
setElementPosition ( this . div , position ) ;
2008-12-23 06:14:16 +00:00
var div _height = getElementDimensions ( this . div ) . h ;
var viewport _bottom = getViewportPosition ( ) . y + getViewportDimensions ( ) . h ;
// if the pulldown is now partially off the bottom of the window, move it up until it isn't
if ( position . y + div _height > viewport _bottom )
new Move ( this . div , { "x" : position . x , "y" : viewport _bottom - div _height , "mode" : "absolute" , "duration" : 0.25 } ) ;
2007-08-14 04:13:49 +00:00
}
2007-07-16 20:22:38 +00:00
2007-07-20 22:41:20 +00:00
Pulldown . prototype . shutdown = function ( ) {
2008-11-15 00:51:35 +00:00
if ( this . div && this . div . parentNode )
removeElement ( this . div ) ;
2007-07-20 22:41:20 +00:00
}
2007-07-31 22:53:57 +00:00
function Options _pulldown ( wiki , notebook _id , invoker , editor ) {
Pulldown . call ( this , wiki , notebook _id , "options_" + editor . id , editor . options _button ) ;
2007-07-20 22:41:20 +00:00
this . invoker = invoker ;
this . editor = editor ;
2008-01-26 19:32:22 +00:00
this . startup _checkbox = createDOM ( "input" , { "type" : "checkbox" , "class" : "pulldown_checkbox" , "id" : "startup_checkbox" } ) ;
this . startup _label = createDOM ( "label" , { "for" : "startup_checkbox" , "class" : "pulldown_label" , "title" : "Display this note whenever the notebook is loaded." } ,
2007-07-20 22:41:20 +00:00
"show on startup"
) ;
2007-07-26 01:18:41 +00:00
appendChildNodes ( this . div , this . startup _checkbox ) ;
2008-01-26 19:32:22 +00:00
appendChildNodes ( this . div , this . startup _label ) ;
2007-07-20 22:41:20 +00:00
this . startup _checkbox . checked = editor . startup ;
var self = this ;
2007-07-26 01:18:41 +00:00
connect ( this . startup _checkbox , "onclick" , function ( event ) { self . startup _clicked ( event ) ; } ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-07-20 22:41:20 +00:00
}
2007-08-20 19:51:02 +00:00
Options _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
2007-07-20 22:41:20 +00:00
Options _pulldown . prototype . constructor = Options _pulldown ;
Options _pulldown . prototype . startup _clicked = function ( event ) {
2007-07-16 20:22:38 +00:00
this . editor . startup = this . startup _checkbox . checked ;
2008-03-07 23:14:39 +00:00
this . editor . mark _dirty ( ) ;
2007-07-16 20:22:38 +00:00
2007-07-31 22:53:57 +00:00
// save this note along with its toggled startup state
this . wiki . save _editor ( this . editor ) ;
2007-07-16 20:22:38 +00:00
}
2007-07-20 22:41:20 +00:00
Options _pulldown . prototype . shutdown = function ( ) {
Pulldown . prototype . shutdown . call ( this ) ;
2007-07-31 22:53:57 +00:00
disconnectAll ( this . startup _checkbox ) ;
2007-07-16 20:22:38 +00:00
}
2007-07-26 01:18:41 +00:00
2007-07-31 22:53:57 +00:00
function Changes _pulldown ( wiki , notebook _id , invoker , editor ) {
Pulldown . call ( this , wiki , notebook _id , "changes_" + editor . id , editor . changes _button ) ;
2007-07-26 01:18:41 +00:00
this . invoker = invoker ;
this . editor = editor ;
2007-07-31 22:53:57 +00:00
this . links = new Array ( ) ;
2007-07-26 01:18:41 +00:00
2008-01-04 04:45:43 +00:00
if ( ! editor . user _revisions || editor . user _revisions . length == 0 ) {
2007-07-26 01:18:41 +00:00
appendChildNodes ( this . div , createDOM ( "span" , "This note has no previous changes." ) ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-07-26 01:18:41 +00:00
return ;
}
Merged revisions 401-446 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/branches/postgres
................
r402 | witten | 2007-10-04 00:48:49 -0700 (Thu, 04 Oct 2007) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-401" from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
................
r404 | witten | 2007-10-04 01:17:07 -0700 (Thu, 04 Oct 2007) | 2 lines
Beginning a conversion from bsddb to postgres.
................
r405 | witten | 2007-10-04 01:18:58 -0700 (Thu, 04 Oct 2007) | 9 lines
Merged revisions 402-404 via svnmerge from
svn+ssh://torsion.org/home/luminotes/repos/luminotes/trunk
........
r403 | witten | 2007-10-04 01:14:45 -0700 (Thu, 04 Oct 2007) | 2 lines
Yay, no more stupid deprecation warnings from simplejson about the sre module.
........
................
r406 | witten | 2007-10-04 15:34:39 -0700 (Thu, 04 Oct 2007) | 4 lines
* Switched back to Python 2.4 because many Python modules in Debian are not packaged to work with Python 2.5
* Began removal of all references to Scheduler, @async, yield, and so on.
* Converted Database.py to support PostgreSQL and updated its unit tests accordingly.
................
r407 | witten | 2007-10-04 16:34:01 -0700 (Thu, 04 Oct 2007) | 2 lines
All unit tests for the new model classes now pass.
................
r409 | witten | 2007-10-05 00:53:56 -0700 (Fri, 05 Oct 2007) | 2 lines
Reordering some columns and adding some indices.
................
r410 | witten | 2007-10-05 16:08:37 -0700 (Fri, 05 Oct 2007) | 4 lines
Now adding trash notebooks to user_notebook table. Also switching db
conversion/verification tools back to require Python 2.5, since they still use
the old Scheduler, which requires 2.5 generator features.
................
r411 | witten | 2007-10-06 16:26:56 -0700 (Sat, 06 Oct 2007) | 2 lines
Lots more unit tests passing. Most of the recent work was on controller.Users and related stuff.
................
r412 | witten | 2007-10-07 01:52:12 -0700 (Sun, 07 Oct 2007) | 2 lines
controller.Users unit tests now finally pass!
................
r413 | witten | 2007-10-07 02:14:10 -0700 (Sun, 07 Oct 2007) | 3 lines
Got controller.Root unit tests passing.
Moved fake sql_* function shenanigans from Test_users.py to Test_controller.py, for use by other controller unit tests.
................
r414 | witten | 2007-10-08 23:11:11 -0700 (Mon, 08 Oct 2007) | 2 lines
All unit tests pass! Fuck yeah!
................
r415 | witten | 2007-10-08 23:13:07 -0700 (Mon, 08 Oct 2007) | 2 lines
Removing all references to Scheduler from luminotes.py
................
r416 | witten | 2007-10-08 23:54:51 -0700 (Mon, 08 Oct 2007) | 3 lines
Converted deleted_from to deleted_from_id in a few more places.
Fixed bug in Users.contents().
................
r417 | witten | 2007-10-09 00:11:59 -0700 (Tue, 09 Oct 2007) | 3 lines
Typo fix in Note sql method.
Adding autocommit flag to Database.next_id() method.
................
r418 | witten | 2007-10-09 00:13:19 -0700 (Tue, 09 Oct 2007) | 2 lines
Updating unit test for new auto commit flag.
................
r419 | witten | 2007-10-09 00:14:09 -0700 (Tue, 09 Oct 2007) | 2 lines
Removing debugging print.
................
r420 | witten | 2007-10-09 00:20:55 -0700 (Tue, 09 Oct 2007) | 2 lines
More sql fixes. I really need some funtional tests that hit the database and exercise the SQL.
................
r421 | witten | 2007-10-09 00:51:34 -0700 (Tue, 09 Oct 2007) | 3 lines
Fixed controller.Database handling of tuple as an Object_type.
Made SQL for user storage calculation better at handling null values and also more succinct.
................
r422 | witten | 2007-10-09 13:32:16 -0700 (Tue, 09 Oct 2007) | 2 lines
Converting Wiki.js to trash_id notebook member instead of trash object.
................
r423 | witten | 2007-10-09 13:42:10 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer displaying "download as html" on the front page, as people see "download" and think they're downloading the software.
................
r424 | witten | 2007-10-09 14:24:40 -0700 (Tue, 09 Oct 2007) | 2 lines
Notebooks.contents() now returns notebooks with correct read-write status.
................
r425 | witten | 2007-10-09 14:32:25 -0700 (Tue, 09 Oct 2007) | 2 lines
Fixed reporting of validation errors to the user. Now says "The blah is missing." instead of just "is missing"
................
r426 | witten | 2007-10-09 17:05:22 -0700 (Tue, 09 Oct 2007) | 2 lines
No longer redirecting to trash notebook upon login.
................
r427 | witten | 2007-10-09 17:20:33 -0700 (Tue, 09 Oct 2007) | 2 lines
Made controller.Database use a connection pool.
................
r429 | witten | 2007-10-09 20:13:30 -0700 (Tue, 09 Oct 2007) | 2 lines
Converted initdb.py and updatedb.py to Postgres from bsddb.
................
r430 | witten | 2007-10-09 20:37:14 -0700 (Tue, 09 Oct 2007) | 2 lines
Changing error message to remove underscores from variable names.
................
r431 | witten | 2007-10-10 13:23:30 -0700 (Wed, 10 Oct 2007) | 2 lines
Removing unused note_title parameter from Wiki.create_editor().
................
r432 | witten | 2007-10-10 13:25:16 -0700 (Wed, 10 Oct 2007) | 2 lines
Revision regular expression now supports timezone notation.
................
r433 | witten | 2007-10-10 14:43:47 -0700 (Wed, 10 Oct 2007) | 2 lines
Finished implementing ranked ordering for startup notes. (However, there's no way to change the rank from the client yet.)
................
r434 | witten | 2007-10-10 16:25:19 -0700 (Wed, 10 Oct 2007) | 4 lines
More strict access checking. Fixed oversight in Postgres DB conversion where,
in certain controller.Notebook methods, access was only checked at the
notebook level, not at the note level as well.
................
r435 | witten | 2007-10-10 17:45:18 -0700 (Wed, 10 Oct 2007) | 3 lines
Now loading revisions on demand from client when the "changes" button is clicked. Also caching
loading revisions so subsequent clicks don't have to reload.
................
r436 | witten | 2007-10-10 21:31:20 -0700 (Wed, 10 Oct 2007) | 2 lines
Tweaking some of the error handling in Expose and Root so that unhandled errors give a generic error message to the client.
................
r437 | witten | 2007-10-10 21:33:49 -0700 (Wed, 10 Oct 2007) | 2 lines
The release script no longer runs initdb.py, because the default database is no longer a single file included in the tarball.
................
r438 | witten | 2007-10-10 21:40:11 -0700 (Wed, 10 Oct 2007) | 2 lines
Updated install instructuctions to include use of initdb.py.
................
r439 | witten | 2007-10-10 21:56:42 -0700 (Wed, 10 Oct 2007) | 3 lines
Made initdb.py only nuke (drop tables/views) when given a command-line flag.
Also made install directions more correct.
................
r440 | witten | 2007-10-10 21:58:48 -0700 (Wed, 10 Oct 2007) | 2 lines
IE 6 doesn't like commas.
................
r441 | witten | 2007-10-10 22:08:50 -0700 (Wed, 10 Oct 2007) | 4 lines
load your notebook. without clicking on "changes", edit a note that has previous revisions. click on "changes". it'll only show
the most recent revision. fixed by not appending to changes as a result of a save unless the client-side revisions list cache has
something in it
................
r442 | witten | 2007-10-10 23:30:41 -0700 (Wed, 10 Oct 2007) | 2 lines
Forgot to actually save off the new revision as editor.revision.
................
r443 | witten | 2007-10-11 01:35:54 -0700 (Thu, 11 Oct 2007) | 13 lines
More intelligent datetime handling:
* convertdb.py assumes old bsddb database timestamps are Pacific, and then
converts them to UTC before inserting them into the new PostgreSQL
database.
* No longer using naked timezoneless datetime objects in model/controller
code, except in unit tests that need compatability with pysqlite. Now
using UTC everwhere.
* Asking PostgreSQL to give us all timestamps back in UTC.
* New dependency on python-tz (pytz) package, noted in INSTALL doc.
* Client now responsible for converting UTC timestamps to local time for
display.
................
r444 | witten | 2007-10-11 01:46:09 -0700 (Thu, 11 Oct 2007) | 2 lines
Tweak to prevent potential race in IE.
................
r445 | witten | 2007-10-11 01:49:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Got JavaScript "unit" tests passing again.
................
r446 | witten | 2007-10-11 01:53:58 -0700 (Thu, 11 Oct 2007) | 2 lines
Noting that js tests require the Luminotes server on localhost.
................
2007-10-11 09:03:43 +00:00
// display list of revision timestamps in reverse chronological order
2008-01-04 04:45:43 +00:00
var user _revisions = clone ( editor . user _revisions ) ;
user _revisions . reverse ( ) ;
2007-07-26 01:18:41 +00:00
2007-07-31 22:53:57 +00:00
var self = this ;
2008-01-04 04:45:43 +00:00
for ( var i = 0 ; i < user _revisions . length - 1 ; ++ i ) { // -1 to skip the oldest revision
var user _revision = user _revisions [ i ] ;
2008-05-03 04:29:23 +00:00
var previous _revision = user _revisions [ i + 1 ] ;
2008-01-04 04:45:43 +00:00
var short _revision = this . wiki . brief _revision ( user _revision . revision ) ;
2007-07-26 01:18:41 +00:00
var href = "/notebooks/" + this . notebook _id + "?" + queryString (
2008-05-03 04:29:23 +00:00
[ "note_id" , "revision" , "previous_revision" ] ,
[ this . editor . id , user _revision . revision , previous _revision . revision ]
2008-01-04 04:45:43 +00:00
) ;
var link = createDOM (
"a" ,
{ "href" : href , "class" : "pulldown_link" } ,
2008-09-08 22:29:16 +00:00
short _revision + ( ( user _revision . username && user _revision . username != "desktopuser" )
? " by " + user _revision . username : "" )
2007-07-26 01:18:41 +00:00
) ;
2008-01-04 04:45:43 +00:00
2007-07-31 22:53:57 +00:00
this . links . push ( link ) ;
2008-01-04 04:45:43 +00:00
link . revision = user _revision . revision ;
2008-05-03 04:29:23 +00:00
link . previous _revision = previous _revision . revision ;
2007-07-31 22:53:57 +00:00
connect ( link , "onclick" , function ( event ) { self . link _clicked ( event , self . editor . id ) ; } ) ;
appendChildNodes ( this . div , link ) ;
2007-07-26 01:18:41 +00:00
appendChildNodes ( this . div , createDOM ( "br" ) ) ;
}
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-07-26 01:18:41 +00:00
}
2007-08-20 19:51:02 +00:00
Changes _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
2007-07-26 01:18:41 +00:00
Changes _pulldown . prototype . constructor = Changes _pulldown ;
2007-07-31 22:53:57 +00:00
Changes _pulldown . prototype . link _clicked = function ( event , note _id ) {
var revision = event . target ( ) . revision ;
2008-05-03 04:29:23 +00:00
var previous _revision = event . target ( ) . previous _revision ;
2009-01-23 22:55:57 +00:00
this . wiki . load _editor ( "Revision not found." , note _id , revision , previous _revision , null , this . editor . holder ) ;
2007-07-31 22:53:57 +00:00
event . stop ( ) ;
}
2007-08-14 04:13:49 +00:00
Changes _pulldown . prototype . shutdown = function ( ) {
2007-07-31 22:53:57 +00:00
Pulldown . prototype . shutdown . call ( this ) ;
for ( var i in this . links )
disconnectAll ( this . links [ i ] ) ;
}
2007-08-14 04:13:49 +00:00
2008-06-13 22:55:19 +00:00
function Link _pulldown ( wiki , notebook _id , invoker , editor , link , ephemeral ) {
2007-08-16 01:29:18 +00:00
link . pulldown = this ;
2007-08-14 04:13:49 +00:00
this . link = link ;
2009-01-23 22:55:57 +00:00
Pulldown . call ( this , wiki , notebook _id , "link_" + editor . id , link , editor . holder , ephemeral ) ;
2007-08-14 04:13:49 +00:00
this . invoker = invoker ;
this . editor = editor ;
2007-08-16 22:27:58 +00:00
this . title _field = createDOM ( "input" , { "class" : "text_field" , "size" : "30" , "maxlength" : "256" } ) ;
2007-11-27 21:28:25 +00:00
this . note _summary = createDOM ( "span" , { } ) ;
2007-08-14 04:13:49 +00:00
this . previous _title = "" ;
2008-06-30 03:32:13 +00:00
this . suggest _pulldown = null ;
2007-08-14 04:13:49 +00:00
var self = this ;
connect ( this . title _field , "onclick" , function ( event ) { self . title _field _clicked ( event ) ; } ) ;
2007-08-20 18:43:45 +00:00
connect ( this . title _field , "onfocus" , function ( event ) { self . title _field _focused ( event ) ; } ) ;
2007-08-14 04:13:49 +00:00
connect ( this . title _field , "onkeydown" , function ( event ) { self . title _field _key _pressed ( event ) ; } ) ;
2008-06-30 03:32:13 +00:00
connect ( this . title _field , "onkeyup" , function ( event ) { self . title _field _key _released ( event ) ; } ) ;
2007-08-14 04:13:49 +00:00
2008-07-07 22:38:16 +00:00
// the timeout prevents a race condition between these handlers and a suggesting being clicked
connect ( this . title _field , "onchange" , function ( event ) {
setTimeout ( function ( ) { self . title _field _changed ( event ) ; } , 250 ) ;
} ) ;
connect ( this . title _field , "onblur" , function ( event ) {
setTimeout ( function ( ) { self . title _field _changed ( event ) ; } , 250 ) ;
} ) ;
2007-08-14 04:13:49 +00:00
appendChildNodes ( this . div , createDOM ( "span" , { "class" : "field_label" } , "links to: " ) ) ;
appendChildNodes ( this . div , this . title _field ) ;
2007-11-27 21:28:25 +00:00
appendChildNodes ( this . div , this . note _summary ) ;
2007-08-14 04:13:49 +00:00
2007-08-16 22:27:58 +00:00
// links with targets are considered links to external sites
if ( link . target ) {
2007-09-07 23:03:12 +00:00
this . title _field . value = link . href ;
2007-11-27 21:28:25 +00:00
replaceChildNodes ( this . note _summary , "web link" ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-08-16 22:27:58 +00:00
return ;
}
2007-08-14 04:13:49 +00:00
var query = parse _query ( link ) ;
2007-08-15 00:18:30 +00:00
var title = link _title ( link , query ) ;
2007-08-14 04:13:49 +00:00
var id = query . note _id ;
2007-09-07 23:03:12 +00:00
// if the note has no destination note id set, try loading the note from the server by title
2007-08-16 22:27:58 +00:00
if ( ( id == undefined || id == "new" || id == "null" ) && title . length > 0 ) {
2007-09-10 20:04:46 +00:00
if ( title == "search results" ) {
this . title _field . value = title ;
2007-11-27 21:28:25 +00:00
this . display _summary ( title , "current search results" ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-09-10 20:04:46 +00:00
return ;
}
2007-12-11 01:15:03 +00:00
if ( title == "share this notebook" ) {
this . title _field . value = title ;
this . display _summary ( title , "share this notebook with others" ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-12-11 01:15:03 +00:00
return ;
}
2008-05-08 03:05:35 +00:00
if ( title == "account settings" ) {
this . title _field . value = title ;
this . display _summary ( title , "account settings" ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2008-05-08 03:05:35 +00:00
return ;
}
2007-08-16 20:11:01 +00:00
this . invoker . invoke (
"/notebooks/load_note_by_title" , "GET" , {
"notebook_id" : this . notebook _id ,
2007-11-27 21:28:25 +00:00
"note_title" : title ,
"summarize" : true
2007-08-16 20:11:01 +00:00
} ,
function ( result ) {
2007-10-22 21:44:17 +00:00
// if the user has already started typing something, don't overwrite it
2008-06-16 22:07:17 +00:00
if ( self . title _field . value . length != 0 ) {
Pulldown . prototype . finish _init . call ( self ) ;
2007-10-22 21:44:17 +00:00
return ;
2008-06-16 22:07:17 +00:00
}
2007-08-16 20:11:01 +00:00
if ( result . note ) {
self . title _field . value = result . note . title ;
2007-11-27 21:28:25 +00:00
self . display _summary ( result . note . title , result . note . summary ) ;
2007-08-16 20:11:01 +00:00
} else {
self . title _field . value = title ;
2007-11-27 21:28:25 +00:00
replaceChildNodes ( self . note _summary , "empty note" ) ;
2007-08-16 20:11:01 +00:00
}
}
) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-08-14 04:13:49 +00:00
return ;
}
2007-08-14 20:34:31 +00:00
// if this link has an actual destination note id set, then see if that note is already open. if
2007-11-27 21:28:25 +00:00
// so, display its title and a summary of its contents
2009-01-12 22:19:32 +00:00
var destination _editor = editor _by _id ( id ) ;
if ( destination _editor ) {
this . title _field . value = destination _editor . title ;
this . display _summary ( destination _editor . title , destination _editor . summarize ( ) ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-08-14 20:34:31 +00:00
return ;
}
2007-11-27 21:28:25 +00:00
// otherwise, load the destination note from the server, displaying its title and a summary of
2007-08-14 20:34:31 +00:00
// its contents
2007-08-14 04:13:49 +00:00
this . invoker . invoke (
"/notebooks/load_note" , "GET" , {
"notebook_id" : this . notebook _id ,
2007-11-27 21:28:25 +00:00
"note_id" : id ,
"summarize" : true
2007-08-14 04:13:49 +00:00
} ,
function ( result ) {
2007-10-22 21:44:17 +00:00
// if the user has already started typing something, don't overwrite it
2008-06-16 22:07:17 +00:00
if ( self . title _field . value . length != 0 ) {
Pulldown . prototype . finish _init . call ( self ) ;
2007-10-22 21:44:17 +00:00
return ;
2008-06-16 22:07:17 +00:00
}
2007-08-14 04:13:49 +00:00
if ( result . note ) {
self . title _field . value = result . note . title ;
2007-11-27 21:28:25 +00:00
self . display _summary ( result . note . title , result . note . summary ) ;
2007-08-14 04:13:49 +00:00
} else {
2007-08-15 00:18:30 +00:00
self . title _field . value = title ;
2007-11-27 21:28:25 +00:00
replaceChildNodes ( self . note _summary , "empty note" ) ;
2007-08-14 04:13:49 +00:00
}
}
) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2007-08-14 04:13:49 +00:00
}
2007-08-20 19:51:02 +00:00
Link _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
2007-08-14 04:13:49 +00:00
Link _pulldown . prototype . constructor = Link _pulldown ;
2007-11-27 21:28:25 +00:00
Link _pulldown . prototype . display _summary = function ( title , summary ) {
if ( ! summary )
replaceChildNodes ( this . note _summary , "empty note" ) ;
else if ( summary . length == 0 )
replaceChildNodes ( this . note _summary , "empty note" ) ;
else
replaceChildNodes ( this . note _summary , summary ) ;
2007-08-14 04:13:49 +00:00
}
Link _pulldown . prototype . title _field _clicked = function ( event ) {
2008-12-03 23:42:08 +00:00
disconnectAll ( this . div ) ;
this . ephemeral = false ;
2007-08-14 04:13:49 +00:00
event . stop ( ) ;
}
2007-08-20 18:43:45 +00:00
Link _pulldown . prototype . title _field _focused = function ( event ) {
2008-12-03 23:42:08 +00:00
disconnectAll ( this . div ) ;
this . ephemeral = false ;
2007-08-20 18:43:45 +00:00
this . title _field . select ( ) ;
}
2008-06-30 03:32:13 +00:00
Link _pulldown . prototype . update _title _field _with _suggestion = function ( note ) {
this . title _field . value = note . title ;
this . title _field _changed ( null , note ) ;
if ( this . suggest _pulldown ) {
this . suggest _pulldown . shutdown ( ) ;
this . suggest _pulldown = null ;
}
}
Link _pulldown . prototype . title _field _changed = function ( event , note ) {
2007-08-14 04:13:49 +00:00
// if the title is actually unchanged, then bail
2008-02-05 19:45:11 +00:00
var title = strip ( this . title _field . value ) ;
if ( title == this . previous _title )
2007-08-14 04:13:49 +00:00
return ;
2007-11-27 21:28:25 +00:00
replaceChildNodes ( this . note _summary , "" ) ;
2007-08-15 00:18:30 +00:00
this . previous _title = title ;
2007-08-16 01:29:18 +00:00
var self = this ;
2008-06-30 03:32:13 +00:00
// if a destination note is given, then update the link to point to it
if ( note ) {
this . link . href = "/notebooks/" + this . notebook _id + "?note_id=" + note . object _id ;
this . suggest _pulldown . shutdown ( ) ;
this . suggest _pulldown = null ;
this . display _summary ( note . title , summarize _html ( note . contents , note . title ) ) ;
// otherwise, try to resolve the link title
} else {
2008-08-01 22:50:49 +00:00
this . wiki . resolve _link ( title , this . link , true , function ( summary ) {
2008-06-30 03:32:13 +00:00
self . display _summary ( title , summary ) ;
} ) ;
}
2007-08-14 04:13:49 +00:00
}
Link _pulldown . prototype . title _field _key _pressed = function ( event ) {
// if enter is pressed, consider the title field altered. this is necessary because IE neglects
// to issue an onchange event when enter is pressed in an input field
2008-06-30 03:32:13 +00:00
if ( event . key ( ) . code == 13 &&
( this . suggest _pulldown == null || this . suggest _pulldown . something _selected ( ) == false ) ) {
2007-08-14 04:13:49 +00:00
this . title _field _changed ( ) ;
event . stop ( ) ;
}
}
2008-06-30 03:32:13 +00:00
Link _pulldown . prototype . title _field _key _released = function ( event ) {
var self = this ;
if ( this . suggest _pulldown ) {
this . suggest _pulldown . update _suggestions ( this . title _field . value ) ;
} else if ( event . key ( ) . code != 13 ) {
2008-06-30 05:26:08 +00:00
this . suggest _pulldown = new Suggest _pulldown ( this . wiki , this . notebook _id , this . invoker , this . title _field , null , this . title _field . value , this . title _field ) ;
2008-06-30 03:32:13 +00:00
connect ( this . suggest _pulldown , "suggestion_selected" , function ( note ) {
self . update _title _field _with _suggestion ( note )
} ) ;
}
}
2008-06-30 05:26:08 +00:00
Link _pulldown . prototype . update _position = function ( always _left _align ) {
Pulldown . prototype . update _position . call ( this , always _left _align ) ;
2008-06-30 03:32:13 +00:00
if ( this . suggest _pulldown )
2008-06-30 05:26:08 +00:00
this . suggest _pulldown . update _position ( always _left _align ) ;
2007-08-14 04:13:49 +00:00
}
Link _pulldown . prototype . shutdown = function ( ) {
2008-06-30 03:32:13 +00:00
if ( this . suggest _pulldown )
this . suggest _pulldown . shutdown ( ) ;
2007-08-14 04:13:49 +00:00
Pulldown . prototype . shutdown . call ( this ) ;
disconnectAll ( this . title _field ) ;
if ( this . link )
2007-08-16 01:29:18 +00:00
this . link . pulldown = null ;
2007-08-14 04:13:49 +00:00
}
2008-01-31 21:52:32 +00:00
2008-08-08 23:39:53 +00:00
function base _upload _filename ( ) {
// get the basename of the file
var filename = getElement ( "upload" ) . value ;
var pieces = filename . split ( "/" ) ;
filename = pieces [ pieces . length - 1 ] ;
pieces = filename . split ( "\\" ) ;
filename = pieces [ pieces . length - 1 ] ;
return filename ;
}
2008-06-13 22:55:19 +00:00
function Upload _pulldown ( wiki , notebook _id , invoker , editor , link , ephemeral ) {
2008-02-22 23:03:10 +00:00
this . link = link || editor . find _link _at _cursor ( ) ;
2008-02-19 20:40:19 +00:00
this . link . pulldown = this ;
2008-01-31 21:52:32 +00:00
2009-01-23 22:55:57 +00:00
Pulldown . call ( this , wiki , notebook _id , "upload_" + editor . id , this . link , editor . holder , ephemeral ) ;
2008-01-31 21:52:32 +00:00
wiki . down _image _button ( "attachFile" ) ;
2008-10-09 00:09:13 +00:00
var vaguely _random = new Date ( ) . getTime ( ) ;
2008-01-31 21:52:32 +00:00
this . invoker = invoker ;
this . editor = editor ;
this . iframe = createDOM ( "iframe" , {
2008-02-01 19:17:10 +00:00
"src" : "/files/upload_page?notebook_id=" + notebook _id + "¬e_id=" + editor . id ,
2008-01-31 21:52:32 +00:00
"frameBorder" : "0" ,
"scrolling" : "no" ,
2008-10-09 00:09:13 +00:00
// if a new iframe has an id/name that WebKit has already seen, then it will just use its
// previous src value and ignore our new src value here. workaround: don't use the same id!
"id" : "upload_frame_" + vaguely _random ,
"name" : "upload_frame_" + vaguely _random ,
2008-02-18 20:08:07 +00:00
"class" : "upload_frame"
2008-01-31 21:52:32 +00:00
} ) ;
2008-02-01 22:44:01 +00:00
this . iframe . pulldown = this ;
2008-02-18 20:08:07 +00:00
this . file _id = null ;
2008-02-19 21:15:09 +00:00
this . uploading = false ;
2008-01-31 21:52:32 +00:00
var self = this ;
connect ( this . iframe , "onload" , function ( event ) { self . init _frame ( ) ; } ) ;
appendChildNodes ( this . div , this . iframe ) ;
2008-02-18 23:44:17 +00:00
this . progress _iframe = createDOM ( "iframe" , {
"frameBorder" : "0" ,
"scrolling" : "no" ,
2008-10-09 00:09:13 +00:00
"id" : "progress_frame_" + vaguely _random ,
"name" : "progress_frame_" + vaguely _random ,
2008-02-18 23:44:17 +00:00
"class" : "upload_frame"
} ) ;
addElementClass ( this . progress _iframe , "undisplayed" ) ;
appendChildNodes ( this . div , this . progress _iframe ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2008-01-31 21:52:32 +00:00
}
Upload _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
Upload _pulldown . prototype . constructor = Upload _pulldown ;
Upload _pulldown . prototype . init _frame = function ( ) {
var self = this ;
2008-02-01 19:17:10 +00:00
var doc = this . iframe . contentDocument || this . iframe . contentWindow . document ;
2008-01-31 21:52:32 +00:00
2008-02-01 19:17:10 +00:00
withDocument ( doc , function ( ) {
2008-01-31 21:52:32 +00:00
connect ( "upload_button" , "onclick" , function ( event ) {
2008-02-01 19:17:10 +00:00
withDocument ( doc , function ( ) {
2008-02-19 20:25:35 +00:00
self . upload _started ( getElement ( "file_id" ) . value ) ;
2008-01-31 21:52:32 +00:00
} ) ;
} ) ;
2008-06-13 22:55:19 +00:00
connect ( doc . body , "onmouseover" , function ( event ) {
self . ephemeral = false ;
} ) ;
2008-01-31 21:52:32 +00:00
} ) ;
}
2008-02-19 20:25:35 +00:00
Upload _pulldown . prototype . upload _started = function ( file _id ) {
this . file _id = file _id ;
2008-02-19 21:15:09 +00:00
this . uploading = true ;
2008-08-08 23:39:53 +00:00
var filename = base _upload _filename ( ) ;
2008-02-19 20:25:35 +00:00
// make the upload iframe invisible but still present so that the upload continues
setElementDimensions ( this . iframe , { "h" : "0" } ) ;
2008-02-18 20:08:07 +00:00
// if the current title is blank, replace the title with the upload's filename
2008-02-19 20:25:35 +00:00
var title = link _title ( this . link ) ;
if ( title == "" )
2008-02-22 23:03:10 +00:00
this . link . innerHTML = filename ;
2008-02-18 20:08:07 +00:00
2008-02-18 23:44:17 +00:00
removeElementClass ( this . progress _iframe , "undisplayed" ) ;
2008-02-19 00:47:59 +00:00
var progress _url = "/files/progress?file_id=" + file _id + "&filename=" + escape ( filename ) ;
2008-10-09 00:09:13 +00:00
this . progress _iframe . src = progress _url ;
2008-01-31 21:52:32 +00:00
}
2008-02-05 19:45:11 +00:00
Upload _pulldown . prototype . upload _complete = function ( ) {
2008-03-18 22:22:19 +00:00
if ( /MSIE/ . test ( navigator . userAgent ) )
var quote _filename = true ;
else
var quote _filename = false ;
2008-02-18 20:08:07 +00:00
// now that the upload is done, the file link should point to the uploaded file
2008-02-19 21:15:09 +00:00
this . uploading = false ;
2008-03-18 22:22:19 +00:00
this . link . href = "/files/download?file_id=" + this . file _id + ""e_filename=" + quote _filename ;
2008-02-18 20:08:07 +00:00
2008-02-05 19:45:11 +00:00
new File _link _pulldown ( this . wiki , this . notebook _id , this . invoker , this . editor , this . link ) ;
2008-02-25 21:56:33 +00:00
this . shutdown ( ) ;
2008-02-05 19:45:11 +00:00
}
2008-06-30 05:26:08 +00:00
Upload _pulldown . prototype . update _position = function ( always _left _align ) {
Pulldown . prototype . update _position . call ( this , always _left _align ) ;
2008-02-19 20:40:19 +00:00
}
2008-02-21 19:39:03 +00:00
Upload _pulldown . prototype . cancel _due _to _click = function ( ) {
2008-02-25 21:56:33 +00:00
this . uploading = false ;
2008-02-21 19:39:03 +00:00
this . wiki . display _message ( "The file upload has been cancelled." )
2008-02-25 21:56:33 +00:00
this . shutdown ( ) ;
2008-02-21 19:39:03 +00:00
}
Upload _pulldown . prototype . cancel _due _to _quota = function ( ) {
2008-02-25 21:56:33 +00:00
this . uploading = false ;
this . shutdown ( ) ;
2008-02-21 19:39:03 +00:00
this . wiki . display _error (
"That file is too large for your available storage space. Before uploading, please delete some notes or files, empty the trash, or" ,
[ createDOM ( "a" , { "href" : "/upgrade" } , "upgrade" ) , " your account." ]
) ;
}
Upload _pulldown . prototype . cancel _due _to _error = function ( message ) {
2008-02-25 21:56:33 +00:00
this . uploading = false ;
2008-02-21 19:39:03 +00:00
this . wiki . display _error ( message )
2008-02-25 21:56:33 +00:00
this . shutdown ( ) ;
2008-02-21 19:39:03 +00:00
}
2008-02-25 21:56:33 +00:00
Upload _pulldown . prototype . shutdown = function ( ) {
if ( this . uploading )
2008-02-21 19:39:03 +00:00
return ;
2008-02-19 20:48:43 +00:00
2008-02-25 21:56:33 +00:00
// in Internet Explorer, the upload won't actually cancel without an explicit Stop command
if ( ! this . iframe . contentDocument && this . iframe . contentWindow ) {
this . iframe . contentWindow . document . execCommand ( 'Stop' ) ;
this . progress _iframe . contentWindow . document . execCommand ( 'Stop' ) ;
}
2008-01-31 21:52:32 +00:00
Pulldown . prototype . shutdown . call ( this ) ;
2008-02-19 20:40:19 +00:00
if ( this . link )
this . link . pulldown = null ;
2008-02-05 19:45:11 +00:00
}
2008-06-19 00:14:07 +00:00
2008-09-18 06:39:11 +00:00
function Export _pulldown ( wiki , notebook _id , invoker , anchor ) {
Pulldown . call ( this , wiki , notebook _id , "export_pulldown" , anchor , null , false ) ;
this . invoker = invoker ;
this . html _link = createDOM ( "a" , {
"href" : "/notebooks/export_html/" + notebook _id ,
"class" : "pulldown_label" ,
"title" : "Download this notebook as a stand-alone HTML web page."
} ,
"HTML web page"
) ;
this . csv _link = createDOM ( "a" , {
"href" : "/notebooks/export_csv/" + notebook _id ,
"class" : "pulldown_label" ,
"title" : "Download this notebook as a CSV spreadsheet file."
} ,
"CSV spreadsheet"
) ;
appendChildNodes ( this . div , createDOM ( "div" , { } , this . html _link ) ) ;
appendChildNodes ( this . div , createDOM ( "div" , { } , this . csv _link ) ) ;
Pulldown . prototype . finish _init . call ( this ) ;
}
Export _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
Export _pulldown . prototype . constructor = Export _pulldown ;
Export _pulldown . prototype . shutdown = function ( ) {
Pulldown . prototype . shutdown . call ( this ) ;
}
2008-08-08 23:39:53 +00:00
function Import _pulldown ( wiki , notebook _id , invoker , anchor ) {
anchor . pulldown = this ;
Pulldown . call ( this , wiki , notebook _id , "import_pulldown" , anchor , null , false ) ;
2008-10-09 00:09:13 +00:00
var vaguely _random = new Date ( ) . getTime ( ) ;
2008-08-08 23:39:53 +00:00
this . invoker = invoker ;
this . iframe = createDOM ( "iframe" , {
"src" : "/files/import_page?notebook_id=" + notebook _id ,
"frameBorder" : "0" ,
"scrolling" : "no" ,
2008-10-09 00:09:13 +00:00
// if a new iframe has an id/name that WebKit has already seen, then it will just use its
// previous src value and ignore our new src value here. workaround: don't use the same id!
"id" : "upload_frame_" + vaguely _random ,
"name" : "upload_frame_" + vaguely _random ,
2008-08-08 23:39:53 +00:00
"class" : "upload_frame"
} ) ;
this . iframe . pulldown = this ;
this . file _id = null ;
this . uploading = false ;
var self = this ;
connect ( this . iframe , "onload" , function ( event ) { self . init _frame ( ) ; } ) ;
appendChildNodes ( this . div , this . iframe ) ;
this . progress _iframe = createDOM ( "iframe" , {
"frameBorder" : "0" ,
"scrolling" : "no" ,
2008-10-09 00:09:13 +00:00
"id" : "progress_frame_" + vaguely _random ,
"name" : "progress_frame_" + vaguely _random ,
2008-08-08 23:39:53 +00:00
"class" : "upload_frame"
} ) ;
addElementClass ( this . progress _iframe , "undisplayed" ) ;
appendChildNodes ( this . div , this . progress _iframe ) ;
Pulldown . prototype . finish _init . call ( this ) ;
}
Import _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
Import _pulldown . prototype . constructor = Import _pulldown ;
Import _pulldown . prototype . init _frame = function ( ) {
var self = this ;
var doc = this . iframe . contentDocument || this . iframe . contentWindow . document ;
withDocument ( doc , function ( ) {
connect ( "upload_button" , "onclick" , function ( event ) {
withDocument ( doc , function ( ) {
self . upload _started ( getElement ( "file_id" ) . value ) ;
} ) ;
} ) ;
} ) ;
}
Import _pulldown . prototype . upload _started = function ( file _id ) {
this . file _id = file _id ;
this . uploading = true ;
var filename = base _upload _filename ( ) ;
// make the upload iframe invisible but still present so that the upload continues
setElementDimensions ( this . iframe , { "h" : "0" } ) ;
removeElementClass ( this . progress _iframe , "undisplayed" ) ;
var progress _url = "/files/progress?file_id=" + file _id + "&filename=" + escape ( filename ) ;
2008-10-09 00:09:13 +00:00
this . progress _iframe . src = progress _url ;
2008-08-08 23:39:53 +00:00
}
Import _pulldown . prototype . upload _complete = function ( ) {
this . uploading = false ;
var wiki = this . wiki ;
this . invoker . invoke (
"/files/csv_head" , "GET" , {
"file_id" : this . file _id
} ,
function ( result ) { wiki . display _import _notebook ( result ) ; }
) ;
this . shutdown ( ) ;
}
Import _pulldown . prototype . update _position = function ( always _left _align ) {
Pulldown . prototype . update _position . call ( this , always _left _align ) ;
}
Import _pulldown . prototype . cancel _due _to _click = function ( ) {
this . uploading = false ;
this . wiki . display _message ( "The file import has been cancelled." )
this . shutdown ( ) ;
}
Import _pulldown . prototype . cancel _due _to _quota = function ( ) {
this . uploading = false ;
this . shutdown ( ) ;
this . wiki . display _error (
"That file is too large for your available storage space. Before uploading, please delete some notes or files, empty the trash, or" ,
[ createDOM ( "a" , { "href" : "/upgrade" } , "upgrade" ) , " your account." ]
) ;
}
Import _pulldown . prototype . cancel _due _to _error = function ( message ) {
this . uploading = false ;
this . wiki . display _error ( message )
this . shutdown ( ) ;
}
Import _pulldown . prototype . shutdown = function ( ) {
if ( this . uploading )
return ;
// in Internet Explorer, the upload won't actually cancel without an explicit Stop command
if ( ! this . iframe . contentDocument && this . iframe . contentWindow ) {
this . iframe . contentWindow . document . execCommand ( 'Stop' ) ;
this . progress _iframe . contentWindow . document . execCommand ( 'Stop' ) ;
}
Pulldown . prototype . shutdown . call ( this ) ;
if ( this . anchor )
this . anchor . pulldown = null ;
}
2008-06-19 00:14:07 +00:00
SMALL _MAX _IMAGE _SIZE = 125 ;
MEDIUM _MAX _IMAGE _SIZE = 300 ;
LARGE _MAX _IMAGE _SIZE = 500 ;
2008-06-13 22:55:19 +00:00
function File _link _pulldown ( wiki , notebook _id , invoker , editor , link , ephemeral ) {
2008-02-05 19:45:11 +00:00
link . pulldown = this ;
this . link = link ;
2009-01-23 22:55:57 +00:00
Pulldown . call ( this , wiki , notebook _id , "file_link_" + editor . id , link , editor . holder , ephemeral ) ;
2008-02-05 19:45:11 +00:00
this . invoker = invoker ;
this . editor = editor ;
this . filename _field = createDOM ( "input" , { "class" : "text_field" , "size" : "30" , "maxlength" : "256" } ) ;
this . file _size = createDOM ( "span" , { } ) ;
this . previous _filename = "" ;
2008-06-13 22:55:19 +00:00
this . link _title = null ;
2008-02-05 19:45:11 +00:00
2008-02-01 22:44:01 +00:00
var self = this ;
2008-02-05 19:45:11 +00:00
connect ( this . filename _field , "onclick" , function ( event ) { self . filename _field _clicked ( event ) ; } ) ;
connect ( this . filename _field , "onfocus" , function ( event ) { self . filename _field _focused ( event ) ; } ) ;
connect ( this . filename _field , "onchange" , function ( event ) { self . filename _field _changed ( event ) ; } ) ;
connect ( this . filename _field , "onblur" , function ( event ) { self . filename _field _changed ( event ) ; } ) ;
connect ( this . filename _field , "onkeydown" , function ( event ) { self . filename _field _key _pressed ( event ) ; } ) ;
2008-02-01 22:44:01 +00:00
2008-06-14 06:26:48 +00:00
this . delete _button = createDOM ( "input" , {
2008-02-20 23:25:13 +00:00
"type" : "button" ,
"class" : "button" ,
"value" : "delete" ,
"title" : "delete file"
} ) ;
2008-04-01 21:54:43 +00:00
var query = parse _query ( link ) ;
this . file _id = query . file _id ;
if ( /MSIE/ . test ( navigator . userAgent ) )
var quote _filename = true ;
else
var quote _filename = false ;
2008-06-13 22:55:19 +00:00
this . thumbnail _span = createDOM ( "span" , { } ,
2008-04-01 21:54:43 +00:00
createDOM ( "a" , { href : "/files/download?file_id=" + this . file _id + ""e_filename=" + quote _filename , target : "_new" } ,
createDOM ( "img" , { "src" : "/files/thumbnail?file_id=" + this . file _id , "class" : "file_thumbnail" } )
)
2008-06-13 22:55:19 +00:00
) ;
appendChildNodes ( this . div , this . thumbnail _span ) ;
// if the link is an image thumbnail link, update the contents of the file link pulldown accordingly
2008-06-14 06:26:48 +00:00
var image = getFirstElementByTagAndClassName ( "img" , null , this . link ) ;
var embed _attributes = { "type" : "checkbox" , "class" : "pulldown_checkbox" , "id" : "embed_checkbox" } ;
2008-06-19 00:14:07 +00:00
var small _size _attributes = { "type" : "radio" , "id" : "small_size_radio" , "name" : "size" , "value" : "small" } ;
var medium _size _attributes = { "type" : "radio" , "id" : "medium_size_radio" , "name" : "size" , "value" : "medium" } ;
var large _size _attributes = { "type" : "radio" , "id" : "large_size_radio" , "name" : "size" , "value" : "large" } ;
2008-06-14 06:26:48 +00:00
var left _justify _attributes = { "type" : "radio" , "id" : "left_justify_radio" , "name" : "justify" , "value" : "left" } ;
var center _justify _attributes = { "type" : "radio" , "id" : "center_justify_radio" , "name" : "justify" , "value" : "center" } ;
var right _justify _attributes = { "type" : "radio" , "id" : "right_justify_radio" , "name" : "justify" , "value" : "right" } ;
if ( image ) {
2008-06-13 22:55:19 +00:00
addElementClass ( this . thumbnail _span , "undisplayed" ) ;
2008-06-14 06:26:48 +00:00
embed _attributes [ "checked" ] = "true" ;
2008-06-19 00:14:07 +00:00
var src = parseQueryString ( image . src . split ( "?" ) . pop ( ) ) ;
var max _size = src [ "max_size" ] ;
if ( max _size == LARGE _MAX _IMAGE _SIZE )
large _size _attributes [ "checked" ] = "true" ;
else if ( max _size == MEDIUM _MAX _IMAGE _SIZE )
medium _size _attributes [ "checked" ] = "true" ;
else
small _size _attributes [ "checked" ] = "true" ;
if ( hasElementClass ( image , "center_justified" ) )
2008-06-14 06:26:48 +00:00
center _justify _attributes [ "checked" ] = "true" ;
else if ( hasElementClass ( image , "right_justified" ) )
right _justify _attributes [ "checked" ] = "true" ;
2008-06-19 00:14:07 +00:00
else
left _justify _attributes [ "checked" ] = "true" ;
2008-06-13 22:55:19 +00:00
} else {
2008-06-19 00:14:07 +00:00
small _size _attributes [ "checked" ] = "true" ;
2008-06-14 06:26:48 +00:00
left _justify _attributes [ "checked" ] = "true" ;
2008-06-13 22:55:19 +00:00
}
2008-06-14 06:26:48 +00:00
this . embed _checkbox = createDOM ( "input" , embed _attributes ) ;
2008-06-19 00:14:07 +00:00
this . small _size _radio = createDOM ( "input" , small _size _attributes ) ;
this . medium _size _radio = createDOM ( "input" , medium _size _attributes ) ;
this . large _size _radio = createDOM ( "input" , large _size _attributes ) ;
2008-06-14 06:26:48 +00:00
this . left _justify _radio = createDOM ( "input" , left _justify _attributes ) ;
this . center _justify _radio = createDOM ( "input" , center _justify _attributes ) ;
this . right _justify _radio = createDOM ( "input" , right _justify _attributes ) ;
2008-06-13 22:55:19 +00:00
var embed _label = createDOM ( "label" , { "for" : "embed_checkbox" , "class" : "pulldown_label" , "title" : "Embed this image within the note itself." } ,
"show image within note"
) ;
2008-04-01 21:54:43 +00:00
2008-06-19 00:14:07 +00:00
var small _size _label = createDOM ( "label" ,
{ "for" : "small_size_radio" , "class" : "radio_label" , "title" : "Display a small thumbnail of this image." } ,
"small"
) ;
var medium _size _label = createDOM ( "label" ,
{ "for" : "medium_size_radio" , "class" : "radio_label" , "title" : "Display a medium thumbnail of this image." } ,
"medium"
) ;
var large _size _label = createDOM ( "label" ,
{ "for" : "large_size_radio" , "class" : "radio_label" , "title" : "Display a large thumbnail of this image." } ,
"large"
) ;
2008-06-14 06:26:48 +00:00
var left _justify _label = createDOM ( "label" ,
{ "for" : "left_justify_radio" , "class" : "radio_label" , "title" : "Left justify this image within the note." } ,
2008-06-19 00:14:07 +00:00
"left"
2008-06-14 06:26:48 +00:00
) ;
var center _justify _label = createDOM ( "label" ,
{ "for" : "center_justify_radio" , "class" : "radio_label" , "title" : "Center this image horizontally within the note." } ,
"center"
) ;
var right _justify _label = createDOM ( "label" ,
{ "for" : "right_justify_radio" , "class" : "radio_label" , "title" : "Right justify this image within the note." } ,
2008-06-19 00:14:07 +00:00
"right"
2008-06-14 06:26:48 +00:00
) ;
2008-06-19 00:14:07 +00:00
this . image _settings _area = createDOM ( "div" , { "class" : "undisplayed" } ,
createDOM ( "table" , { "id" : "image_settings_table" } ,
2008-06-16 20:42:52 +00:00
createDOM ( "tbody" , { } ,
createDOM ( "tr" , { } ,
2008-06-19 00:14:07 +00:00
createDOM ( "td" , { "class" : "field_label" } , "size: " ) ,
createDOM ( "td" , { } , this . small _size _radio , small _size _label ) ,
createDOM ( "td" , { } , this . medium _size _radio , medium _size _label ) ,
createDOM ( "td" , { } , this . large _size _radio , large _size _label )
) ,
createDOM ( "tr" , { } ,
createDOM ( "td" , { "class" : "field_label" } , "position: " ) ,
2008-06-16 20:42:52 +00:00
createDOM ( "td" , { } , this . left _justify _radio , left _justify _label ) ,
createDOM ( "td" , { } , this . center _justify _radio , center _justify _label ) ,
createDOM ( "td" , { } , this . right _justify _radio , right _justify _label )
)
2008-06-14 06:26:48 +00:00
)
)
) ;
if ( image )
2008-06-19 00:14:07 +00:00
removeElementClass ( this . image _settings _area , "undisplayed" ) ;
2008-06-14 06:26:48 +00:00
2008-02-05 19:45:11 +00:00
appendChildNodes ( this . div , createDOM ( "span" , { "class" : "field_label" } , "filename: " ) ) ;
appendChildNodes ( this . div , this . filename _field ) ;
appendChildNodes ( this . div , this . file _size ) ;
2008-02-20 23:25:13 +00:00
appendChildNodes ( this . div , " " ) ;
2008-06-14 06:26:48 +00:00
appendChildNodes ( this . div , this . delete _button ) ;
2008-06-13 22:55:19 +00:00
appendChildNodes ( this . div , createDOM ( "div" , { } , this . embed _checkbox , embed _label ) ) ;
2008-06-19 00:14:07 +00:00
appendChildNodes ( this . div , this . image _settings _area ) ;
2008-02-05 19:45:11 +00:00
// get the file's name and size from the server
this . invoker . invoke (
"/files/stats" , "GET" , {
2008-02-20 23:25:13 +00:00
"file_id" : this . file _id
2008-02-05 19:45:11 +00:00
} ,
function ( result ) {
// if the user has already started typing something, don't overwrite it
2008-02-20 23:25:13 +00:00
if ( self . filename _field . value . length == 0 ) {
2008-02-05 19:45:11 +00:00
self . filename _field . value = result . filename ;
2008-02-20 23:25:13 +00:00
self . previous _filename = result . filename ;
}
2008-02-05 19:45:11 +00:00
replaceChildNodes ( self . file _size , bytes _to _megabytes ( result . size _bytes , true ) ) ;
2008-02-20 00:57:10 +00:00
self . wiki . display _storage _usage ( result . storage _bytes ) ;
2008-02-05 19:45:11 +00:00
}
) ;
2008-02-19 00:47:59 +00:00
2008-06-14 06:26:48 +00:00
connect ( this . delete _button , "onclick" , function ( event ) { self . delete _button _clicked ( event ) ; } ) ;
2008-06-13 22:55:19 +00:00
connect ( this . embed _checkbox , "onclick" , function ( event ) { self . embed _clicked ( event ) ; } ) ;
2008-06-19 00:14:07 +00:00
connect ( this . small _size _radio , "onclick" , function ( event ) { self . resize _image ( event , "small" ) ; } ) ;
connect ( this . medium _size _radio , "onclick" , function ( event ) { self . resize _image ( event , "medium" ) ; } ) ;
connect ( this . large _size _radio , "onclick" , function ( event ) { self . resize _image ( event , "large" ) ; } ) ;
2008-06-14 06:26:48 +00:00
connect ( this . left _justify _radio , "onclick" , function ( event ) { self . justify _image ( event , "left" ) ; } ) ;
connect ( this . center _justify _radio , "onclick" , function ( event ) { self . justify _image ( event , "center" ) ; } ) ;
connect ( this . right _justify _radio , "onclick" , function ( event ) { self . justify _image ( event , "right" ) ; } ) ;
2008-02-20 23:25:13 +00:00
2008-02-19 00:47:59 +00:00
editor . focus ( ) ;
2008-06-16 22:07:17 +00:00
Pulldown . prototype . finish _init . call ( this ) ;
2008-02-05 19:45:11 +00:00
}
File _link _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
File _link _pulldown . prototype . constructor = File _link _pulldown ;
File _link _pulldown . prototype . filename _field _clicked = function ( event ) {
event . stop ( ) ;
}
File _link _pulldown . prototype . filename _field _focused = function ( event ) {
this . filename _field . select ( ) ;
}
File _link _pulldown . prototype . filename _field _changed = function ( event ) {
// if the filename is actually unchanged, then bail
var filename = strip ( this . filename _field . value ) ;
2008-02-25 21:56:33 +00:00
if ( filename == "" || filename == this . previous _filename )
2008-02-05 19:45:11 +00:00
return ;
2008-02-20 23:25:13 +00:00
var title = link _title ( this . link ) ;
if ( title == this . previous _filename )
replaceChildNodes ( this . link , this . editor . document . createTextNode ( filename ) ) ;
2008-02-05 19:45:11 +00:00
this . previous _filename = filename ;
this . invoker . invoke (
2008-02-20 23:25:13 +00:00
"/files/rename" , "POST" , {
"file_id" : this . file _id ,
2008-02-05 19:45:11 +00:00
"filename" : filename
}
) ;
}
File _link _pulldown . prototype . filename _field _key _pressed = function ( event ) {
// if enter is pressed, consider the title field altered. this is necessary because IE neglects
// to issue an onchange event when enter is pressed in an input field
if ( event . key ( ) . code == 13 ) {
this . filename _field _changed ( ) ;
event . stop ( ) ;
}
}
2008-02-20 23:25:13 +00:00
File _link _pulldown . prototype . delete _button _clicked = function ( event ) {
var self = this ;
2008-06-13 22:55:19 +00:00
// change the embedded image (if any) back into a plain file link before deletion
2008-06-14 06:26:48 +00:00
if ( getFirstElementByTagAndClassName ( "img" , null , this . link ) )
2008-06-13 22:55:19 +00:00
this . link . innerHTML = this . link _title || this . filename _field . value || this . previous _filename ;
2008-02-20 23:25:13 +00:00
this . invoker . invoke (
"/files/delete" , "POST" , {
"file_id" : this . file _id
} ,
function ( result ) { self . wiki . display _storage _usage ( result . storage _bytes ) ; }
) ;
2008-02-21 00:41:08 +00:00
this . link . href = "/files/new" ;
this . editor . focus ( ) ;
2008-02-22 21:08:29 +00:00
this . wiki . display _message ( 'The file "' + strip ( this . filename _field . value ) + '" has been deleted.' ) ;
2008-02-20 23:25:13 +00:00
}
2008-06-13 22:55:19 +00:00
File _link _pulldown . prototype . embed _clicked = function ( event ) {
if ( this . embed _checkbox . checked ) {
2008-06-19 00:14:07 +00:00
var image = createDOM ( "img" , { "src" : "/files/thumbnail?file_id=" + this . file _id + "&max_size=" + SMALL _MAX _IMAGE _SIZE , "class" : "left_justified" } ) ;
2008-06-13 22:55:19 +00:00
var image _span = createDOM ( "span" , { } , image ) ;
this . link _title = link _title ( this . link ) ;
this . link . innerHTML = image _span . innerHTML ;
addElementClass ( this . thumbnail _span , "undisplayed" ) ;
2008-06-19 00:14:07 +00:00
removeElementClass ( this . image _settings _area , "undisplayed" ) ;
2008-06-13 22:55:19 +00:00
} else {
2008-06-16 20:42:52 +00:00
this . justify _image ( "left" ) ;
this . left _justify _radio . checked = true ;
2008-06-19 00:14:07 +00:00
this . small _size _radio . checked = true ;
2008-06-13 22:55:19 +00:00
removeElementClass ( this . thumbnail _span , "undisplayed" ) ;
2008-06-19 00:14:07 +00:00
addElementClass ( this . image _settings _area , "undisplayed" ) ;
2008-06-13 22:55:19 +00:00
this . link . innerHTML = this . link _title || this . filename _field . value || this . previous _filename ;
}
2008-06-30 05:26:08 +00:00
this . update _position ( ) ;
2008-06-14 06:26:48 +00:00
this . editor . resize ( ) ;
}
2008-06-19 00:14:07 +00:00
File _link _pulldown . prototype . resize _image = function ( event , position ) {
var image = getFirstElementByTagAndClassName ( "img" , null , this . link ) ;
if ( ! image )
return ;
if ( position == "large" ) {
var max _size = LARGE _MAX _IMAGE _SIZE ;
} else if ( position == "medium" ) {
var max _size = MEDIUM _MAX _IMAGE _SIZE ;
} else {
var max _size = SMALL _MAX _IMAGE _SIZE ;
}
// when the newly resized image finishes loading, update the pulldown position and resize the
// editor
var self = this ;
connect ( image , "onload" , function ( ) {
2008-06-30 05:26:08 +00:00
self . update _position ( ) ;
2008-06-19 00:14:07 +00:00
self . editor . resize ( ) ;
} ) ;
image . setAttribute ( "src" , "/files/thumbnail?file_id=" + this . file _id + "&max_size=" + max _size ) ;
}
2008-06-14 06:26:48 +00:00
File _link _pulldown . prototype . justify _image = function ( event , position ) {
var image = getFirstElementByTagAndClassName ( "img" , null , this . link ) ;
if ( ! image )
return ;
removeElementClass ( image , "left_justified" ) ;
removeElementClass ( image , "center_justified" ) ;
removeElementClass ( image , "right_justified" ) ;
addElementClass ( image , position + "_justified" ) ;
2008-06-30 05:26:08 +00:00
this . update _position ( ) ;
2008-06-14 06:26:48 +00:00
this . editor . resize ( ) ;
2008-06-13 22:55:19 +00:00
}
2008-06-30 05:26:08 +00:00
File _link _pulldown . prototype . update _position = function ( always _left _align ) {
Pulldown . prototype . update _position . call ( this , always _left _align ) ;
2008-02-05 19:45:11 +00:00
}
File _link _pulldown . prototype . shutdown = function ( ) {
Pulldown . prototype . shutdown . call ( this ) ;
disconnectAll ( this . filename _field ) ;
if ( this . link )
this . link . pulldown = null ;
2008-06-14 06:26:48 +00:00
disconnectAll ( this . delete _button ) ;
disconnectAll ( this . embed _checkbox ) ;
disconnectAll ( this . left _justify _radio ) ;
disconnectAll ( this . center _justify _radio ) ;
disconnectAll ( this . right _justify _radio ) ;
2008-01-31 21:52:32 +00:00
}
2008-06-27 23:11:09 +00:00
2008-06-30 05:26:08 +00:00
function Suggest _pulldown ( wiki , notebook _id , invoker , anchor , relative _to , search _text , key _press _node ) {
2008-06-27 23:11:09 +00:00
anchor . pulldown = this ;
this . anchor = anchor ;
this . previous _search _text = "" ;
2008-07-07 22:49:01 +00:00
this . sequence _number = 0 ;
2008-06-27 23:11:09 +00:00
2008-06-30 05:26:08 +00:00
Pulldown . call ( this , wiki , notebook _id , "suggest_pulldown" , anchor , relative _to ) ;
2008-06-27 23:11:09 +00:00
this . invoker = invoker ;
this . update _suggestions ( search _text ) ;
var self = this ;
this . key _handler = connect ( key _press _node , "onkeydown" , function ( event ) { self . key _pressed ( event ) ; } ) ;
2008-06-30 05:26:08 +00:00
Pulldown . prototype . update _position . call ( this , true ) ;
2008-06-27 23:11:09 +00:00
}
Suggest _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
Suggest _pulldown . prototype . constructor = Suggest _pulldown ;
Suggest _pulldown . prototype . update _suggestions = function ( search _text ) {
// if the search text hasn't changed since last time, bail
if ( this . previous _search _text == search _text )
return ;
// if there is no search text, hide the pulldown and bail
if ( ! search _text ) {
addElementClass ( this . div , "invisible" ) ;
2008-06-30 05:26:08 +00:00
this . previous _search _text = "" ;
2008-06-27 23:11:09 +00:00
return ;
}
var self = this ;
this . previous _search _text = search _text ;
2008-07-07 22:49:01 +00:00
this . sequence _number += 1 ;
var sequence _number = this . sequence _number ;
2008-06-27 23:11:09 +00:00
this . invoker . invoke ( "/notebooks/search_titles" , "GET" , {
"notebook_id" : this . notebook _id ,
"search_text" : search _text
} ,
2008-07-07 22:49:01 +00:00
function ( result ) {
// if the sequence number is not what we expect, then this must not be most recent suggests
// update, so bail without displaying the result
if ( self . sequence _number != sequence _number )
return ;
self . display _suggestions ( result , search _text ) ;
}
2008-06-27 23:11:09 +00:00
) ;
}
Suggest _pulldown . prototype . display _suggestions = function ( result , search _text ) {
if ( result . notes . length == 0 ) {
addElementClass ( this . div , "invisible" ) ;
return ;
}
removeElementClass ( this . div , "invisible" ) ;
var results _list = createDOM ( "div" ) ;
var self = this ;
function connect _link ( suggest _link , note ) {
connect ( suggest _link , "onclick" , function ( event ) { self . suggestion _selected ( event , note ) ; } ) ;
}
for ( var i in result . notes ) {
var note = result . notes [ i ] ;
if ( ! note . title ) continue ;
var suggest _link = createDOM ( "a" , { "href" : "#" , "class" : "pulldown_link" } ) ;
suggest _link . innerHTML = note . summary ;
suggest _link . note = note ;
appendChildNodes ( results _list , createDOM ( "div" , { "class" : "suggestion" } , suggest _link ) ) ;
connect _link ( suggest _link , note ) ;
}
replaceChildNodes ( this . div , results _list ) ;
}
Suggest _pulldown . prototype . suggestion _selected = function ( event , note ) {
event . stop ( ) ;
signal ( this , "suggestion_selected" , note ) ;
}
Suggest _pulldown . prototype . key _pressed = function ( event ) {
// an invisible Suggest_pulldown shouldn't grab keypresses
if ( hasElementClass ( this . div , "invisible" ) )
return ;
var code = event . key ( ) . code ;
2008-06-29 20:53:49 +00:00
var selected = getFirstElementByTagAndClassName ( "div" , "selected_suggestion" , this . div ) ;
2008-06-27 23:11:09 +00:00
2008-06-29 20:13:20 +00:00
// up arrow or shift-tab: move up to the previous suggestion
if ( code == 38 || ( code == 9 && event . modifier ( ) . shift ) ) {
2008-06-29 20:53:49 +00:00
this . previous _suggestion ( selected ) ;
2008-06-29 20:13:20 +00:00
// down arrow or tab: move down to the previous suggestion
} else if ( code == 40 || code == 9 ) {
2008-06-29 20:53:49 +00:00
this . next _suggestion ( selected ) ;
2008-06-27 23:11:09 +00:00
// enter: select current suggestion
} else if ( code == 13 ) {
var suggest _link = getFirstElementByTagAndClassName ( "a" , "pulldown_link" , selected ) ;
if ( selected )
this . suggestion _selected ( event , suggest _link . note ) ;
2008-06-30 03:32:13 +00:00
else // if nothing is selected, don't handle enter
return ;
2008-06-27 23:11:09 +00:00
// escape: hide the suggestions
} else if ( code == 27 ) {
addElementClass ( this . div , "invisible" ) ;
// otherwise, not a key this method handles
} else {
return ;
}
event . stop ( ) ;
}
2008-06-29 20:53:49 +00:00
Suggest _pulldown . prototype . previous _suggestion = function ( selected ) {
// if something is selected and there's a previous suggestion in the list, move the selection up
if ( selected && selected . previousSibling ) {
removeElementClass ( selected , "selected_suggestion" ) ;
addElementClass ( selected . previousSibling , "selected_suggestion" ) ;
// otherwise, hide the Suggest_pulldown
} else {
addElementClass ( this . div , "invisible" ) ;
}
}
Suggest _pulldown . prototype . next _suggestion = function ( selected ) {
// if something is selected and there's a next suggestion in the list, move the selection down
if ( selected ) {
if ( selected . nextSibling ) {
removeElementClass ( selected , "selected_suggestion" ) ;
addElementClass ( selected . nextSibling , "selected_suggestion" ) ;
}
// if nothing is selected yet, then just select the first link
} else {
var suggest _link = getFirstElementByTagAndClassName ( "a" , "pulldown_link" , this . div ) ;
addElementClass ( suggest _link . parentNode , "selected_suggestion" ) ;
}
}
2008-06-30 05:26:08 +00:00
Suggest _pulldown . prototype . update _position = function ( always _left _align ) {
// ignore the requested always_left_align value and force it to true, since Suggest_pulldown
// looks better that way
Pulldown . prototype . update _position . call ( this , true ) ;
2008-06-27 23:11:09 +00:00
}
2008-06-30 03:32:13 +00:00
Suggest _pulldown . prototype . something _selected = function ( ) {
if ( hasElementClass ( this . div , "invisible" ) )
return false ;
var selected = getFirstElementByTagAndClassName ( "div" , "selected_suggestion" , this . div ) ;
if ( selected )
return true ;
return false ;
}
2008-07-12 21:24:23 +00:00
Suggest _pulldown . prototype . visible = function ( ) {
return ! hasElementClass ( this . div , "invisible" ) ;
}
2008-06-27 23:11:09 +00:00
Suggest _pulldown . prototype . shutdown = function ( ) {
Pulldown . prototype . shutdown . call ( this ) ;
this . anchor . pulldown = null ;
disconnectAll ( this ) ;
disconnect ( this . key _handler ) ;
}
2008-12-11 07:21:44 +00:00
function Font _pulldown ( wiki , notebook _id , invoker , anchor , editor ) {
anchor . pulldown = this ;
this . anchor = anchor ;
this . editor = editor ;
2008-12-17 20:15:08 +00:00
this . initial _selected _mark = null ;
2008-12-11 07:21:44 +00:00
Pulldown . call ( this , wiki , notebook _id , "font_pulldown" , anchor ) ;
this . invoker = invoker ;
var fonts = [
2008-12-27 03:51:34 +00:00
[ "Arial" , "arial,sans-serif" ] ,
[ "Times New Roman" , "times new roman,serif" ] ,
[ "Courier" , "courier new,monospace" ] ,
[ "Comic Sans" , "comic sans ms,sans-serif" ] ,
2008-12-11 07:21:44 +00:00
[ "Garamond" , "garamond,serif" ] ,
[ "Georgia" , "georgia,serif" ] ,
[ "Tahoma" , "tahoma,sans-serif" ] ,
[ "Trebuchet" , "trebuchet ms,sans-serif" ] ,
[ "Verdana" , "verdana,sans-serif" ]
] ;
var self = this ;
2008-12-23 03:25:09 +00:00
var current _font _family = editor . query _command _value ( "fontname" ) ;
2008-12-23 07:26:01 +00:00
if ( current _font _family ) {
current _font _family = current _font _family . toLowerCase ( ) ;
2008-12-27 08:09:54 +00:00
current _font _family = current _font _family . replace ( /'/g , "" ) . replace ( /-webkit-/ , "" ) ;
current _font _family = current _font _family . split ( ',' ) [ 0 ] ;
2008-12-23 07:26:01 +00:00
}
2008-12-23 03:25:09 +00:00
2008-12-11 07:21:44 +00:00
for ( var i in fonts ) {
var font = fonts [ i ] ;
var font _name = font [ 0 ] ;
var font _family = font [ 1 ] ;
2008-12-27 03:32:12 +00:00
// using a button here instead of a <label> to make IE happy: when a <label> is used, clicking
// on the label steals focus from the editor iframe and prevents the font from being changed
var label = createDOM ( "input" , { "type" : "button" , "value" : font _name , "class" : "pulldown_label font_label_button" , "style" : "font-family: " + font _family + ";" } ) ;
2008-12-16 02:10:38 +00:00
2008-12-17 20:15:08 +00:00
var selected _mark _char = document . createTextNode ( "\u25cf" ) ;
2008-12-23 06:14:16 +00:00
if ( current _font _family && font _family . search ( current _font _family ) == 0 ) {
2008-12-27 08:32:37 +00:00
var selected _mark = createDOM ( "span" , { "class" : "selected_mark" } , selected _mark _char ) ;
2008-12-17 20:15:08 +00:00
this . initial _selected _mark = selected _mark ;
2008-12-16 02:10:38 +00:00
} else {
2008-12-27 08:32:37 +00:00
var selected _mark = createDOM ( "span" , { "class" : "selected_mark invisible" } , selected _mark _char ) ;
2008-12-16 02:10:38 +00:00
}
2008-12-17 20:15:08 +00:00
var div = createDOM ( "div" , { } , selected _mark , " " , label ) ;
2008-12-16 02:10:38 +00:00
2008-12-11 07:21:44 +00:00
label . font _family = font _family ;
2008-12-17 20:15:08 +00:00
label . selected _mark = selected _mark ;
2008-12-16 02:10:38 +00:00
appendChildNodes ( this . div , div ) ;
2008-12-11 07:21:44 +00:00
connect ( label , "onclick" , function ( event ) { self . font _name _clicked ( event ) ; } ) ;
}
Pulldown . prototype . finish _init . call ( this ) ;
}
Font _pulldown . prototype = new function ( ) { this . prototype = Pulldown . prototype ; } ;
Font _pulldown . prototype . constructor = Font _pulldown ;
Font _pulldown . prototype . font _name _clicked = function ( event ) {
var label = event . src ( ) ;
2008-12-17 20:15:08 +00:00
if ( this . initial _selected _mark )
addElementClass ( this . initial _selected _mark , "invisible" ) ;
removeElementClass ( label . selected _mark , "invisible" ) ;
2008-12-16 02:10:38 +00:00
var self = this ;
setTimeout ( function ( ) {
self . editor . focus ( ) ;
self . editor . exec _command ( "fontname" , label . font _family ) ;
self . shutdown ( ) ;
} , 100 ) ;
2008-12-11 07:21:44 +00:00
}
Font _pulldown . prototype . shutdown = function ( ) {
Pulldown . prototype . shutdown . call ( this ) ;
this . anchor . pulldown = null ;
disconnectAll ( this ) ;
}
2008-04-09 23:31:30 +00:00
function Note _tree ( wiki , notebook _id , invoker ) {
this . wiki = wiki ;
this . notebook _id = notebook _id ;
this . invoker = invoker ;
2008-11-14 20:34:06 +00:00
this . suggest _pulldown = null ;
2008-04-09 23:31:30 +00:00
// add onclick handlers to the initial note links within the tree
var links = getElementsByTagAndClassName ( "a" , "note_tree_link" , "note_tree_area" ) ;
var self = this ;
2008-04-12 00:51:32 +00:00
function connect _expander ( note _id ) {
2008-04-16 00:28:18 +00:00
connect ( "note_tree_expander_" + note _id , "onclick" , function ( event ) { self . expand _collapse _link ( event , note _id ) ; } ) ;
2008-04-12 00:51:32 +00:00
}
2008-04-09 23:31:30 +00:00
for ( var i in links ) {
var link = links [ i ] ;
2008-04-12 00:51:32 +00:00
var query = parse _query ( link ) ;
var note _id = query [ "note_id" ] ;
if ( note _id )
connect _expander ( note _id ) ;
2008-04-09 23:31:30 +00:00
connect ( link , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
}
// connect to the wiki note events
connect ( wiki , "note_renamed" , function ( editor , new _title ) { self . rename _link ( editor , new _title ) ; } ) ;
2008-11-14 20:34:06 +00:00
connect ( wiki , "note_added" , function ( editor ) { self . add _root _link ( editor . id , editor . title , editor . contents ( ) , editor . startup ) ; } ) ;
2008-04-09 23:31:30 +00:00
connect ( wiki , "note_removed" , function ( id ) { self . remove _link ( id ) ; } ) ;
2008-04-10 18:45:52 +00:00
connect ( wiki , "note_saved" , function ( editor ) { self . update _link ( editor ) ; } ) ;
2008-04-09 23:31:30 +00:00
}
Note _tree . prototype . link _clicked = function ( event ) {
var link = event . target ( ) ;
var query = parse _query ( link ) ;
var note _id = query [ "note_id" ] ;
2008-04-13 21:25:47 +00:00
var title = query [ "title" ] ;
2008-04-09 23:31:30 +00:00
if ( ! note _id )
return ;
2008-04-13 21:25:47 +00:00
this . wiki . load _editor ( title , note _id ) ;
2008-04-09 23:31:30 +00:00
event . stop ( ) ;
}
2008-04-16 01:14:37 +00:00
LINK _PATTERN = /<a\s+([^>]+\s)?href="[^"]+"[^>]*>/i ;
2008-04-10 19:40:17 +00:00
2008-11-14 20:34:06 +00:00
Note _tree . prototype . add _root _link = function ( note _id , title , contents , startup ) {
2008-04-09 23:31:30 +00:00
// for now, only add startup notes to the note tree
2008-11-14 20:34:06 +00:00
if ( ! startup )
2008-04-09 23:31:30 +00:00
return ;
2008-04-13 22:29:50 +00:00
// if the root note is already present in the tree, no need to add it again
2008-11-14 20:34:06 +00:00
var item = getElement ( "note_tree_item_" + note _id ) ;
if ( item ) {
new Highlight ( item , { "endcolor" : "#fafafa" } ) ;
2008-04-13 22:29:50 +00:00
return ;
2008-11-14 20:34:06 +00:00
}
2008-04-13 22:29:50 +00:00
2008-11-14 20:34:06 +00:00
// display the tree expander arrow if the given note's contents contains any outgoing links
if ( LINK _PATTERN . exec ( contents ) )
var expander = createDOM ( "div" , { "class" : "tree_expander" , "id" : "note_tree_expander_" + note _id } ) ;
2008-04-10 19:40:17 +00:00
else
2008-11-14 20:34:06 +00:00
var expander = createDOM ( "div" , { "class" : "tree_expander_empty" , "id" : "note_tree_expander_" + note _id } ) ;
2008-04-10 19:40:17 +00:00
2008-04-09 23:31:30 +00:00
var link = createDOM ( "a" , {
2008-11-14 20:34:06 +00:00
"href" : "/notebooks/" + this . notebook _id + "?note_id=" + note _id ,
"id" : "note_tree_link_" + note _id ,
2008-04-09 23:31:30 +00:00
"class" : "note_tree_link"
2009-01-07 22:15:22 +00:00
} , normalize _title ( title ) ) ;
2008-04-09 23:31:30 +00:00
2008-11-14 20:34:06 +00:00
insertSiblingNodesBefore ( "new_note_tree_link_row" , createDOM (
2008-04-12 00:51:32 +00:00
"tr" ,
2008-11-14 20:34:06 +00:00
{ "id" : "note_tree_item_" + note _id , "class" : "note_tree_item" } ,
2008-04-16 06:38:19 +00:00
createDOM ( "td" , { } , expander ) ,
2008-04-12 00:51:32 +00:00
createDOM ( "td" , { } , link )
2008-04-09 23:31:30 +00:00
) ) ;
var self = this ;
2008-11-14 20:34:06 +00:00
connect ( expander , "onclick" , function ( event ) { self . expand _collapse _link ( event , note _id ) ; } ) ;
2008-04-09 23:31:30 +00:00
connect ( link , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
}
2008-04-12 00:51:32 +00:00
Note _tree . prototype . remove _link = function ( note _id ) {
2008-04-13 21:57:03 +00:00
var item = getElement ( "note_tree_item_" + note _id ) ;
if ( item )
removeElement ( item ) ;
2008-04-15 19:40:36 +00:00
if ( getFirstElementByTagAndClassName ( "a" , null , "note_tree_root_table" ) )
return ;
2008-04-09 23:31:30 +00:00
}
Note _tree . prototype . rename _link = function ( editor , new _title ) {
2008-04-10 00:05:03 +00:00
var link = getElement ( "note_tree_link_" + editor . id ) ;
2008-04-16 00:28:18 +00:00
if ( link )
2009-01-07 22:15:22 +00:00
replaceChildNodes ( link , normalize _title ( new _title ) ) ;
2008-04-09 23:31:30 +00:00
}
2008-04-10 18:45:52 +00:00
Note _tree . prototype . update _link = function ( editor ) {
var link = getElement ( "note_tree_link_" + editor . id ) ;
2008-04-14 21:57:48 +00:00
if ( ! link && editor . startup ) {
2008-11-14 20:34:06 +00:00
this . add _root _link ( editor . id , editor . title , editor . contents ( ) , editor . startup ) ;
2008-04-10 18:45:52 +00:00
return ;
2008-04-14 20:28:42 +00:00
}
2008-04-10 18:45:52 +00:00
2008-04-14 21:57:48 +00:00
if ( link && ! editor . startup )
2008-04-10 18:45:52 +00:00
this . remove _link ( editor . id ) ;
2008-04-14 21:57:48 +00:00
// if the tree has any expanded links to the given editor's note, then update the children of
// those links
2008-04-14 23:54:04 +00:00
function update _links ( note _tree , notebook _id , note _id , link , children _area ) {
2008-04-14 21:57:48 +00:00
note _tree . invoker . invoke (
"/notebooks/load_note_links" , "GET" , {
"notebook_id" : notebook _id ,
"note_id" : note _id
} ,
2008-04-14 23:54:04 +00:00
function ( result ) { note _tree . display _child _links ( result , link , children _area ) ; }
2008-04-14 21:57:48 +00:00
) ;
}
var links = getElementsByTagAndClassName ( "a" , null , "note_tree_root_table" ) ;
for ( var i in links ) {
var link = links [ i ]
var note _id = parse _query ( link ) [ "note_id" ] ;
2008-04-14 23:54:04 +00:00
var children _area = getFirstElementByTagAndClassName ( "div" , "note_tree_children_area" , link . parentNode ) ;
2008-04-14 21:57:48 +00:00
2008-04-14 23:54:04 +00:00
if ( note _id != editor . id )
continue ;
update _links ( this , this . notebook _id , editor . id , link , children _area ) ;
2008-04-14 21:57:48 +00:00
}
2008-04-09 23:31:30 +00:00
}
2008-04-16 00:28:18 +00:00
Note _tree . prototype . expand _collapse _link = function ( event , note _id ) {
2008-04-12 00:51:32 +00:00
var expander = event . target ( ) ;
if ( ! expander || hasElementClass ( expander , "tree_expander_empty" ) )
return ;
// if it's collapsed, expand it
if ( hasElementClass ( expander , "tree_expander" ) ) {
2008-04-14 20:14:32 +00:00
// first check if the expander is for a link to a parent/grandparent/etc. if so, just highlight
// the containing table instead of performing an expansion
2008-04-16 06:38:19 +00:00
var parent _node = expander . parentNode . parentNode ;
2008-04-14 20:14:32 +00:00
while ( ! hasElementClass ( parent _node , "note_tree_root_table" ) ) {
parent _node = parent _node . parentNode ;
if ( ! parent _node ) break ;
var parent _link = parent _node . previousSibling ;
if ( ! parent _link || ! hasElementClass ( parent _link , "note_tree_link" ) ) continue ;
var parent _note _id = parse _query ( parent _link ) [ "note_id" ] ;
if ( note _id == parent _note _id ) {
new Highlight ( parent _node . parentNode , { "endcolor" : "#fafafa" } ) ;
return ;
}
}
2008-04-12 21:57:29 +00:00
var children _area = createDOM ( "div" , { "class" : "note_tree_children_area" } ,
2008-04-12 00:51:32 +00:00
createDOM ( "span" , { "class" : "note_tree_loading" } , "loading..." )
) ;
swapElementClass ( expander , "tree_expander" , "tree_expander_expanded" ) ;
2008-04-16 06:38:19 +00:00
var link = getFirstElementByTagAndClassName ( "a" , null , expander . parentNode . parentNode ) ;
2008-04-12 21:57:29 +00:00
insertSiblingNodesAfter ( link , children _area ) ;
2008-04-12 00:51:32 +00:00
var self = this ;
this . invoker . invoke (
"/notebooks/load_note_links" , "GET" , {
"notebook_id" : this . notebook _id ,
"note_id" : note _id
} ,
2008-04-14 23:54:04 +00:00
function ( result ) { self . display _child _links ( result , link , children _area ) ; }
2008-04-12 00:51:32 +00:00
) ;
return ;
}
// if it's expanded, collapse it
if ( hasElementClass ( expander , "tree_expander_expanded" ) ) {
swapElementClass ( expander , "tree_expander_expanded" , "tree_expander" ) ;
2008-04-16 06:38:19 +00:00
var children = getFirstElementByTagAndClassName ( "div" , "note_tree_children_area" , expander . parentNode . parentNode ) ;
2008-04-12 00:51:32 +00:00
if ( children )
removeElement ( children ) ;
}
2008-04-09 23:31:30 +00:00
}
2008-04-14 23:54:04 +00:00
Note _tree . prototype . display _child _links = function ( result , link , children _area ) {
2008-04-13 07:28:32 +00:00
var self = this ;
function connect _expander ( expander , note _id ) {
2008-04-16 00:28:18 +00:00
connect ( expander , "onclick" , function ( event ) { self . expand _collapse _link ( event , note _id ) ; } ) ;
2008-04-13 07:28:32 +00:00
}
var span = createDOM ( "span" ) ;
span . innerHTML = result . tree _html ;
2008-04-14 23:54:04 +00:00
// if there's a children area, replace its contents and add an onclick handler for each newly
// loaded expander and each note link
if ( children _area ) {
replaceChildNodes ( children _area , span ) ;
var child _links = getElementsByTagAndClassName ( "a" , null , children _area ) ;
for ( var i in child _links ) {
var child _link = child _links [ i ] ;
connect ( child _link , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
2008-04-16 06:38:19 +00:00
var expander = getFirstElementByTagAndClassName ( "div" , "tree_expander" , child _link . parentNode . parentNode ) ;
2008-04-14 23:54:04 +00:00
if ( expander ) {
var note _id = parse _query ( child _link ) [ "note_id" ] ;
if ( note _id )
connect _expander ( expander , note _id ) ;
}
}
} else {
var child _links = getElementsByTagAndClassName ( "a" , null , span ) ;
}
// if the parent has no children anymore, remove its expander arrow
if ( child _links . length == 0 ) {
if ( children _area )
removeElement ( children _area ) ;
2008-04-16 06:38:19 +00:00
var expander = getFirstElementByTagAndClassName ( "div" , "tree_expander" , link . parentNode . parentNode ) ;
if ( expander && link . parentNode . parentNode == expander . parentNode . parentNode ) {
2008-04-14 23:54:04 +00:00
swapElementClass ( expander , "tree_expander" , "tree_expander_empty" ) ;
disconnectAll ( expander ) ;
return ;
}
2008-04-13 07:28:32 +00:00
2008-04-16 06:38:19 +00:00
expander = getFirstElementByTagAndClassName ( "div" , "tree_expander_expanded" , link . parentNode . parentNode ) ;
if ( expander && link . parentNode . parentNode == expander . parentNode . parentNode ) {
2008-04-14 23:54:04 +00:00
swapElementClass ( expander , "tree_expander_expanded" , "tree_expander_empty" ) ;
disconnectAll ( expander ) ;
return ;
2008-04-13 07:28:32 +00:00
}
2008-04-14 23:54:04 +00:00
return ;
2008-04-13 07:28:32 +00:00
}
2008-04-14 23:54:04 +00:00
// if a note without an expander arrow now has children, add an expander arrow for it
2008-04-16 06:38:19 +00:00
var expander = getFirstElementByTagAndClassName ( "div" , "tree_expander_empty" , link . parentNode . parentNode ) ;
if ( ! expander || link . parentNode . parentNode != expander . parentNode . parentNode ) return ;
2008-04-14 23:54:04 +00:00
swapElementClass ( expander , "tree_expander_empty" , "tree_expander" ) ;
var note _id = parse _query ( link ) [ "note_id" ] ;
2008-04-16 00:44:57 +00:00
disconnectAll ( expander ) ;
2008-04-14 23:54:04 +00:00
connect _expander ( expander , note _id ) ;
2008-04-13 07:28:32 +00:00
}
2008-04-16 00:28:18 +00:00
2008-11-14 20:34:06 +00:00
Note _tree . prototype . start _link _add = function ( ) {
// if the add is already in progress, end the add instead of starting one
var new _note _tree _link _field = getElement ( "new_note_tree_link_field" ) ;
if ( new _note _tree _link _field ) {
this . end _link _add ( ) ;
return ;
}
link _field = createDOM (
"input" , {
"type" : "text" ,
"value" : "" ,
"id" : "new_note_tree_link_field" ,
"name" : "new_note_tree_link_field" ,
2008-11-14 23:41:18 +00:00
"title" : "Enter the title of an existing note." ,
2008-11-14 20:34:06 +00:00
"size" : "10" ,
2008-11-15 00:51:35 +00:00
"autocomplete" : "off" ,
2008-11-14 20:34:06 +00:00
"class" : "text_field"
}
) ;
var ok _button = createDOM (
"input" , {
"type" : "button" ,
"class" : "message_button" ,
"value" : "add" ,
"title" : "add the note"
}
) ;
var form = createDOM (
"form" , { "id" : "new_note_tree_link_form" , "class" : "inline" } , link _field , ok _button
) ;
replaceChildNodes ( "new_note_tree_link_area" , form ) ;
// add a suggest pulldown beneath the link name text field
var self = this ;
this . suggest _pulldown = new Suggest _pulldown (
this . wiki , this . notebook _id , this . invoker , link _field , null , "" , link _field
) ;
connect ( this . suggest _pulldown , "suggestion_selected" , function ( note ) {
2008-11-15 00:51:35 +00:00
self . end _link _add ( note ) ;
2008-11-14 20:34:06 +00:00
} ) ;
connect ( form , "onsubmit" , function ( event ) {
self . end _link _add ( ) ;
event . stop ( ) ;
} ) ;
connect ( form , "onkeyup" , function ( event ) {
self . suggest _pulldown . update _suggestions ( link _field . value ) ;
} ) ;
connect ( ok _button , "onclick" , function ( event ) {
self . end _link _add ( ) ;
event . stop ( ) ;
} ) ;
link _field . focus ( ) ;
link _field . select ( ) ;
}
2008-11-15 00:51:35 +00:00
Note _tree . prototype . end _link _add = function ( note ) {
// if no note is provided, load it based on the title
if ( ! note ) {
var note _name = getElement ( "new_note_tree_link_field" ) . value ;
replaceChildNodes ( "new_note_tree_link_area" , "" ) ;
// if the new name is blank, bail
if ( /^\s*$/ . test ( note _name ) )
return ;
// load the requested note by title and add it as a root link
var self = this ;
this . invoker . invoke ( "/notebooks/load_note_by_title" , "GET" , {
"notebook_id" : this . notebook _id ,
"note_title" : note _name
} , function ( result ) {
self . save _and _display _startup _note ( result . note ) ;
} ) ;
// otherwise, a note is provided
} else {
replaceChildNodes ( "new_note_tree_link_area" , "" ) ;
this . save _and _display _startup _note ( note ) ;
}
2008-11-14 20:34:06 +00:00
2008-11-15 00:51:35 +00:00
if ( this . suggest _pulldown ) {
this . suggest _pulldown . shutdown ( ) ;
this . suggest _pulldown = null ;
}
}
Note _tree . prototype . save _and _display _startup _note = function ( note ) {
if ( ! note ) {
this . wiki . display _message ( "Sorry, a note by that title doesn't exist. (If you're trying to create a new note, then simply click that large \"+\" button on the left.)" ) ;
2008-11-14 20:34:06 +00:00
return ;
2008-11-15 00:51:35 +00:00
}
2008-11-14 20:34:06 +00:00
2008-11-15 00:51:35 +00:00
// if it's already a startup note, just highlight it and bail
if ( note . startup ) {
this . add _root _link ( note . object _id , note . title , note . contents , true ) ;
return ;
}
// mark the note as a startup note on the client
this . wiki . startup _notes [ note . object _id ] = true ;
2009-01-12 22:19:32 +00:00
var editor = editor _by _id ( note . object _id ) ;
if ( editor )
editor . startup = true ;
2008-11-15 00:51:35 +00:00
// save the note as a startup note on the server, and then add it to the note tree
2008-11-14 20:34:06 +00:00
var self = this ;
2008-11-15 00:51:35 +00:00
this . invoker . invoke ( "/notebooks/save_note" , "POST" , {
2008-11-14 20:34:06 +00:00
"notebook_id" : this . notebook _id ,
2008-11-15 00:51:35 +00:00
"note_id" : note . object _id ,
"contents" : note . contents ,
"startup" : true ,
"previous_revision" : note . revision
2008-11-14 20:34:06 +00:00
} , function ( result ) {
2008-11-15 00:51:35 +00:00
self . add _root _link ( note . object _id , note . title , note . contents , true ) ;
2008-11-14 20:34:06 +00:00
} ) ;
}
2008-04-29 00:54:08 +00:00
function Recent _notes ( wiki , notebook _id , invoker ) {
2008-04-16 00:28:18 +00:00
this . wiki = wiki ;
this . notebook _id = notebook _id ;
2008-04-29 00:54:08 +00:00
this . invoker = invoker ;
this . INCREMENT = 10 ;
this . max _recent _notes _count = this . INCREMENT ; // maximum increases when the user clicks "more"
this . total _notes _count = 0 ;
this . total _notes _count _updated ( wiki . total _notes _count ) ;
2008-04-16 00:28:18 +00:00
// if there's no recent notes table, there's nothing to do with recent notes!
if ( ! getElement ( "recent_notes_table" ) )
return ;
// add onclick handlers to the recent note links as well
var self = this ;
var recent _links = getElementsByTagAndClassName ( "a" , "recent_note_link" , "note_tree_area" ) ;
for ( var i in recent _links ) {
var link = recent _links [ i ] ;
var query = parse _query ( link ) ;
var note _id = query [ "note_id" ] ;
connect ( link , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
}
// connect to the wiki note events
connect ( wiki , "note_added" , function ( editor ) { self . add _link ( editor ) ; } ) ;
connect ( wiki , "note_removed" , function ( id ) { self . remove _link ( id ) ; } ) ;
connect ( wiki , "note_saved" , function ( editor ) { self . update _link ( editor ) ; } ) ;
2008-04-29 00:54:08 +00:00
connect ( wiki , "total_notes_count_updated" , function ( count ) { self . total _notes _count _updated ( count ) ; } ) ;
// connect to the "more" navigation link
connect ( "recent_notes_more_link" , "onclick" , function ( event ) { self . more _clicked ( event ) ; } ) ;
connect ( "recent_notes_less_link" , "onclick" , function ( event ) { self . less _clicked ( event ) ; } ) ;
}
Recent _notes . prototype . links _count = function ( ) {
var recent _links = getElementsByTagAndClassName ( "a" , "recent_note_link" , "note_tree_area" ) ;
return recent _links . length ;
}
Recent _notes . prototype . total _notes _count _updated = function ( count ) {
this . total _notes _count = count ;
this . update _navigation _links ( ) ;
}
Recent _notes . prototype . update _navigation _links = function ( ) {
2008-04-29 03:25:19 +00:00
var more _link = getElement ( "recent_notes_more_link" ) ;
if ( more _link ) {
if ( this . total _notes _count > this . max _recent _notes _count )
removeElementClass ( more _link , "undisplayed" ) ;
else
addElementClass ( more _link , "undisplayed" ) ;
}
2008-04-29 00:54:08 +00:00
2008-04-29 03:25:19 +00:00
var less _link = getElement ( "recent_notes_less_link" ) ;
if ( less _link ) {
if ( this . max _recent _notes _count > this . INCREMENT )
removeElementClass ( less _link , "undisplayed" ) ;
else
addElementClass ( less _link , "undisplayed" ) ;
}
2008-04-16 00:28:18 +00:00
}
Recent _notes . prototype . link _clicked = function ( event ) {
var link = event . target ( ) ;
var query = parse _query ( link ) ;
var note _id = query [ "note_id" ] ;
var title = query [ "title" ] ;
if ( ! note _id )
return ;
this . wiki . load _editor ( title , note _id ) ;
event . stop ( ) ;
}
2008-04-29 00:54:08 +00:00
Recent _notes . prototype . more _clicked = function ( event ) {
event . stop ( ) ;
this . max _recent _notes _count += this . INCREMENT ;
var self = this ;
var links _count = this . links _count ( ) ;
this . invoker . invoke (
"/notebooks/load_recent_updates" , "GET" , {
"notebook_id" : this . notebook _id ,
"start" : links _count ,
"count" : this . max _recent _notes _count - links _count
} ,
function ( result ) { self . append _links ( result ) ; }
) ;
}
Recent _notes . prototype . append _links = function ( result ) {
var self = this ;
var table = getElement ( "recent_notes_table" ) ;
var links _count = this . links _count ( ) ;
for ( var i in result . notes ) {
var note = result . notes [ i ] ;
var row = table . insertRow ( links _count + 1 ) ;
row . setAttribute ( "id" , "recent_note_item_" + note . object _id ) ;
addElementClass ( row , "recent_note_item" ) ;
var expander _td = row . insertCell ( 0 ) ;
expander _td . innerHTML = '<div id="recent_note_expander_' + note . object _id + '" class="tree_expander_empty"' ;
var link _td = row . insertCell ( 1 ) ;
link _td . innerHTML =
'<a href="/notebooks/' + this . notebook _id + '?note_id=' + note . object _id +
'" id="recent_note_link_' + note . object _id + '" class="recent_note_link">' +
2009-01-07 22:15:22 +00:00
( normalize _title ( note . title ) ) + '</a>' ;
2008-04-29 00:54:08 +00:00
connect ( "recent_note_link_" + note . object _id , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
links _count += 1 ;
}
this . update _navigation _links ( ) ;
}
Recent _notes . prototype . less _clicked = function ( event ) {
event . stop ( ) ;
this . max _recent _notes _count -= this . INCREMENT ;
var rows _to _remove _count = this . links _count ( ) - this . max _recent _notes _count ;
if ( rows _to _remove _count <= 0 )
return ;
var rows = getElementsByTagAndClassName ( "tr" , "recent_note_item" , "recent_notes_table" ) ;
var row _count = rows . length ;
for ( var i = 0 ; i < rows _to _remove _count ; ++ i ) {
removeElement ( rows [ row _count - i - 1 ] ) ;
}
this . update _navigation _links ( ) ;
}
2008-04-16 00:28:18 +00:00
Recent _notes . prototype . add _link = function ( editor ) {
// if the link is already present in the recent notes list, bail
var item = getElement ( "recent_note_item_" + editor . id )
if ( item ) return ;
// if there will be too many recent notes listed once another is added, then remove the last one
var recent _items = getElementsByTagAndClassName ( "tr" , "recent_note_item" , "recent_notes_table" ) ;
2008-04-29 00:54:08 +00:00
if ( recent _items && recent _items . length >= this . max _recent _notes _count ) {
2008-04-16 00:28:18 +00:00
var last _item = recent _items [ recent _items . length - 1 ] ;
removeElement ( last _item ) ;
}
// add a new recent note link at the top of the list
2008-04-16 06:38:19 +00:00
var expander = createDOM ( "div" , { "class" : "tree_expander_empty" , "id" : "recent_note_expander_" + editor . id } ) ;
2008-04-16 00:28:18 +00:00
var link = createDOM ( "a" , {
"href" : "/notebooks/" + this . notebook _id + "?note_id=" + editor . id ,
"id" : "recent_note_link_" + editor . id ,
"class" : "recent_note_link"
2009-01-07 22:15:22 +00:00
} , normalize _title ( editor . title ) ) ;
2008-04-16 00:28:18 +00:00
insertSiblingNodesAfter ( "recent_notes_top" , createDOM (
"tr" ,
{ "id" : "recent_note_item_" + editor . id , "class" : "recent_note_item" } ,
2008-04-16 06:38:19 +00:00
createDOM ( "td" , { } , expander ) ,
2008-04-16 00:28:18 +00:00
createDOM ( "td" , { } , link )
) ) ;
var self = this ;
connect ( link , "onclick" , function ( event ) { self . link _clicked ( event ) ; } ) ;
}
Recent _notes . prototype . remove _link = function ( note _id ) {
var item = getElement ( "recent_note_item_" + note _id ) ;
if ( ! item ) return ;
removeElement ( item ) ;
}
Recent _notes . prototype . update _link = function ( editor ) {
var item = getElement ( "recent_note_item_" + editor . id ) ;
var link = getElement ( "recent_note_link_" + editor . id ) ;
// the link isn't in the recent notes list, so add it
if ( ! item || ! link ) {
this . add _link ( editor ) ;
return ;
}
// the link is already in the recent notes list, so just move it to the top of the list
removeElement ( item ) ;
2009-01-07 22:15:22 +00:00
replaceChildNodes ( link , normalize _title ( editor . title ) ) ;
2008-04-16 00:28:18 +00:00
insertSiblingNodesAfter ( "recent_notes_top" , item ) ;
}
2008-05-13 22:52:20 +00:00
function Autosaver ( wiki ) {
this . wiki = wiki ;
this . last _state _change _time = null ;
this . timer = null ;
var INTERVAL _MILLISECONDS = 10000 ; // 10 seconds
function save _if _idle ( ) {
// if the note state has changed in the last few seconds (e.g. due to typing), don't save,
// but do reschedule a new timer
if ( this . last _state _change _time + INTERVAL _MILLISECONDS > ( new Date ( ) ) . getTime ( ) ) {
if ( this . timer ) clearTimeout ( this . timer ) ;
this . timer = setTimeout ( save _if _idle , INTERVAL _MILLISECONDS ) ;
return ;
}
this . wiki . save _editor ( ) ;
}
// whenever the focused editor's state changes, record the current time, cancel any current
// timer, and schedule a timer to save the editor in several seconds from now
var self = this ;
connect ( wiki , "note_state_changed" , function ( editor ) {
self . last _state _change _time = ( new Date ( ) ) . getTime ( ) ;
if ( self . timer ) clearTimeout ( self . timer ) ;
self . timer = setTimeout ( save _if _idle , INTERVAL _MILLISECONDS ) ;
} ) ;
}