namespace eval ::xowiki {}
::nsf::object::alloc ::xo::tdom::Class ::xowiki::BootstrapNavbarDropzone {set :__default_metaclass ::xotcl::Class
set :__default_superclass ::xotcl::Object}
::xowiki::BootstrapNavbarDropzone instproc render {} {
if {${:href} ni {"" "#"}} {
html::li {
html::form -method "post" -enctype "multipart/form-data" -style "display: none;" -id "js-upload-form" {
html::div -class "form-inline" {
html::div -class "form-group" {
html::input -type "file" -name {files[]} -id "js-upload-files" -data-file_name_prefix ${:file_name_prefix} -data-url ${:href} -data-disposition ${:disposition} -multiple multiple
}
html::button -type "submit" -class "btn btn-sm btn-primary" -id "js-upload-submit" {
html::t ${:text}
}
::html::CSRFToken
}
}
html::div -class "upload-drop-zone" -id "drop-zone" {
html::span {html::t ${:label}}
html::div -class "progress" {
html::div -style "width: 0%;" -class "progress-bar" -id dropzone-progress-bar {
html::span -class "sr-only" {html::t ""}
}
}
}
}
:js
}
}
::xowiki::BootstrapNavbarDropzone instproc js {} {
html::script -type "text/javascript" -nonce [security::csp::nonce] {
html::t {
+ function($) {
'use strict';
var dropZone = document.getElementById('drop-zone');
var uploadForm = document.getElementById('js-upload-form');
var progressBar = document.getElementById('dropzone-progress-bar');
var dropZoneResponse = document.getElementById('thumbnail-files-wrapper');
var uploadFileRunning = 0;
var uploadFilesStatus = [];
var uploadFilesResponse = [];
var startUpload = function(files, disposition, url, prefix, csrf) {
//console.log("files " + files + " dispo '"+ disposition + "' url " + url + " prefix " + prefix);
if (typeof files !== "undefined") {
for (var i=0, l=files.length; i<l; i++) {
// Send the file as multiple single requests and
// not as a single post containing all entries. This
// gives users with older NaviServers or AOLserver the chance
// drop multiple files.
uploadFile(files[i], disposition, url, prefix, csrf);
}
} else {
alert("No support for the File API in this web browser");
}
}
var uploadFile = function(file, disposition, url, prefix, csrf) {
var xhr;
var formData = new FormData();
var fullName = (prefix == "" ? file.name : prefix + '/' + file.name);
var fullUrl = url
+ "&disposition=" + encodeURIComponent(disposition)
+ "&name=" + encodeURIComponent(fullName);
xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
// For multiple drop files, we should probably we
// should sum up the sizes. However, since the
// uploads are in parallel, this is already useful.
progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";
} else {
// No data to calculate on
}
}, false);
xhr.addEventListener("load", function (event) {
uploadFileRunning--;
uploadFilesStatus.push(event.currentTarget.status);
uploadFilesResponse.push(event.currentTarget.response);
//console.log("ended with status " + event.currentTarget.status);
//console.log("running: " + uploadFileRunning);
if (dropZoneResponse) {
// We have a dropzone response and update this in the
// web page.
dropZoneResponse.innerHTML = uploadFilesResponse[uploadFilesResponse.length-1];
dropZoneResponse.querySelectorAll('.thumbnail-file').forEach(el => thumbnail_files_setup(el));
}
if (uploadFileRunning < 1) {
if (dropZoneResponse) {
// We are done with all uploads. When the response is
// provided, it was updated above already in the web
// page, but we have still to reset the progress bar
// to indicate that we are done.
progressBar.style.width = '0%';
} else {
// Reload the page to trigger a refresh
location.reload(true);
}
}
}, false);
xhr.open("post", fullUrl, true);
formData.append("upload", file);
formData.append("__csrf_token", csrf);
uploadFileRunning++;
xhr.send(formData);
}
uploadForm.addEventListener('submit', function(e) {
//
// Input handler for classical form submit
//
var input = document.getElementById('js-upload-files');
var uploadFiles = input.files;
var csrf = input.form.elements["__csrf_token"].value;
e.preventDefault();
//console.log("Submit handler");
startUpload(input.files,
input.dataset.disposition ?? 'File',
input.dataset.url,
input.dataset.file_name_prefix ?? '',
csrf);
})
dropZone.ondrop = function(e) {
//
// Input handler for drag & drop
//
e.preventDefault();
this.className = 'upload-drop-zone';
var form = document.getElementById('js-upload-files').form;
var csrf = form.elements["__csrf_token"].value;
var input = document.getElementById('js-upload-files');
//console.log("Drop handler");
startUpload(e.dataTransfer.files,
input.dataset.disposition ?? 'File',
input.dataset.url,
input.dataset.file_name_prefix ?? '',
csrf);
}
dropZone.ondragover = function() {
this.className = 'upload-drop-zone drop';
return false;
}
dropZone.ondragleave = function() {
this.className = 'upload-drop-zone';
return false;
}
} (jQuery);
}
}
}
::xowiki::BootstrapNavbarDropzone instparametercmd label
::xowiki::BootstrapNavbarDropzone instparametercmd text
::xowiki::BootstrapNavbarDropzone instparametercmd file_name_prefix
::xowiki::BootstrapNavbarDropzone instparametercmd disposition
::xowiki::BootstrapNavbarDropzone instparametercmd href
::nsf::relation::set ::xowiki::BootstrapNavbarDropzone superclass ::xowiki::MenuComponent
::nx::slotObj -container slot ::xowiki::BootstrapNavbarDropzone
::xowiki::BootstrapNavbarDropzone::slot eval {set :__parameter {
{label "DropZone"}
{href "#"}
{text ""}
{disposition File}
{file_name_prefix ""}
}}
::nsf::object::alloc ::xotcl::Attribute ::xowiki::BootstrapNavbarDropzone::slot::label {set :accessor public
set :configurable true
set :convert false
set :default DropZone
set :defaultmethods {}
set :disposition alias
set :domain ::xowiki::BootstrapNavbarDropzone
set :incremental 0
set :manager ::xowiki::BootstrapNavbarDropzone::slot::label
set :methodname label
set :multiplicity 1..1
set :name label
set :parameterSpec {-label:substdefault DropZone}
set :per-object false
set :position 0
set :required false
set :substdefault 0b111
set :trace none
: init}
::nsf::object::alloc ::xotcl::Attribute ::xowiki::BootstrapNavbarDropzone::slot::href {set :accessor public
set :configurable true
set :convert false
set :default #
set :defaultmethods {}
set :disposition alias
set :domain ::xowiki::BootstrapNavbarDropzone
set :incremental 0
set :manager ::xowiki::BootstrapNavbarDropzone::slot::href
set :methodname href
set :multiplicity 1..1
set :name href
set :parameterSpec {-href:substdefault #}
set :per-object false
set :position 0
set :required false
set :substdefault 0b111
set :trace none
: init}
::nsf::object::alloc ::xotcl::Attribute ::xowiki::BootstrapNavbarDropzone::slot::disposition {set :accessor public
set :configurable true
set :convert false
set :default File
set :defaultmethods {}
set :disposition alias
set :domain ::xowiki::BootstrapNavbarDropzone
set :incremental 0
set :manager ::xowiki::BootstrapNavbarDropzone::slot::disposition
set :methodname disposition
set :multiplicity 1..1
set :name disposition
set :parameterSpec {-disposition:substdefault File}
set :per-object false
set :position 0
set :required false
set :substdefault 0b111
set :trace none
: init}
::nsf::object::alloc ::xotcl::Attribute ::xowiki::BootstrapNavbarDropzone::slot::file_name_prefix {set :accessor public
set :configurable true
set :convert false
set :default {}
set :defaultmethods {}
set :disposition alias
set :domain ::xowiki::BootstrapNavbarDropzone
set :incremental 0
set :manager ::xowiki::BootstrapNavbarDropzone::slot::file_name_prefix
set :methodname file_name_prefix
set :multiplicity 1..1
set :name file_name_prefix
set :parameterSpec {-file_name_prefix:substdefault {}}
set :per-object false
set :position 0
set :required false
set :substdefault 0b111
set :trace none
: init}
::nsf::object::alloc ::xotcl::Attribute ::xowiki::BootstrapNavbarDropzone::slot::text {set :accessor public
set :configurable true
set :convert false
set :default {}
set :defaultmethods {}
set :disposition alias
set :domain ::xowiki::BootstrapNavbarDropzone
set :incremental 0
set :manager ::xowiki::BootstrapNavbarDropzone::slot::text
set :methodname text
set :multiplicity 1..1
set :name text
set :parameterSpec {-text:substdefault {}}
set :per-object false
set :position 0
set :required false
set :substdefault 0b111
set :trace none
: init}
namespace eval ::xowiki {::namespace export Menu YUIMenuBar YUIMenuBarItem YUIMenu YUIMenuItem YUIMenuItemList YUIContextMenu YUIContextMenuItem}