From a56536ee5e10d13e1c42986d205ef32091ea1d47 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Wed, 9 Apr 2008 23:31:30 +0000 Subject: [PATCH] Began implementing note tree control on the left side of the page: * Added a fixed list of startup links. * When link in list is clicked, open corresponding note editor. * When a startup note is added/deleted, update the list. Still much more work to do on this before it's complete. --- static/css/ie6.css | 42 ++--- static/css/ie7.css | 16 +- static/css/style.css | 64 ++++++-- static/images/tree_arrow.png | Bin 0 -> 275 bytes static/images/tree_arrow.xcf | Bin 0 -> 1114 bytes static/images/tree_arrow_down.png | Bin 0 -> 275 bytes static/images/tree_arrow_down.xcf | Bin 0 -> 1051 bytes static/images/tree_arrow_down_hover.png | Bin 0 -> 258 bytes static/images/tree_arrow_down_hover.xcf | Bin 0 -> 1051 bytes static/images/tree_arrow_hover.png | Bin 0 -> 287 bytes static/images/tree_arrow_hover.xcf | Bin 0 -> 1114 bytes static/js/Wiki.js | 207 ++++++++++-------------- view/Link_area.py | 17 +- view/Main_page.py | 15 +- view/Note_tree_area.py | 31 ++++ 15 files changed, 208 insertions(+), 184 deletions(-) create mode 100644 static/images/tree_arrow.png create mode 100644 static/images/tree_arrow.xcf create mode 100644 static/images/tree_arrow_down.png create mode 100644 static/images/tree_arrow_down.xcf create mode 100644 static/images/tree_arrow_down_hover.png create mode 100644 static/images/tree_arrow_down_hover.xcf create mode 100644 static/images/tree_arrow_hover.png create mode 100644 static/images/tree_arrow_hover.xcf create mode 100644 view/Note_tree_area.py diff --git a/static/css/ie6.css b/static/css/ie6.css index 7e83f2f..9b86eaf 100644 --- a/static/css/ie6.css +++ b/static/css/ie6.css @@ -4,13 +4,20 @@ #toolbar { position: absolute; - float: none; - width: auto; + width: expression( eval( document.all.center_area && ( document.all.center_area.offsetLeft - 50 ) || 0 ) ); + text-align: right; +} + +#note_tree_area { + left: 0; + width: expression( eval( document.all.center_area && ( document.all.center_area.offsetLeft - 50 ) || 0 ) ); + position: absolute; top: expression( eval( document.compatMode && document.compatMode == 'CSS1Compat' ) ? documentElement.scrollTop + 80 : document.body.scrollTop + 80 ); - margin-left: expression( - document.body.clientWidth < ( 900 / 12 ) * - parseInt( document.body.currentStyle.fontSize ) ? "-120px": "-80px" - ); +} + +#note_tree_area_holder { + overflow: auto; + height: expression( eval( documentElement.offsetHeight - 100 ) ); } #status_area { @@ -27,23 +34,15 @@ #everything_area { width:expression( document.body.clientWidth < ( 1300 / 12 ) * - parseInt( document.body.currentStyle.fontSize ) ? "100%": "78em" + parseInt( document.body.currentStyle.fontSize ) ? "100%": "80em" ); } -#toolbar_area { - width:expression( - document.body.clientWidth < ( 1300 / 12 ) * - parseInt( document.body.currentStyle.fontSize ) ? "18%": "15em" - ); - text-align: right; -} - #center_area { float: right; width:expression( document.body.clientWidth < ( 1300 / 12 ) * - parseInt( document.body.currentStyle.fontSize ) ? "60%": "45em" + parseInt( document.body.currentStyle.fontSize ) ? "56%": "45em" ); } @@ -51,17 +50,6 @@ width: 100%; } -#link_area { - width:expression( - document.body.clientWidth < ( 1300 / 12 ) * - parseInt( document.body.currentStyle.fontSize ) ? "17%": "15em" - ); -} - -#link_area_wrapper { - margin-left: 1.5em; -} - .pulldown { height: expression( this.scrollHeight > 200 ? "200px" : "auto" ); width: expression( this.scrollHeight > 200 ? "12em" : "auto" ); diff --git a/static/css/ie7.css b/static/css/ie7.css index 47d10f4..81157b5 100644 --- a/static/css/ie7.css +++ b/static/css/ie7.css @@ -1,7 +1,19 @@ -#toolbar { - left: 2em; +#note_tree_area { + float: right; + margin-left: -6em; +} + +#note_tree_area_holder { + overflow: auto; + height: expression( eval( documentElement.offsetHeight - 100 ) ); +} + +#center_area { + float: right; + max-width: 59%; } #this_notebook_area_title { margin-top: 1.5em; } + diff --git a/static/css/style.css b/static/css/style.css index bb4e750..30cc2e1 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -28,26 +28,24 @@ img { #everything_area { margin: 0 auto; text-align: center; - width: 78em; - max-width: 100%; + max-width: 80em; } -#toolbar_area { +#left_area { float: left; - width: 15em; - max-width: 18%; + width: 17em; + max-width: 20%; } #toolbar { - width: 15em; - max-width: 18%; - position: fixed; text-align: right; z-index: 1; } #toolbar .button_wrapper { float: right; + margin-left: 15px; + margin-right: 15px; } #toolbar .image_button { @@ -232,17 +230,43 @@ img { background-image: url(/static/images/arrow_down_hover.png); } +#note_tree_area { + position: fixed; + width: 17em; + max-width: 20%; + text-align: left; + line-height: 140%; + top: 80px; + bottom: 1em; + overflow-y: visible; +} + +#note_tree_area_holder { + height: 100%; + overflow-y: auto; + padding-left: 1em; + margin-right: 1em; +} + +#note_tree_area_title { + margin-top: 0.5em; + margin-bottom: 0.25em; +} + #link_area { float: right; text-align: left; + line-height: 140%; + width: 20%; +} + +#link_area_holder { + padding-left: 1em; padding-right: 1em; - line-height: 100%; - width: 15em; - max-width: 17%; } #this_notebook_area_title { - margin-top: 0.5em; + margin-top: 0; margin-bottom: 0.25em; } @@ -500,8 +524,19 @@ img { } .link_area_item { - margin-top: 0.25em; - padding: 0.25em 0.25em 0.25em 0.5em; + padding: 0.2em 0.25em 0.2em 0.5em; +} + +.tree_expander { + float: left; + width: 20px; + height: 1.5em; + background: url(/static/images/tree_arrow.png) no-repeat center center; +} + +.tree_expander:hover { + background: url(/static/images/tree_arrow_hover.png) no-repeat center center; + cursor: pointer; } #storage_usage_area { @@ -607,6 +642,7 @@ img { .small_text { font-size: 90%; + font-weight: normal; } .new_feature_text { diff --git a/static/images/tree_arrow.png b/static/images/tree_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..17cbf7d0d0f33dbb1d03f1c10874021e3445b0e3 GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ-0U~39{!9Z2Bze2LF#HF>1$&oI28wVNctjR6 zFbJqIFz^d8>OYHK4-{lC@$_|Nzrn&OENyi<`_f9FkZg%-M2T~LZfWj~zrxX#NZNVE0cZ|12TODxr` zwFEsGtmVGnyC(I#GO4Gs>Dnv-rhC==_Ng>O;8d(Bh9{xrA+ zUW1mPGti9!6K@^-GuWz+Yin-U>8K!q&nUUEA1NnMO>wQ0mN;)Iad3FtpzLx^*B!@K zH9yi#ilKs+Wt{ZdO6VX_QLNlVhe5nqk)H2{?JyEDH?_#WaK!f3b}m!EPLbL~>BW>% zlNY}OD(%LXj;jM-?3jNc*qatCVzsM4CurVnDeAf#dS0xOuLi05XJ{0eETwrA!XFv4 z?~Dg)_C*t}Hk_CSeB|_0L>!9_2$5)C8MItrDwr=Y46BS`dH}>HS%ex~9m7k&beEAi z0K+ry!~7p9D=dhnVQ{UR$(VId{;;3g>4)s6RyvTo{gkI%zQd-H%K@yk9F8Yl(IvjLCj!iF_jZ_{k_J&T3_B4wT8`Z VjqF#KSYN3=87rNVzxS4Z*(Y}N<>&kwEg;Q8Tcx(33zd#|`64!_l=ltB<)VvY~=c3falGGH1 z^30M9g^-L?1$R&1fcGh?c|e8bo-U3d5|>*~Z{%e*#9wckg%h+EzohXLF>Ll%@nFq*X9A%ybNO zbde4TopEz{N5`IXcY|Ff%?x(AbocY`|IOCL9)(HWcKpDLhEYtN+%@8$=hEhBGq)|IRix_B+S}5q^7MCt zt&?QzdOQqhOFavM(`~^b*0>LO3gW#1L)DYW_Y;<`1Y-Bk&@!^wit{K;dm+T=s1Sfk?&3=b5~O9Cnd$A+DPgCq7D$4#*wZ4aP$b&c->$GwzUKvbRj zKGgFerAI}f5)8Ha<7P~M!u29^EaxK=S=%w3c{>xDm;={xZipFh2$sZW=48SWi)Ueo zzv{8&f=Em1q%2Kh$}-Vqg)Ag7P`G+CoUDDr9=^}vzviFILTT{Pyf6JqCCuMc`9isg L|2a9E<(K>dHj2s9 literal 0 HcmV?d00001 diff --git a/static/images/tree_arrow_down_hover.png b/static/images/tree_arrow_down_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..d717e6a281b751a595a9e0f174a6f5b4ba99c330 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^+(696!3HEnjZ%JqI7!~_E)4%caKYZ?lYt_f1s;*b z3=9HlAk5gj%|{d{$X?><>&kwEg;Q8TLTP7BDNsnZ#5JPCIX^cyHLrxhxhOTUBsE2$ zJhLQ2AtWPJ!QIn0;C+f}9#CPLr;B5V#O2o0ihPF+M3@7@ZzUf3pC>$TV!hbs*7hel zcUyg8t~4#Xq%$+(ytL={dmr`Jn(i?YW-vH*;9oE6UVHm1Q4?o2sCXNBy0`4zzFIJG vlHJ+X_wCj(A1XDL>UgTe~DWM4fK(kpW literal 0 HcmV?d00001 diff --git a/static/images/tree_arrow_down_hover.xcf b/static/images/tree_arrow_down_hover.xcf new file mode 100644 index 0000000000000000000000000000000000000000..89d1f55f8d412c16cf86db7b06e0a437e1cd3660 GIT binary patch literal 1051 zcmc&zy-ve05Vn)hmO=%HpV?y=ia~xpU*TsD+h_F8BHF`<%-;iDd7V^+Umg>~aFO0$xD?wgFBl+%~~$$1n619q<;o z2ae>O5+iRL_}35{5p3HGlU|R&Uu>gFqcW3?bdw}g-JI_nQuZfjamWQ-`h8~034L1U68gGNNt_{ z4p7?9Zi7(95j(KYg5+RPvdlH_VwpqpVTWVa{X~e2=aU9eJ)at9eoAp3rO{_X+%vm^ zXwM5L+_(xd9PoKC;3;w(yn*3?;(2NCT8UAxTw(~MK7(;nc=RLu#|C}7Xn@fKKs*lok literal 0 HcmV?d00001 diff --git a/static/images/tree_arrow_hover.png b/static/images/tree_arrow_hover.png new file mode 100644 index 0000000000000000000000000000000000000000..8da975d7a60737280973fb1c03e6ef1f3255b559 GIT binary patch literal 287 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJ-0U~39{!9Z2Bze2LF#HF>1$&oI28wVNctjR6 zFbJqIFz^d8>OYHK4-{lC@$_|Nzrn&OEN7^A?tcnUNVdc^qQp5rH#aq}gu%HeHL)Z$ zMWH;iBts!2BUQoO(>LIKifSHEVY8=;V~E7%((@a64=V_?K3sl7Il$<^QoAEEUzW7B zDcUgZy__z+dwD8%ON&SP&++8gxMWIz*Utlz z4BMtI{KL&4;AHWT>-oob+l=1zt1p?dqj$j{zUMMMhUyyo4@Xu1VGt}$dw1VfVNsoE cXZ_Rs_YaGN!u&4j1D(U*>FVdQ&MBb@0CI+D+5i9m literal 0 HcmV?d00001 diff --git a/static/images/tree_arrow_hover.xcf b/static/images/tree_arrow_hover.xcf new file mode 100644 index 0000000000000000000000000000000000000000..7980bdac641039d18bc1f45a2b6f43e58ef7859a GIT binary patch literal 1114 zcmc&yv2GJV5Z%4Ah;6V)1fT9VI@Jbam}s8r|T(v%bNexk&y zlQ&~z_Z{8LqD1wR+?*pu6}&BraxqoHq@~IW6_+MUi=(d8Nt{iyTu5j7d2$ws;b7>b z0UXzDD`>qcYxA)aS_EPO~kSP7X=qh!8+FekeZT)k0%OK&oiwHRo)GV>OVu< z$Zjd_qZWR{Sa{_2TRKK%bF6=XHh4@}(P<8CbY41cq%!s@47RzbCv&zBXien?BUk`_i< zZokWG@3@3xZA)BrQ;U^ju3+Sfuh61){<(#AObsJ7*Jx2Y%`Geo8Mh$|Y`{XxS<7yi y?cfN=LloH!Xe9n(u$b;!b@_XZ|7(42ER05*9c=C0l(fFqXgAh6h5zE#efAfx!0yBV literal 0 HcmV?d00001 diff --git a/static/js/Wiki.js b/static/js/Wiki.js index 92e68d9..227b1c7 100644 --- a/static/js/Wiki.js +++ b/static/js/Wiki.js @@ -9,7 +9,6 @@ function Wiki( invoker ) { this.parent_id = getElement( "parent_id" ).value; // id of the notebook containing this one this.startup_notes = new Array(); // map of startup notes: note id to bool this.open_editors = new Array(); // map of open notes: note title to editor - this.all_notes_editor = null; // editor for display of list of all notes this.search_results_editor = null; // editor for display of search results this.invoker = invoker; this.rate_plan = evalJSON( getElement( "rate_plan" ).value ); @@ -19,6 +18,7 @@ function Wiki( invoker ) { this.after_login = getElement( "after_login" ).value; this.signup_plan = getElement( "signup_plan" ).value; this.font_size = null; + this.note_tree = new Note_tree( this, this.notebook_id, this.invoker ); var total_notes_count_node = getElement( "total_notes_count" ); if ( total_notes_count_node ) @@ -312,14 +312,6 @@ Wiki.prototype.populate = function ( startup_notes, current_notes, note_read_wri ); } - var all_notes_link = getElement( "all_notes_link" ); - if ( all_notes_link ) { - connect( all_notes_link, "onclick", function ( event ) { - self.load_editor( "all notes", "null", null, null, getElement( "notes_top" ) ); - event.stop(); - } ); - } - var download_html_link = getElement( "download_html_link" ); if ( download_html_link ) { connect( download_html_link, "onclick", function ( event ) { @@ -398,8 +390,7 @@ Wiki.prototype.create_blank_editor = function ( event ) { var editor = this.create_editor( undefined, undefined, undefined, undefined, undefined, this.notebook.read_write, true, true ); this.increment_total_notes_count(); this.blank_editor_id = editor.id; - - this.add_all_notes_link( editor.id, "" ); + signal( this, "note_added", editor ); } Wiki.prototype.load_editor = function ( note_title, note_id, revision, link, position_after ) { @@ -443,13 +434,6 @@ Wiki.prototype.load_editor = function ( note_title, note_id, revision, link, pos var self = this; if ( pulldown_title || note_id == undefined || note_id == "new" || note_id == "null" ) { // if the note_title corresponds to a "magic" note's title, then dynamically highlight or create the note - if ( note_title == "all notes" ) { - this.invoker.invoke( - "/notebooks/all_notes", "GET", { "notebook_id": this.notebook.object_id }, - function( result ) { self.display_all_notes_list( result ); } - ); - return; - } if ( note_title == "search results" ) { var editor = this.open_editors[ note_title ]; if ( editor ) { @@ -513,14 +497,12 @@ Wiki.prototype.resolve_link = function ( note_title, link, callback ) { if ( link && link.target ) link.removeAttribute( "target" ); - if ( note_title == "all notes" || note_title == "search results" || note_title == "share this notebook" ) { + if ( note_title == "search results" || note_title == "share this notebook" ) { link.href = "/notebooks/" + this.notebook_id + "?" + queryString( [ "title", "note_id" ], [ note_title, "null" ] ); if ( callback ) { - if ( note_title == "all notes" ) - callback( "list of all notes in this notebook" ); if ( note_title == "search results" ) callback( "current search results" ); else @@ -751,7 +733,7 @@ Wiki.prototype.editor_title_changed = function ( editor, old_title, new_title ) if ( new_title != null && !editor.empty() ) { this.open_editors[ new_title ] = editor; - this.add_all_notes_link( editor.id, new_title ); + signal( this, "note_renamed", editor, new_title ); } } @@ -804,7 +786,7 @@ Wiki.prototype.editor_focused = function ( editor, synchronous ) { // 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.id == this.blank_editor_id && this.focused_editor.empty() ) { - this.remove_all_notes_link( this.focused_editor.id ); + signal( this, "note_removed", this.focused_editor.id ); this.focused_editor.shutdown(); this.decrement_total_notes_count(); this.display_empty_message(); @@ -1081,7 +1063,7 @@ Wiki.prototype.hide_editor = function ( event, editor ) { // if the editor to hide is completely empty, then simply remove it if ( editor.id == this.blank_editor_id && editor.empty() ) { - this.remove_all_notes_link( editor.id ); + signal( this, "note_removed", editor.id ); editor.shutdown(); this.decrement_total_notes_count(); } else { @@ -1090,10 +1072,9 @@ Wiki.prototype.hide_editor = function ( event, editor ) { this.save_editor( editor ); editor.shutdown(); - Highlight( "all_notes_link" ); } - this.display_empty_message( id == "all_notes" ); + this.display_empty_message(); } event.stop(); @@ -1142,7 +1123,7 @@ Wiki.prototype.delete_editor = function ( event, editor ) { connect( undo_button, "onclick", function ( event ) { self.undelete_editor_via_undo( event, editor, message_div ); } ); } - self.remove_all_notes_link( editor.id ); + signal( self, "note_removed", editor.id ); editor.shutdown(); self.decrement_total_notes_count(); @@ -1176,7 +1157,7 @@ Wiki.prototype.undelete_editor_via_trash = function ( event, editor ) { if ( editor == this.focused_editor ) this.focused_editor = null; - this.remove_all_notes_link( editor.id ); + signal( this, "note_removed", editor.id ); editor.shutdown(); this.decrement_total_notes_count(); @@ -1199,6 +1180,7 @@ Wiki.prototype.undelete_editor_via_undo = function( event, editor, position_afte this.startup_notes[ editor.id ] = true; this.increment_total_notes_count(); this.load_editor( "Note not found.", editor.id, null, null, position_after ); + signal( this, "note_added", editor ); } event.stop(); @@ -1216,6 +1198,7 @@ Wiki.prototype.undelete_editor_via_undelete = function( event, note_id, position this.startup_notes[ note_id ] = true; this.increment_total_notes_count(); this.load_editor( "Note not found.", note_id, null, null, position_after ); + signal( this, "note_removed", editor.id ); event.stop(); } @@ -1371,40 +1354,6 @@ Wiki.prototype.display_search_results = function ( result ) { this.search_results_editor = this.create_editor( "search_results", "

search results

" + list.innerHTML, undefined, undefined, undefined, false, true, true, getElement( "notes_top" ) ); } -Wiki.prototype.display_all_notes_list = function ( result ) { - this.clear_messages(); - this.clear_pulldowns(); - - if ( this.display_empty_message( true ) == true ) - return; - - if ( this.all_notes_editor ) - this.all_notes_editor.shutdown(); - - // build up a list of all notes in this notebook, one link per note - var list = createDOM( "ul", { "id": "notes_list" } ); - if ( this.focused_editor ) { - var focused_title = this.focused_editor.title; - if ( focused_title != "all notes" && focused_title != "search results" && focused_title != "share this notebook" ) - appendChildNodes( list, this.create_all_notes_link( this.focused_editor.id, this.focused_editor.title || "untitled note" ) ); - } - - for ( var i in result.notes ) { - var note_tuple = result.notes[ i ] - var note_id = note_tuple[ 0 ]; - var note_title = note_tuple[ 1 ]; - if ( this.focused_editor && note_id == this.focused_editor.id ) - continue; - if ( !note_title ) - note_title = "untitled note"; - - appendChildNodes( list, this.create_all_notes_link( note_id, note_title ) ); - } - var list_holder = createDOM( "div", {}, list ); - - this.all_notes_editor = this.create_editor( "all_notes", "

all notes

" + list_holder.innerHTML, undefined, undefined, undefined, false, true, true, getElement( "notes_top" ) ); -} - Wiki.prototype.share_notebook = function () { this.clear_pulldowns(); @@ -1792,11 +1741,7 @@ Wiki.prototype.display_empty_message = function ( replace_messages ) { } if ( !replace_messages ) { - var self = this; - this.invoker.invoke( - "/notebooks/all_notes", "GET", { "notebook_id": this.notebook.object_id }, - function( result ) { self.display_all_notes_list( result ); } - ); + // TODO: display a message about the note tree, or some way for the user to get back to their notes return true; } @@ -1837,55 +1782,6 @@ Wiki.prototype.zero_total_notes_count = function () { replaceChildNodes( "total_notes_count", this.total_notes_count ); } -Wiki.prototype.remove_all_notes_link = function ( note_id ) { - if ( !this.all_notes_editor ) return; - - withDocument( this.all_notes_editor.document, function () { - var note_link = getElement( "note_link_" + note_id ); - if ( note_link ) - removeElement( note_link ); - } ); - - this.all_notes_editor.resize(); -} - -Wiki.prototype.add_all_notes_link = function ( note_id, note_title ) { - if ( !this.all_notes_editor ) return; - if ( note_title == "all notes" || note_title == "search results" || note_title == "share this notebook" ) return; - - if ( !note_title || note_title.length == 0 ) - note_title = "untitled note"; - - var self = this; - withDocument( this.all_notes_editor.document, function () { - // if the note link already exists, update its title and bail - var note_link = getElement( "note_link_" + note_id ); - if ( note_link ) { - replaceChildNodes( note_link.firstChild, note_title ); - self.all_notes_editor.resize(); - return; - } - - var notes_list = getElement( "notes_list" ); - if ( !notes_list ) return; - var first_note_link = notes_list.firstChild; - var new_note_link = self.create_all_notes_link( note_id, note_title ); - - if ( first_note_link ) - insertSiblingNodesBefore( first_note_link, new_note_link ); - else - appendChildNodes( notes_list, new_note_link ); - } ); - - this.all_notes_editor.resize(); -} - -Wiki.prototype.create_all_notes_link = function ( note_id, note_title ) { - return createDOM( "li", { "id": "note_link_" + note_id }, - createDOM( "a", { "href": "/notebooks/" + this.notebook_id + "?note_id=" + note_id }, note_title ) - ); -} - Wiki.prototype.start_notebook_rename = function () { this.clear_pulldowns(); @@ -2257,12 +2153,6 @@ function Link_pulldown( wiki, notebook_id, invoker, editor, link ) { // if the note has no destination note id set, try loading the note from the server by title if ( ( id == undefined || id == "new" || id == "null" ) && title.length > 0 ) { - if ( title == "all notes" ) { - this.title_field.value = title; - this.display_summary( title, "list of all notes in this notebook" ); - return; - } - if ( title == "search results" ) { this.title_field.value = title; this.display_summary( title, "current search results" ); @@ -2663,3 +2553,76 @@ File_link_pulldown.prototype.shutdown = function () { this.link.pulldown = null; } +function Note_tree( wiki, notebook_id, invoker ) { + this.wiki = wiki; + this.notebook_id = notebook_id; + this.invoker = invoker; + + // add onclick handlers to the initial note links within the tree + var links = getElementsByTagAndClassName( "a", "note_tree_link", "note_tree_area" ); + + var self = this; + for ( var i in links ) { + var link = links[ i ]; + // TODO: connect expander as well + 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 ); } ); + connect( wiki, "note_added", function ( editor ) { self.add_link( editor ); } ); + connect( wiki, "note_removed", function ( id ) { self.remove_link( id ); } ); + connect( wiki, "note_updated", function ( editor ) { self.update_child_links( editor ); } ); +} + +Note_tree.prototype.link_clicked = function ( event ) { + var link = event.target(); + var query = parse_query( link ); + var note_id = query[ "note_id" ]; + + if ( !note_id ) + return; + + this.wiki.load_editor( null, note_id ); + event.stop(); +} + +Note_tree.prototype.add_link = function ( editor ) { + // for now, only add startup notes to the note tree + if ( !editor.startup ) + return; + + var expander = createDOM( "div", { "class": "tree_expander" } ); + var link = createDOM( "a", { + "href": "/notebooks/" + this.notebook_id + "?note_id=" + editor.id, + "id": "note_tree_link_" + editor.id, + "class": "note_tree_link" + }, editor.title ); + + appendChildNodes( "note_tree_area_holder", createDOM( + "div", + { "id": "note_tree_item_" + editor.id, "class": "link_area_item" }, + expander, + link + ) ); + + var self = this; + // TODO: connect expander as well + connect( link, "onclick", function ( event ) { self.link_clicked( event ); } ); +} + +Note_tree.prototype.remove_link = function ( id ) { + removeElement( "note_tree_item_" + id ); +} + +Note_tree.prototype.rename_link = function ( editor, new_title ) { +} + +Note_tree.prototype.expand_link = function ( id ) { +} + +Note_tree.prototype.collapse_link = function ( id ) { +} + +Note_tree.prototype.update_child_links = function ( editor ) { +} diff --git a/view/Link_area.py b/view/Link_area.py index 92c5b81..56f4180 100644 --- a/view/Link_area.py +++ b/view/Link_area.py @@ -4,7 +4,7 @@ from Search_form import Search_form class Link_area( Div ): - def __init__( self, notebooks, notebook, total_notes_count, parent_id, notebook_path, user ): + def __init__( self, notebooks, notebook, parent_id, notebook_path, user ): linked_notebooks = [ nb for nb in notebooks if ( nb.read_write or not nb.name.startswith( u"Luminotes" ) ) and nb.name not in ( u"trash" ) and @@ -20,19 +20,6 @@ class Link_area( Div ): Search_form(), class_ = u"link_area_item", ), - ( parent_id is None ) and Div( - A( - u"all notes", - href = u"#", - id = u"all_notes_link", - title = u"View a list of all notes in this notebook.", - ), - Span( - Span( total_notes_count, id = u"total_notes_count" ), u"total", - class_ = u"small_text", - ), - class_ = u"link_area_item", - ) or None, ( notebook.name != u"Luminotes" ) and Div( A( @@ -156,7 +143,7 @@ class Link_area( Div ): Div( id = u"storage_usage_area", ), - id = u"link_area_wrapper", + id = u"link_area_holder", ), id = u"link_area", ) diff --git a/view/Main_page.py b/view/Main_page.py index e2f3d5c..53d9e3c 100644 --- a/view/Main_page.py +++ b/view/Main_page.py @@ -2,6 +2,7 @@ from cgi import escape from Page import Page from Header import Header from Tags import Link, Input, Div, Span, H2, H4, A, Br, Strong, Script, Img +from Note_tree_area import Note_tree_area from Link_area import Link_area from Toolbar import Toolbar from Json import Json @@ -134,11 +135,17 @@ class Main_page( Page ): Header( user, header_notebook, login_url, logout_url, header_note_title ), Div( Div( - Br(), - Toolbar( hide_toolbar = parent_id or not notebook.read_write ), - id = u"toolbar_area", + Note_tree_area( + Toolbar( + hide_toolbar = parent_id or not notebook.read_write + ), + notebook, + startup_notes, # TODO: pass root_notes, not startup_notes + total_notes_count, + ), + id = u"left_area", ), - Link_area( notebooks, notebook, total_notes_count, parent_id, notebook_path, user ), + Link_area( notebooks, notebook, parent_id, notebook_path, user ), Div( Rounded_div( ( notebook.name == u"trash" ) and u"trash_notebook" or u"current_notebook", diff --git a/view/Note_tree_area.py b/view/Note_tree_area.py new file mode 100644 index 0000000..c8e5c1f --- /dev/null +++ b/view/Note_tree_area.py @@ -0,0 +1,31 @@ +from Tags import Div, Span, H4, A + + +class Note_tree_area( Div ): + def __init__( self, toolbar, notebook, root_notes, total_notes_count ): + Div.__init__( + self, + toolbar, + Div( + H4( u"notes", + Span( + Span( total_notes_count, id = u"total_notes_count" ), u"total", + class_ = u"small_text link_area_item", + ), + id = u"note_tree_area_title", + ), + [ Div( + Div( class_ = u"tree_expander" ), + A( + note.title, + href = u"/notebooks/%s?note_id=%s" % ( notebook.object_id, note.object_id ), + id = u"note_tree_link_" + note.object_id, + class_ = u"note_tree_link", + ), + id = u"note_tree_item_" + note.object_id, + class_ = u"link_area_item", + ) for note in root_notes ], + id = u"note_tree_area_holder", + ), + id = u"note_tree_area", + )