Index: openacs-4/packages/xowiki/tcl/includelet-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/includelet-procs.tcl,v
diff -u -N -r1.239.2.10 -r1.239.2.11
--- openacs-4/packages/xowiki/tcl/includelet-procs.tcl 10 May 2019 22:53:10 -0000 1.239.2.10
+++ openacs-4/packages/xowiki/tcl/includelet-procs.tcl 12 May 2019 20:02:46 -0000 1.239.2.11
@@ -1411,7 +1411,6 @@
my-tags instproc render {} {
:get_parameters
- ::xo::Page requireJS urn:ad:js:get-http-object
set p_link [${:__including_page} pretty_link]
set return_url [::xo::cc url]?[::xo::cc actual_query]
@@ -1867,7 +1866,10 @@
# includelets based on order
#
Class create PageReorderSupport
- PageReorderSupport instproc page_reorder_check_allow {{-with_head_entries true} allow_reorder} {
+ PageReorderSupport instproc page_reorder_check_allow {
+ {-with_head_entries true}
+ allow_reorder
+ } {
if {$allow_reorder ne ""} {
set granted [::${:package_id} check_permissions \
-user_id [[::${:package_id} context] user_id] \
@@ -1876,10 +1878,11 @@
#:msg "granted=$granted"
if {$granted} {
if {$with_head_entries} {
- set ajaxhelper 1
- ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "utilities/utilities.js"
- ::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "selector/selector-min.js"
- ::xo::Page requireJS "/resources/xowiki/yui-page-order-region.js"
+ #set ajaxhelper 1
+ #::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "utilities/utilities.js"
+ #::xowiki::Includelet require_YUI_JS -ajaxhelper $ajaxhelper "selector/selector-min.js"
+ #::xo::Page requireJS "/resources/xowiki/yui-page-order-region.js"
+ ::xo::Page requireJS "/resources/xowiki/listdnd.js"
}
} else {
# the user has not enough permissions, so disallow
@@ -1891,7 +1894,7 @@
PageReorderSupport instproc page_reorder_init_vars {-allow_reorder js_ last_level_ ID_ min_level_} {
:upvar $js_ js $last_level_ last_level $ID_ ID $min_level_ min_level
- set js "YAHOO.xo_page_order_region.DDApp.package_url = '[::${:package_id} package_url]';\n"
+ #set js "YAHOO.xo_page_order_region.DDApp.package_url = '[::${:package_id} package_url]';\n"
set last_level 0
set ID [:js_name]
if {[string is integer -strict $allow_reorder]} {
@@ -1911,13 +1914,17 @@
set key :__count($prefix_js)
set p [incr $key]
set id ${ID}_${prefix_js}_$p
- append js "YAHOO.xo_page_order_region.DDApp.cd\['$id'\] = '$page_order';\n"
+ #append js "YAHOO.xo_page_order_region.DDApp.cd\['$id'\] = '$page_order';\n"
return $id
}
#
# toc -- Table of contents
#
+ # The "toc" includelet renders the page titles of the current files
+ # based on the value of the "page_order" attributes. Only those
+ # pages are rendered that have a non-empty "page_order" field.
+ #
::xowiki::IncludeletClass create toc \
-superclass ::xowiki::Includelet \
-instmixin PageReorderSupport \
@@ -2260,22 +2267,32 @@
toc instproc render_tree {{-full false} pages} {
:get_parameters
- set tree [::xowiki::Tree new -destroy_on_cleanup -orderby pos -id [:id] -verbose 1]
+ set tree [::xowiki::Tree new -destroy_on_cleanup \
+ -orderby pos \
+ -id [:id] \
+ -verbose 0 \
+ -owner [self]]
$tree array set open_node [array get :open_node]
$tree add_pages -full $full -remove_levels $remove_levels \
-book_mode $book_mode -open_page $open_page \
-owner [self] \
$pages
- set HTML [$tree render -style ${:renderer}]
+ if {$allow_reorder ne ""} {
+ set allow_reorder [:page_reorder_check_allow -with_head_entries false $allow_reorder]
+ }
+
+ if {$allow_reorder ne ""} {
+ :page_reorder_init_vars -allow_reorder $allow_reorder js last_level ID min_level
+ #:log "=== call tree render [list $tree render -style listdnd] min_level=$min_level"
+ set HTML [$tree render -style listdnd -context [list min_level $min_level]]
+ } else {
+ set HTML [$tree render -style list]
+ }
#:log "render_tree HTML => $HTML"
return $HTML
}
- toc instproc parent_id {} {
- ${:__including_page} parent_id
- }
-
toc instproc render_list {{-full false} pages} {
:get_parameters
@@ -2292,15 +2309,16 @@
}
set tree [::xowiki::Tree new -destroy_on_cleanup -orderby pos -id [:id]]
$tree array set open_node [array get :open_node]
- $tree add_pages -full $full -remove_levels $remove_levels \
+ $tree add_pages -full $full \
+ -remove_levels $remove_levels \
-book_mode $book_mode -open_page $open_page -expand_all $expand_all \
-owner [self] \
$pages
if {$allow_reorder ne ""} {
:page_reorder_init_vars -allow_reorder $allow_reorder js last_level ID min_level
- set js "\nYAHOO.xo_page_order_region.DDApp.package_url = '[::$package_id package_url]';"
- set HTML [$tree render -style listdnd -js $js -context [list min_level $min_level]]
+ #set js "\nYAHOO.xo_page_order_region.DDApp.package_url = '[::$package_id package_url]';"
+ set HTML [$tree render -style listdnd -context [list min_level $min_level]]
} else {
set HTML [$tree render -style list]
}
@@ -2389,7 +2407,7 @@
# of the toc-specific renderers, but first we have to check, if
# these are fully feature-compatible.
#
-
+ #:log "=== toc render with <${:renderer}> treerenderer ${:use_tree_renderer} list_mode <${:list_mode}>"
if {${:renderer} eq "none"} {
} elseif {${:use_tree_renderer}} {
return [:render_tree -full 1 $pages]
Index: openacs-4/packages/xowiki/tcl/tree-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/tcl/tree-procs.tcl,v
diff -u -N -r1.23 -r1.23.2.1
--- openacs-4/packages/xowiki/tcl/tree-procs.tcl 11 Jul 2018 13:46:15 -0000 1.23
+++ openacs-4/packages/xowiki/tcl/tree-procs.tcl 12 May 2019 20:02:46 -0000 1.23.2.1
@@ -17,6 +17,7 @@
-superclass ::xo::OrderedComposite \
-parameter {
{name ""}
+ {owner}
{verbose 0}
id
}
@@ -172,7 +173,9 @@
append content [:render_node -open true $cat_content]
}
- if {${:verbose}} {:log "TreeNode items [:isobject [self]::items] render open_requests ${:open_requests} -> $content"}
+ if {${:verbose}} {
+ :log "TreeNode items [:isobject [self]::items] render open_requests ${:open_requests} -> $content"
+ }
return $content
}
@@ -259,8 +262,10 @@
set h_atts [lindex [$cl highlight_atts] [expr {${:highlight} ? 0 : 1}]]
set u_atts ""
- if {[info exists :li_id]} {append o_atts " id='${:li_id}'"}
- if {[info exists :ul_id]} {append u_atts " id='${:ul_id}'"}
+ if {[info exists :li_id]} {append o_atts " id='${:li_id}'"}
+ if {[info exists :li_atts]} {append o_atts " ${:li_atts}"}
+ if {[info exists :ul_id]} {append u_atts " id='${:ul_id}'"}
+ if {[info exists :ul_atts]} {append u_atts " ${:ul_atts}"}
if {[info exists :ul_class]} {append u_atts " class='${:ul_class}'"}
set label [::xowiki::Includelet html_encode [:label]]
@@ -281,7 +286,7 @@
} else {
set content ""
}
- return "
${:prefix} $entry$content"
+ return "${:prefix} $entry$content"
}
#--------------------------------------------------------------------------------
@@ -419,42 +424,87 @@
#--------------------------------------------------------------------------------
- # list-specific render with YUI drag and drop functionality
+ # list-specific render with drag and drop functionality
#--------------------------------------------------------------------------------
TreeRenderer create TreeRenderer=listdnd \
-superclass TreeRenderer=list \
-li_expanded_atts [list "" ""]
TreeRenderer=listdnd proc include_head_entries {args} {
- set ajaxhelper 0
- ::xo::Page requireJS urn:ad:js:yui2:utilities/utilities
- ::xo::Page requireJS urn:ad:js:yui2:selector/selector-min
- ::xo::Page requireJS "/resources/xowiki/yui-page-order-region.js"
+ ::xo::Page requireJS "/resources/xowiki/listdnd.js"
}
+ TreeRenderer=listdnd proc min_level {} {
+ if {[dict exists ${:context} min_level]} {
+ return [dict get ${:context} min_level]
+ }
+ return ""
+ }
+ TreeRenderer=listdnd proc add_handler {-id -event} {
+ template::add_event_listener \
+ -id $id \
+ -event $event \
+ -preventdefault=false \
+ -script "listdnd_${event}_handler(event);"
+ }
+
TreeRenderer=listdnd proc render {tree} {
- array set "" ${:context}
- if {[info exists (min_level)] && $(min_level) == 1} {
- set css_class "page_order_region"
+ #:log "=== TreeRenderer=listdnd render $tree"
+ #
+ # Do we allow reorder on the toplevel?
+ #
+ if {[:min_level] == 1} {
+ set css_class "page_order_region"
+ set id [$tree id]-topul
+ foreach event {drop dragover dragleave} {
+ :add:handler -id $id -event $event
+ }
} else {
set css_class "page_order_region_no_target"
}
- return ""
+ :log "=== TreeRenderer=listdnd render $tree min_level <[:min_level]>"
+ if {[$tree exists owner]} {
+ #
+ # assume, the "owner" is an includelet.
+ set owner [$tree set owner]
+ set page [$owner set __including_page]
+ set package_url [::[$page package_id] package_url]
+ set package_url_data " data-package_url='$package_url' data-folder_id='[$page parent_id]'"
+ } else {
+ set package_url_data ""
+ }
+
+ return [subst {
+ }]
}
TreeRenderer=listdnd instproc render_node {{-open:boolean false} cat_content} {
+ #:log "=== TreeRenderer=listdnd render_node $cat_content"
#set open_state [expr {${:open_requests} > 0 ?"class='liOpen'" : "class='liClosed'"}]
- #set cl [lindex [:info precedence] 0]
- set obj ${:object}
- set o [:owner]
- $obj instvar page_order
- set :li_id [::xowiki::Includelet js_name [$o set id]_$page_order]
- set :ul_id [::xowiki::Includelet js_name [$o set id]__l${:level}_$page_order]
+ ${:object} instvar page_order
- set cl [self class]
- $cl append js "\nYAHOO.xo_page_order_region.DDApp.cd\['${:li_id}'\] = '$page_order';"
+ set :li_id [::xowiki::Includelet js_name [${:owner} set id]_$page_order]
+ set :ul_id [::xowiki::Includelet js_name [${:owner} set id]__l${:level}_$page_order]
+
+ set min_level [[self class] min_level]
+ set reorder_child [expr {$min_level ne "" && ${:level} >= $min_level}]
+ set reorder_self [expr {$min_level ne "" && ${:level} > $min_level}]
+ :log "=== render_node $page_order min_level $min_level level ${:level} reorder_child $reorder_child reorder_self $reorder_self"
- array set "" [$cl set context]
- set :ul_class [expr {[info exists (min_level)] && ${:level} >= $(min_level) ?
- "page_order_region" : "page_order_region_no_target"}]
+ if {$reorder_child} {
+ foreach event {drop dragover dragleave} {
+ [self class] add_handler -id ${:ul_id} -event $event
+ }
+ set :ul_class "page_order_region"
+ } else {
+ set :ul_class "page_order_region_no_target"
+ }
+ if {$reorder_self} {
+ set :li_atts [subst {data-value='$page_order' draggable='true'}]
+ [self class] add_handler -id ${:li_id} -event dragstart
+ }
+ set :ul_id [::xowiki::Includelet js_name [${:owner} set id]__l${:level}_$page_order]
+
return [next]
}
Index: openacs-4/packages/xowiki/www/resources/listdnd.js
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/Attic/listdnd.js,v
diff -u -N
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ openacs-4/packages/xowiki/www/resources/listdnd.js 12 May 2019 20:02:46 -0000 1.1.2.1
@@ -0,0 +1,157 @@
+/*
+ * Drag and drop for reordering table of contents (toc) items based on
+ * the tree renderer "listdnd" using HTML5. This code is intended to
+ * behave similar as the previous solution based on YUI2.
+ *
+ * The CSS part of this handler is placed in xowiki.css, using the
+ * classes "page_order_region", "page_order_region_no_target",
+ * "mark-above", "mark-below".
+ *
+ * In essence, the implementation uses darag and drop of list items
+ * between potentially different lists and issues AJAX requests to the
+ * backend to reflect these changes in the database. Since the order
+ * of the items in a "toc" is determiend by the "page_order" attribute
+ * in the database, it reports the changed lists of page_orders back.
+ *
+ * The implementation uses the following data attributes:
+ * - data-value (containing page_order)
+ * - data-folder_id data-package_url (for reporting to the backend)
+ *
+ * Gustaf Neumann fecit May 2019
+ */
+
+function listdnd_get_parent( target, nodeName ) {
+ while ( target.nodeName != nodeName && target.nodeName != 'BODY' ) {
+ target = target.parentNode;
+ }
+ if ( target.nodeName == 'BODY' ) {
+ return false;
+ } else {
+ return target;
+ }
+}
+
+function listdnd_page_orders( element ) {
+ //
+ // Collect the page_orders of the LI items below the given element
+ // and return it in form of an array.
+ //
+ var items = element.getElementsByTagName('LI');
+ var result = [];
+
+ for (var j = 0; j < items.length; j++) {
+ var page_order = items[j].dataset.value;
+ if (page_order != '') {
+ result.push(page_order);
+ }
+ }
+ return result;
+}
+
+function listdnd_dragstart_handler(ev) {
+ // Add the target element's id to the data transfer object
+ var target = listdnd_get_parent( ev.target, 'LI' );
+ ev.dataTransfer.setData("text/plain", target.id);
+ ev.dataTransfer.dropEffect = "move";
+ //console.log("listdnd_dragstart_handler on " + target.id);
+}
+
+function listdnd_dragover_handler(ev) {
+ ev.preventDefault();
+ ev.dataTransfer.dropEffect = "move"
+ var target = listdnd_get_parent( ev.target, 'LI' );
+ var value = target.dataset.value;
+ if (typeof value !== 'undefined') {
+ var bounding = target.getBoundingClientRect()
+ var offset = bounding.y + (bounding.height/2);
+ if ( event.clientY - offset > 0 ) {
+ target.classList.add('mark-below')
+ target.classList.remove('mark-above')
+ } else {
+ target.classList.add('mark-above')
+ target.classList.remove('mark-below')
+ }
+ }
+}
+
+function listdnd_dragleave_handler(ev) {
+ ev.preventDefault();
+ // Set the dropEffect to move
+ ev.dataTransfer.dropEffect = "move"
+ var target = listdnd_get_parent( ev.target, 'LI' );
+ target.classList.remove('mark-above', 'mark-below');
+}
+
+
+function listdnd_drop_handler(ev) {
+ ev.preventDefault();
+ //console.log("drop_handler on " + ev.target.nodeName);
+
+ // Get the dropped element based on the transferred ID.
+ var sourceElement = document.getElementById(ev.dataTransfer.getData("text/plain"))
+
+ // We want to allow only drops on elements having a "data-value"
+ // attribute set (because of desisred reorderings of the page_order)
+ var target = listdnd_get_parent( ev.target, 'LI');
+
+ var value = target.dataset.value;
+ if (typeof value !== 'undefined') {
+
+ // Used variables:
+ // - dropul: The target ul, which should be updated with
+ // the dropped item.
+ // - div: The outer did, needed for obtaining "folder_id"
+ // and "package_url".
+ // - before: collection of "page_orders" before drop.
+ // - after: collection of "page_orders" after drop.
+ //
+ var dropul = target.parentNode;
+ var div = listdnd_get_parent( target.parentNode, 'DIV');
+ var before = listdnd_page_orders(dropul);
+
+ if ( target.classList.contains('mark-above') ) {
+ target.classList.remove('mark-above')
+ target.parentNode.insertBefore(sourceElement, target);
+ } else {
+ target.classList.remove('mark-below')
+ target.parentNode.insertBefore(sourceElement, target.nextSibling);
+ }
+
+ var after = listdnd_page_orders(dropul);
+ var diff = after.filter(x => !before.includes(x) );
+
+ //console.log('drop before <' + before + '> after <' + after + '> diff <' + diff + '>');
+
+ var data = 'change-page-order=1' +
+ '&from=' + escape(before.join(' ')) +
+ '&to=' + escape(after.join(' ')) +
+ '&clean=' + escape(diff.join(' ')) +
+ '&folder_id=' + escape(div.dataset.folder_id) +
+ '';
+
+ //console.log('package_url <' + div.dataset.package_url + '>');
+ if (1) {
+ var request = new XMLHttpRequest();
+ request.onload = function(e) {
+ // There seems no good way to handle redirects (301 or
+ // 302) in XHR. Since we know valid results (just the
+ // "OK"), everything else must have been a
+ // redirect. We could be brutal and display the
+ // returned page, but not sure, if this would be
+ // desirable either.
+ if (this.getResponseHeader["Content-Length"] > 10) {
+ // there must have happened a redirect
+ alert("Refresh your login and redo update");
+ window.location.href = div.dataset.package_url
+ + "?refresh-login&return_url="
+ + escape(window.location.href);
+ } else {
+ window.location.reload();
+ }
+ };
+ request.open('POST', div.dataset.package_url, true);
+ request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
+ request.send(data);
+ }
+ }
+}
Index: openacs-4/packages/xowiki/www/resources/xowiki.css
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xowiki/www/resources/xowiki.css,v
diff -u -N -r1.64.2.1 -r1.64.2.2
--- openacs-4/packages/xowiki/www/resources/xowiki.css 10 May 2019 22:53:10 -0000 1.64.2.1
+++ openacs-4/packages/xowiki/www/resources/xowiki.css 12 May 2019 20:02:46 -0000 1.64.2.2
@@ -55,86 +55,6 @@
padding-right: 14px;
}
-/* appearance of item-buttons */
-/*
-div.xowiki-content a.edit-item-button {
- background: url(/resources/acs-subsite/Edit16.gif) right center no-repeat;
- padding-right: 16px;
-}
-div.xowiki-content a.delete-item-button {
- background: url(/resources/acs-subsite/Delete16.gif) right center no-repeat;
- padding-right: 16px;
-}
-div.xowiki-content a.view-item-button {
- background: url(/resources/acs-subsite/Zoom16.gif) right center no-repeat;
- padding-right: 16px;
-}
-div.xowiki-content a.create-item-button {
- background: url( /resources/acs-subsite/Add16.gif) right center no-repeat;
- padding-right: 16px;
-}
-div.xowiki-content a.copy-item-button {
- background: url(/resources/acs-subsite/Copy16.gif) right center no-repeat;
- padding-right: 16px;
-}
-div.xowiki-content a.copy-item-button {
- background: url(/resources/acs-subsite/Copy16.gif) right center no-repeat;
- padding-right: 16px;
-}
-*/
-/* positions
- Add16 -2,-1
- Copy16 -2,-22
- Delete16 -2,-44
- Edit16 -2,-66
- New16 -2,-88
- Open16 -2,-110
- Preferences16 -2,-132
- Properties16 -2,-154
- Zoom16 -2,-176
- ZoomIn16 -2,-198
- ZoomOut16 -2,-220
- email.png -2,-242
- external.png -2,-264
- file.png -2,-286
- transparent.png -1,-308
-*/
-div.xowiki-content a.edit-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -66px no-repeat;
- padding-right: 16px;
- text-decoration: none;
-}
-div.xowiki-content a.delete-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -44px no-repeat;
- padding-right: 16px;
- text-decoration: none;
-}
-div.xowiki-content a.view-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -176px no-repeat;
- padding-right: 16px;
- text-decoration: none;
-}
-div.xowiki-content a.create-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -1px no-repeat;
- padding-right: 16px;
- text-decoration: none;
-}
-div.xowiki-content a.copy-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -22px no-repeat;
- padding-right: 16px;
- text-decoration: none;
- width: 16px; height: 16px;
-}
-div.xowiki-content a.add-item-button {
- background: transparent url(/resources/xowiki/sprite16.png) -2px -1px no-repeat;
- padding-right: 16px;
- text-decoration: none;
-}
-div.xowiki-content a.notification-image-button {
- background: transparent url(/resources/xowiki/sprite16.png) -4px -248px no-repeat; /* 6px more */
- padding-right: 16px;
- text-decoration: none;
-}
/* headings */
div.xowiki-content h1 {
@@ -416,9 +336,16 @@
list targetable. Alternatively, we could leave the padding
off by default, adding it when we detect that the list is empty.
*/
- padding-bottom:3ex;
+ padding-bottom:1ex;
}
+div.xowiki-content ul.page_order_region li.mark-above {
+ border-top: solid 4px #428bca;
+}
+div.xowiki-content ul.page_order_region li.mark-below {
+ border-bottom: solid 4px #428bca;
+}
+
/*
Handling hidden field-sets: