Compare commits

..
Author SHA1 Message Date
jocelyn fc2c72a49b Added files, and especiall upload files facility.
Main contribution from Fabian Murer, as part of ETH student project.
Supervised, refactorized and merged by Jocelyn Fiat.

Signed-off-by: Fabian Murer <fmurer@student.ethz.ch>
Signed-off-by: Jocelyn Fiat <git@djoce.net>
2016-02-16 21:03:02 +01:00
22 changed files with 3549 additions and 7752 deletions
-1
View File
@@ -1,4 +1,3 @@
@echo off
setlocal setlocal
set ROC_CMD=call %~dp0..\..\tools\roc.bat set ROC_CMD=call %~dp0..\..\tools\roc.bat
set ROC_CMS_DIR=%~dp0 set ROC_CMS_DIR=%~dp0
@@ -1,44 +1,38 @@
.uploaded-files table { .uploaded-files {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
border: 1px solid black; border: 1px solid black;
} }
.uploaded-files table th { .uploaded-files th {
padding: 3px 0 3px 5px; padding-left: 5px;
padding-top: 3px;
padding-bottom: 3px;
} }
.uploaded-files table td { .uploaded-files td {
padding: 3px 0 3px 5px; padding-left: 5px;
padding-top: 3px;
padding-bottom: 3px;
} }
.uploaded-files a.button { .uploaded-files a.button {
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999; border: solid 1px #999;
background-color: #ddd; background-color: #ddd;
padding: 2px 4px 2px 4px;
} }
.uploaded-files a.button:hover { .uploaded-files a.button:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
.upload-files .center { .upload-files a.upload-button {
text-align: center;
padding: 10px;
}
.upload-files a.button {
margin: auto; margin: auto;
width: 100px; width: 100px;
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
} }
.upload-files a.button:hover { .upload-files a.upload-button:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
/******************* Drop Zone *******************/ /******************* Drop Zone *******************/
@@ -50,3 +44,18 @@
padding-top: 15px; padding-top: 15px;
padding-bottom: 15px; padding-bottom: 15px;
} }
.dropzone .dz-message {
cursor: pointer;
}
.dropzone .dz-preview, .dropzone .dz-file-preview, .dropzone .dz-processing, .dropzone .dz-success,
.dropzone .dz-image-preview, .dropzone .dz-complete {
padding: 10px;
margin: 10px;
width: auto;
display: inline-block;
}
.dropzone .dz-preview {
border: 1px solid black;
border-radius: 5px;
background: #e6e6e6;
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,78 +0,0 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
position: relative;
.dz-preview {
position: relative;
display: inline-block;
width: 120px;
margin: 0.5em;
.dz-progress {
display: block;
height: 15px;
border: 1px solid #aaa;
.dz-upload {
display: block;
height: 100%;
width: 0;
background: green;
}
}
.dz-error-message {
color: red;
display: none;
}
&.dz-error {
.dz-error-message, .dz-error-mark {
display: block;
}
}
&.dz-success {
.dz-success-mark {
display: block;
}
}
.dz-error-mark, .dz-success-mark {
position: absolute;
display: none;
left: 30px;
top: 30px;
width: 54px;
height: 58px;
left: 50%;
margin-left: -(54px/2);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,413 +0,0 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
@mixin prefix($map, $vendors: webkit moz ms o) {
@each $prop, $value in $map {
@if $vendors {
@each $vendor in $vendors {
#{"-" + $vendor + "-" + $prop}: #{$value};
}
}
// Dump regular property anyway
#{$prop}: #{$value};
}
}
@include keyframes(passing-through) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30%, 70% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
100% {
opacity: 0;
@include prefix((transform: translateY(-40px)));
}
}
@include keyframes(slide-in) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
}
@include keyframes(pulse) {
0% { @include prefix((transform: scale(1))); }
10% { @include prefix((transform: scale(1.1))); }
20% { @include prefix((transform: scale(1))); }
}
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
$image-size: 120px;
$image-border-radius: 20px;
&.dz-clickable {
cursor: pointer;
* {
cursor: default;
}
.dz-message {
&, * {
cursor: pointer;
}
}
}
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 20px 20px;
&.dz-started {
.dz-message {
display: none;
}
}
&.dz-drag-hover {
border-style: solid;
.dz-message {
opacity: 0.5;
}
}
.dz-message {
text-align: center;
margin: 2em 0;
}
.dz-preview {
position: relative;
display: inline-block;
vertical-align: top;
margin: 16px;
min-height: 100px;
&:hover {
// Making sure that always the hovered preview element is on top
z-index: 1000;
.dz-details {
opacity: 1;
}
}
&.dz-file-preview {
.dz-image {
border-radius: $image-border-radius;
background: #999;
background: linear-gradient(to bottom, #eee, #ddd);
}
.dz-details {
opacity: 1;
}
}
&.dz-image-preview {
background: white;
.dz-details {
@include prefix((transition: opacity 0.2s linear));
}
}
.dz-remove {
font-size: 14px;
text-align: center;
display: block;
cursor: pointer;
border: none;
&:hover {
text-decoration: underline;
}
}
&:hover .dz-details {
opacity: 1;
}
.dz-details {
$background-color: #444;
z-index: 20;
position: absolute;
top: 0;
left: 0;
opacity: 0;
font-size: 13px;
min-width: 100%;
max-width: 100%;
padding: 2em 1em;
text-align: center;
color: rgba(0, 0, 0, 0.9);
$width: 120px;
line-height: 150%;
.dz-size {
margin-bottom: 1em;
font-size: 16px;
}
.dz-filename {
white-space: nowrap;
&:hover {
span {
border: 1px solid rgba(200, 200, 200, 0.8);
background-color: rgba(255, 255, 255, 0.8);
}
}
&:not(:hover) {
span {
border: 1px solid transparent;
}
overflow: hidden;
text-overflow: ellipsis;
}
}
.dz-filename, .dz-size {
span {
background-color: rgba(255, 255, 255, 0.4);
padding: 0 0.4em;
border-radius: 3px;
}
}
}
&:hover {
.dz-image {
// opacity: 0.8;
img {
@include prefix((transform: scale(1.05, 1.05))); // Getting rid of that white bleed-in
@include prefix((filter: blur(8px)), webkit); // Getting rid of that white bleed-in
}
}
}
.dz-image {
border-radius: $image-border-radius;
overflow: hidden;
width: $image-size;
height: $image-size;
position: relative;
display: block;
z-index: 10;
img {
display: block;
}
}
&.dz-success {
.dz-success-mark {
@include prefix((animation: passing-through 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
&.dz-error {
.dz-error-mark {
opacity: 1;
@include prefix((animation: slide-in 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
.dz-success-mark, .dz-error-mark {
$image-height: 54px;
$image-width: 54px;
pointer-events: none;
opacity: 0;
z-index: 500;
position: absolute;
display: block;
top: 50%;
left: 50%;
margin-left: -($image-width/2);
margin-top: -($image-height/2);
svg {
display: block;
width: $image-width;
height: $image-height;
}
}
&.dz-processing .dz-progress {
opacity: 1;
@include prefix((transition: all 0.2s linear));
}
&.dz-complete .dz-progress {
opacity: 0;
@include prefix((transition: opacity 0.4s ease-in));
}
&:not(.dz-processing) {
.dz-progress {
@include prefix((animation: pulse 6s ease infinite));
}
}
.dz-progress {
opacity: 1;
z-index: 1000;
pointer-events: none;
position: absolute;
height: 16px;
left: 50%;
top: 50%;
margin-top: -8px;
width: 80px;
margin-left: -40px;
// border: 2px solid #333;
background: rgba(255, 255, 255, 0.9);
// Fix for chrome bug: https://code.google.com/p/chromium/issues/detail?id=157218
-webkit-transform: scale(1);
border-radius: 8px;
overflow: hidden;
.dz-upload {
background: #333;
background: linear-gradient(to bottom, #666, #444);
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 0;
@include prefix((transition: width 300ms ease-in-out));
}
}
&.dz-error {
.dz-error-message {
display: block;
}
&:hover .dz-error-message {
opacity: 1;
pointer-events: auto;
}
}
.dz-error-message {
$width: $image-size + 20px;
$color: rgb(190, 38, 38);
pointer-events: none;
z-index: 1000;
position: absolute;
display: block;
display: none;
opacity: 0;
@include prefix((transition: opacity 0.3s ease));
border-radius: 8px;
font-size: 13px;
top: $image-size + 10px;
left: -10px;
width: $width;
background: $color;
background: linear-gradient(to bottom, $color, darken($color, 5%));
padding: 0.5em 1.2em;
color: white;
// The triangle pointing up
&:after {
content: '';
position: absolute;
top: -6px;
left: $width / 2 - 6px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $color;
}
}
}
}
@@ -1,16 +1,18 @@
.uploaded-files { .uploaded-files {
table { width: 100%;
width: 100%; border-collapse: collapse;
border-collapse: collapse; border: 1px solid black;
border: 1px solid black;
th { th {
padding: 3px 0 3px 5px; padding-left: 5px;
} padding-top: 3px;
padding-bottom: 3px;
}
td { td {
padding: 3px 0 3px 5px; padding-left: 5px;
} padding-top: 3px;
padding-bottom: 3px;
} }
a.button{ a.button{
@@ -18,33 +20,23 @@
text-decoration: none; text-decoration: none;
border: solid 1px #999; border: solid 1px #999;
background-color: #ddd; background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover { &:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
} }
} }
.upload-files { .upload-files {
.center { a.upload-button{
text-align: center;
padding: 10px;
}
a.button{
margin: auto; margin: auto;
width: 100px; width: 100px;
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover { &:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
} }
} }
@@ -59,5 +51,23 @@
text-align: center; text-align: center;
padding-top: 15px; padding-top: 15px;
padding-bottom: 15px; padding-bottom: 15px;
}
.dz-message {
cursor: pointer;
}
.dz-preview, .dz-file-preview, .dz-processing, .dz-success,
.dz-image-preview, .dz-complete {
padding: 10px;
margin: 10px;
width: auto;
display: inline-block;
}
.dz-preview {
border: 1px solid black;
border-radius: 5px;
background: #e6e6e6;
}
}
+11 -13
View File
@@ -103,7 +103,7 @@ feature -- Storage
end end
end end
save_uploaded_file (uf: CMS_UPLOADED_FILE) save_uploaded_file (f: CMS_UPLOADED_FILE)
local local
p: PATH p: PATH
ut: FILE_UTILITIES ut: FILE_UTILITIES
@@ -113,9 +113,9 @@ feature -- Storage
finished: BOOLEAN finished: BOOLEAN
do do
reset_error reset_error
create original_name.make_from_string (uf.filename) create original_name.make_from_string (f.filename)
p := uf.location p := f.location
if not p.is_absolute then if not p.is_absolute then
p := uploads_directory.extended_path (p) p := uploads_directory.extended_path (p)
end end
@@ -128,8 +128,8 @@ feature -- Storage
finished finished
loop loop
if ut.file_path_exists (p) then if ut.file_path_exists (p) then
uf.set_new_location_with_number (n) f.set_new_location_with_number (n)
p := uf.location p := f.location
if p.is_absolute then if p.is_absolute then
else else
p := uploads_directory.extended_path (p) p := uploads_directory.extended_path (p)
@@ -139,15 +139,13 @@ feature -- Storage
finished := True finished := True
end end
end end
stored := uf.move_to (p) stored := f.move_to (p)
else else
-- move file to path -- move file to path
stored := uf.move_to (p) stored := f.move_to (p)
end end
if stored then if not stored then
save_metadata_from_uploaded_file (uf, cms_api.user)
else
error_handler.add_custom_error (-1, "uploaded file storage failed", "Issue occurred when saving uploaded file!") error_handler.add_custom_error (-1, "uploaded file storage failed", "Issue occurred when saving uploaded file!")
end end
end end
@@ -158,7 +156,7 @@ feature -- Storage
h_date: HTTP_DATE h_date: HTTP_DATE
retried: BOOLEAN retried: BOOLEAN
do do
if retried then if not retried then
-- FIXME: Report error? -- FIXME: Report error?
if f /= Void and then not f.is_closed then if f /= Void and then not f.is_closed then
f.close f.close
@@ -174,7 +172,7 @@ feature -- Storage
end end
-- insert username -- insert username
if u /= Void then if u /= Void then
f.put_string (u.id.out) f.put_integer_64 (u.id)
f.put_new_line f.put_new_line
-- f.put_string (utf.utf_32_string_to_utf_8_string_8 (u.name)) -- f.put_string (utf.utf_32_string_to_utf_8_string_8 (u.name))
-- f.put_new_line -- f.put_new_line
@@ -184,7 +182,7 @@ feature -- Storage
end end
-- insert uploaded_time -- insert uploaded_time
create h_date.make_now_utc create h_date.make_now_utc
f.put_string (h_date.timestamp.out) f.put_integer_64 (h_date.timestamp)
f.put_new_line f.put_new_line
-- insert size of file -- insert size of file
+39 -48
View File
@@ -43,15 +43,10 @@ feature -- Access
-- List of permission ids, used by this module, and declared. -- List of permission ids, used by this module, and declared.
do do
Result := Precursor Result := Precursor
Result.force (admin_files_permission) Result.force ("admin files")
Result.force (upload_files_permission) Result.force ("upload files")
Result.force (browse_files_permission)
end end
admin_files_permission: STRING = "admin files"
upload_files_permission: STRING = "upload files"
browse_files_permission: STRING = "browse files"
feature {CMS_API} -- Module Initialization feature {CMS_API} -- Module Initialization
initialize (api: CMS_API) initialize (api: CMS_API)
@@ -97,7 +92,7 @@ feature -- Access: router
do do
map_uri_template_agent (a_router, "/" + uploads_location, agent execute_upload (?, ?, a_api), Void) -- Accepts any method GET, HEAD, POST, PUT, DELETE, ... map_uri_template_agent (a_router, "/" + uploads_location, agent execute_upload (?, ?, a_api), Void) -- Accepts any method GET, HEAD, POST, PUT, DELETE, ...
map_uri_template_agent (a_router, "/" + uploads_location + "{filename}", agent display_uploaded_file_info (?, ?, a_api), a_router.methods_get) map_uri_template_agent (a_router, "/" + uploads_location + "{filename}", agent display_uploaded_file_info (?, ?, a_api), a_router.methods_get)
map_uri_template_agent (a_router, "/" + uploads_location + "remove/{filename}", agent remove_file (?, ?, a_api), a_router.methods_get) map_uri_template_agent (a_router, "/" + uploads_location + "remove/{filename}", agent remove (?, ?, a_api), a_router.methods_get)
end end
uploads_location: STRING = "upload/" uploads_location: STRING = "upload/"
@@ -114,7 +109,7 @@ feature -- Hooks
link: CMS_LOCAL_LINK link: CMS_LOCAL_LINK
do do
-- login in demo did somehow not work -- login in demo did somehow not work
if a_response.has_permission (upload_files_permission) then if a_response.has_permission ("upload files") then
create link.make ("Upload files", uploads_location) create link.make ("Upload files", uploads_location)
a_menu_system.navigation_menu.extend (link) a_menu_system.navigation_menu.extend (link)
end end
@@ -138,17 +133,13 @@ feature -- Handler
fn: READABLE_STRING_32 fn: READABLE_STRING_32
do do
check req.is_get_request_method end check req.is_get_request_method end
if not api.has_permission (browse_files_permission) then create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.add_error_message ("You are not allowed to browse CMS files!")
elseif attached {WSF_STRING} req.path_parameter ("filename") as p_filename then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
-- add style -- add style
r.add_style (r.url ("/module/" + name + "/files/css/files.css", Void), Void) r.add_style (r.url ("/module/" + name + "/files/css/files.css", Void), Void)
create body.make_empty
create body.make_empty
if attached {WSF_STRING} req.path_parameter ("filename") as p_filename then
fn := p_filename.value fn := p_filename.value
r.set_page_title ({STRING_32} "File %"" + fn + {STRING_32} "%"") r.set_page_title ({STRING_32} "File %"" + fn + {STRING_32} "%"")
body.append ("<div class=%"uploaded-files%">%N") -- To ease css customization. body.append ("<div class=%"uploaded-files%">%N") -- To ease css customization.
@@ -216,13 +207,9 @@ feature -- Handler
body.append ("</div>%N") -- Overview body.append ("</div>%N") -- Overview
end end
body.append ("</div>%N") body.append ("</div>%N")
r.add_to_primary_tabs (create {CMS_LOCAL_LINK}.make ("Uploaded files", uploads_location))
r.set_main_content (body)
else
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.set_main_content ("Missing 'filename' field value!")
end end
r.add_to_primary_tabs (create {CMS_LOCAL_LINK}.make ("Uploaded files", uploads_location))
r.set_main_content (body)
r.execute r.execute
end end
@@ -242,9 +229,8 @@ feature -- Handler
-- add JS for dropzone -- add JS for dropzone
r.add_javascript_url (r.url ("/module/" + name + "/files/js/dropzone.js", void)) r.add_javascript_url (r.url ("/module/" + name + "/files/js/dropzone.js", void))
r.add_style (r.url ("/module/" + name + "/files/js/dropzone.css", void), void)
if api.has_permission (upload_files_permission) then if r.has_permission ("upload files") then
-- create body -- create body
body.append ("<p>Please choose some file(s) to upload.</p>") body.append ("<p>Please choose some file(s) to upload.</p>")
@@ -252,7 +238,7 @@ feature -- Handler
body.append ("<div class=%"upload-files%">") body.append ("<div class=%"upload-files%">")
body.append ("<form action=%"" + r.url (uploads_location, Void) + "%" class=%"dropzone%">") body.append ("<form action=%"" + r.url (uploads_location, Void) + "%" class=%"dropzone%">")
body.append ("</form>%N") body.append ("</form>%N")
body.append ("<div class=%"center%"><a class=%"button%" href=%""+ r.url (uploads_location, Void) +"%">Upload Files</a></div>") body.append ("<a class=%"button%" href=%""+ r.url (uploads_location, Void) +"%">Upload Files</a>")
body.append ("</div>") body.append ("</div>")
if req.is_post_request_method then if req.is_post_request_method then
process_uploaded_files (req, api, body) process_uploaded_files (req, api, body)
@@ -262,11 +248,8 @@ feature -- Handler
end end
-- Build the response. -- Build the response.
if r.has_permission (browse_files_permission) then
append_uploaded_file_album_to (req, api, body) append_uploaded_file_album_to (req, api, body)
else
r.add_warning_message ("You are not allowed to browse files!")
end
r.set_main_content (body) r.set_main_content (body)
else else
@@ -276,9 +259,7 @@ feature -- Handler
end end
process_uploaded_files (req: WSF_REQUEST; api: CMS_API; a_output: STRING) process_uploaded_files (req: WSF_REQUEST; api: CMS_API; a_output: STRING)
-- Process http request uploaded files. -- show all newly uploaded files
require
has_permission: api.has_permission (upload_files_permission)
local local
l_uploaded_file: CMS_UPLOADED_FILE l_uploaded_file: CMS_UPLOADED_FILE
uf: WSF_UPLOADED_FILE uf: WSF_UPLOADED_FILE
@@ -296,12 +277,14 @@ feature -- Handler
a_output.append ("<li>") a_output.append ("<li>")
a_output.append (api.html_encoded (l_uploaded_file.filename)) a_output.append (api.html_encoded (l_uploaded_file.filename))
-- store the just uploaded file
l_files_api.save_uploaded_file (l_uploaded_file)
-- create medadata file -- create medadata file
l_uploaded_file.set_size (uf.size) l_uploaded_file.set_size (uf.size)
l_uploaded_file.set_type (uf.content_type) l_uploaded_file.set_type (uf.content_type)
-- store the just uploaded file l_files_api.save_metadata_from_uploaded_file (l_uploaded_file, api.current_user (req))
l_files_api.save_uploaded_file (l_uploaded_file)
if l_files_api.has_error then if l_files_api.has_error then
a_output.append (" <span class=%"error%">: upload failed!</span>") a_output.append (" <span class=%"error%">: upload failed!</span>")
@@ -320,14 +303,14 @@ feature -- Handler
p: PATH p: PATH
rel: PATH rel: PATH
md: detachable CMS_FILE_METADATA md: detachable CMS_FILE_METADATA
size: INTEGER
do do
if attached files_api as l_files_api then if attached files_api as l_files_api then
rel := l_files_api.uploads_relative_path rel := l_files_api.uploads_relative_path
p := l_files_api.uploads_directory p := l_files_api.uploads_directory
a_output.append ("<div class=%"uploaded-files%">%N")
a_output.append ("<strong>Uploaded files:</strong>%N") a_output.append ("<strong>Uploaded files:</strong>%N")
a_output.append ("<table>%N") a_output.append ("<table class=%"uploaded-files%">%N")
a_output.append ("<tr><th>Filename</th><th>Uploading Time</th><th>User</th><th>Size</th><th></th><th></th></tr>%N") a_output.append ("<tr><th>Filename</th><th>Uploading Time</th><th>User</th><th>Size</th><th></th><th></th></tr>%N")
create d.make_with_path (p) create d.make_with_path (p)
@@ -378,7 +361,18 @@ feature -- Handler
-- add size -- add size
a_output.append ("<td class=%"size%">") a_output.append ("<td class=%"size%">")
if md.size > 0 then if md.size > 0 then
a_output.append (file_size_human_string (md.size)) size := md.size
if size >= 1000000 then
size := size // 1000000
a_output.append (size.out + " MB")
else
if size >= 1000 then
size := size // 1000
a_output.append (size.out + " kB")
else
a_output.append (size.out + " bytes")
end
end
else else
a_output.append ("NA") a_output.append ("NA")
end end
@@ -387,12 +381,12 @@ feature -- Handler
-- add download link -- add download link
a_output.append ("<td>") a_output.append ("<td>")
a_output.append ("<a class=%"button%" href=%"" + req.script_url ("/" + l_files_api.file_link (f).location) + "%" download>Download</a>%N") a_output.append ("<button><a class=%"download-button%" href=%"" + req.script_url ("/" + l_files_api.file_link (f).location) + "%" download>Download</a></button>%N")
a_output.append ("</td>%N") a_output.append ("</td>%N")
-- add remove button -- add remove button
a_output.append ("<td>") a_output.append ("<td>")
a_output.append ("<a class=%"button%" href=%"" + req.script_url ("/" + uploads_location + "remove/" + f.filename) + "%">Remove</a>%N") a_output.append ("<button><a class=%"download-button%" href=%"" + req.script_url ("/" + uploads_location + "remove/" + f.filename) + "%">Remove</a></button>%N")
a_output.append ("</td>%N") a_output.append ("</td>%N")
a_output.append ("</tr>%N") a_output.append ("</tr>%N")
@@ -420,21 +414,18 @@ feature -- Handler
end end
end end
a_output.append ("</table>%N") a_output.append ("</table>%N")
a_output.append ("</div>%N")
end end
end end
remove_file (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API) remove (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
local local
body: STRING body: STRING
r: CMS_RESPONSE r: CMS_RESPONSE
err: BOOLEAN err: BOOLEAN
do do
if attached files_api as l_files_api then if attached files_api as l_files_api then
if not api.has_permission (admin_files_permission) then if attached {WSF_STRING} req.path_parameter ("filename") as p_filename then
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.add_error_message ("You are not allowed to remove file!")
elseif attached {WSF_STRING} req.path_parameter ("filename") as p_filename then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
l_files_api.delete_file (p_filename.value) l_files_api.delete_file (p_filename.value)
+28 -19
View File
@@ -1,44 +1,38 @@
.uploaded-files table { .uploaded-files {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
border: 1px solid black; border: 1px solid black;
} }
.uploaded-files table th { .uploaded-files th {
padding: 3px 0 3px 5px; padding-left: 5px;
padding-top: 3px;
padding-bottom: 3px;
} }
.uploaded-files table td { .uploaded-files td {
padding: 3px 0 3px 5px; padding-left: 5px;
padding-top: 3px;
padding-bottom: 3px;
} }
.uploaded-files a.button { .uploaded-files a.button {
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999; border: solid 1px #999;
background-color: #ddd; background-color: #ddd;
padding: 2px 4px 2px 4px;
} }
.uploaded-files a.button:hover { .uploaded-files a.button:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
.upload-files .center { .upload-files a.upload-button {
text-align: center;
padding: 10px;
}
.upload-files a.button {
margin: auto; margin: auto;
width: 100px; width: 100px;
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
} }
.upload-files a.button:hover { .upload-files a.upload-button:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
/******************* Drop Zone *******************/ /******************* Drop Zone *******************/
@@ -50,3 +44,18 @@
padding-top: 15px; padding-top: 15px;
padding-bottom: 15px; padding-bottom: 15px;
} }
.dropzone .dz-message {
cursor: pointer;
}
.dropzone .dz-preview, .dropzone .dz-file-preview, .dropzone .dz-processing, .dropzone .dz-success,
.dropzone .dz-image-preview, .dropzone .dz-complete {
padding: 10px;
margin: 10px;
width: auto;
display: inline-block;
}
.dropzone .dz-preview {
border: 1px solid black;
border-radius: 5px;
background: #e6e6e6;
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,78 +0,0 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
position: relative;
.dz-preview {
position: relative;
display: inline-block;
width: 120px;
margin: 0.5em;
.dz-progress {
display: block;
height: 15px;
border: 1px solid #aaa;
.dz-upload {
display: block;
height: 100%;
width: 0;
background: green;
}
}
.dz-error-message {
color: red;
display: none;
}
&.dz-error {
.dz-error-message, .dz-error-mark {
display: block;
}
}
&.dz-success {
.dz-success-mark {
display: block;
}
}
.dz-error-mark, .dz-success-mark {
position: absolute;
display: none;
left: 30px;
top: 30px;
width: 54px;
height: 58px;
left: 50%;
margin-left: -(54px/2);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,413 +0,0 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
@mixin prefix($map, $vendors: webkit moz ms o) {
@each $prop, $value in $map {
@if $vendors {
@each $vendor in $vendors {
#{"-" + $vendor + "-" + $prop}: #{$value};
}
}
// Dump regular property anyway
#{$prop}: #{$value};
}
}
@include keyframes(passing-through) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30%, 70% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
100% {
opacity: 0;
@include prefix((transform: translateY(-40px)));
}
}
@include keyframes(slide-in) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
}
@include keyframes(pulse) {
0% { @include prefix((transform: scale(1))); }
10% { @include prefix((transform: scale(1.1))); }
20% { @include prefix((transform: scale(1))); }
}
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
$image-size: 120px;
$image-border-radius: 20px;
&.dz-clickable {
cursor: pointer;
* {
cursor: default;
}
.dz-message {
&, * {
cursor: pointer;
}
}
}
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 20px 20px;
&.dz-started {
.dz-message {
display: none;
}
}
&.dz-drag-hover {
border-style: solid;
.dz-message {
opacity: 0.5;
}
}
.dz-message {
text-align: center;
margin: 2em 0;
}
.dz-preview {
position: relative;
display: inline-block;
vertical-align: top;
margin: 16px;
min-height: 100px;
&:hover {
// Making sure that always the hovered preview element is on top
z-index: 1000;
.dz-details {
opacity: 1;
}
}
&.dz-file-preview {
.dz-image {
border-radius: $image-border-radius;
background: #999;
background: linear-gradient(to bottom, #eee, #ddd);
}
.dz-details {
opacity: 1;
}
}
&.dz-image-preview {
background: white;
.dz-details {
@include prefix((transition: opacity 0.2s linear));
}
}
.dz-remove {
font-size: 14px;
text-align: center;
display: block;
cursor: pointer;
border: none;
&:hover {
text-decoration: underline;
}
}
&:hover .dz-details {
opacity: 1;
}
.dz-details {
$background-color: #444;
z-index: 20;
position: absolute;
top: 0;
left: 0;
opacity: 0;
font-size: 13px;
min-width: 100%;
max-width: 100%;
padding: 2em 1em;
text-align: center;
color: rgba(0, 0, 0, 0.9);
$width: 120px;
line-height: 150%;
.dz-size {
margin-bottom: 1em;
font-size: 16px;
}
.dz-filename {
white-space: nowrap;
&:hover {
span {
border: 1px solid rgba(200, 200, 200, 0.8);
background-color: rgba(255, 255, 255, 0.8);
}
}
&:not(:hover) {
span {
border: 1px solid transparent;
}
overflow: hidden;
text-overflow: ellipsis;
}
}
.dz-filename, .dz-size {
span {
background-color: rgba(255, 255, 255, 0.4);
padding: 0 0.4em;
border-radius: 3px;
}
}
}
&:hover {
.dz-image {
// opacity: 0.8;
img {
@include prefix((transform: scale(1.05, 1.05))); // Getting rid of that white bleed-in
@include prefix((filter: blur(8px)), webkit); // Getting rid of that white bleed-in
}
}
}
.dz-image {
border-radius: $image-border-radius;
overflow: hidden;
width: $image-size;
height: $image-size;
position: relative;
display: block;
z-index: 10;
img {
display: block;
}
}
&.dz-success {
.dz-success-mark {
@include prefix((animation: passing-through 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
&.dz-error {
.dz-error-mark {
opacity: 1;
@include prefix((animation: slide-in 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
.dz-success-mark, .dz-error-mark {
$image-height: 54px;
$image-width: 54px;
pointer-events: none;
opacity: 0;
z-index: 500;
position: absolute;
display: block;
top: 50%;
left: 50%;
margin-left: -($image-width/2);
margin-top: -($image-height/2);
svg {
display: block;
width: $image-width;
height: $image-height;
}
}
&.dz-processing .dz-progress {
opacity: 1;
@include prefix((transition: all 0.2s linear));
}
&.dz-complete .dz-progress {
opacity: 0;
@include prefix((transition: opacity 0.4s ease-in));
}
&:not(.dz-processing) {
.dz-progress {
@include prefix((animation: pulse 6s ease infinite));
}
}
.dz-progress {
opacity: 1;
z-index: 1000;
pointer-events: none;
position: absolute;
height: 16px;
left: 50%;
top: 50%;
margin-top: -8px;
width: 80px;
margin-left: -40px;
// border: 2px solid #333;
background: rgba(255, 255, 255, 0.9);
// Fix for chrome bug: https://code.google.com/p/chromium/issues/detail?id=157218
-webkit-transform: scale(1);
border-radius: 8px;
overflow: hidden;
.dz-upload {
background: #333;
background: linear-gradient(to bottom, #666, #444);
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 0;
@include prefix((transition: width 300ms ease-in-out));
}
}
&.dz-error {
.dz-error-message {
display: block;
}
&:hover .dz-error-message {
opacity: 1;
pointer-events: auto;
}
}
.dz-error-message {
$width: $image-size + 20px;
$color: rgb(190, 38, 38);
pointer-events: none;
z-index: 1000;
position: absolute;
display: block;
display: none;
opacity: 0;
@include prefix((transition: opacity 0.3s ease));
border-radius: 8px;
font-size: 13px;
top: $image-size + 10px;
left: -10px;
width: $width;
background: $color;
background: linear-gradient(to bottom, $color, darken($color, 5%));
padding: 0.5em 1.2em;
color: white;
// The triangle pointing up
&:after {
content: '';
position: absolute;
top: -6px;
left: $width / 2 - 6px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $color;
}
}
}
}
+35 -25
View File
@@ -1,16 +1,18 @@
.uploaded-files { .uploaded-files {
table { width: 100%;
width: 100%; border-collapse: collapse;
border-collapse: collapse; border: 1px solid black;
border: 1px solid black;
th { th {
padding: 3px 0 3px 5px; padding-left: 5px;
} padding-top: 3px;
padding-bottom: 3px;
}
td { td {
padding: 3px 0 3px 5px; padding-left: 5px;
} padding-top: 3px;
padding-bottom: 3px;
} }
a.button{ a.button{
@@ -18,33 +20,23 @@
text-decoration: none; text-decoration: none;
border: solid 1px #999; border: solid 1px #999;
background-color: #ddd; background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover { &:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
} }
} }
.upload-files { .upload-files {
.center { a.upload-button{
text-align: center;
padding: 10px;
}
a.button{
margin: auto; margin: auto;
width: 100px; width: 100px;
color: black; color: black;
text-decoration: none; text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover { &:hover {
color: black; color: black;
border: solid 1px #06f; text-decoration: none;
background-color: #cff;
} }
} }
} }
@@ -59,5 +51,23 @@
text-align: center; text-align: center;
padding-top: 15px; padding-top: 15px;
padding-bottom: 15px; padding-bottom: 15px;
}
.dz-message {
cursor: pointer;
}
.dz-preview, .dz-file-preview, .dz-processing, .dz-success,
.dz-image-preview, .dz-complete {
padding: 10px;
margin: 10px;
width: auto;
display: inline-block;
}
.dz-preview {
border: 1px solid black;
border-radius: 5px;
background: #e6e6e6;
}
}
+30 -32
View File
@@ -9,38 +9,38 @@ deferred class
feature -- Initialisation feature -- Initialisation
load_assets: STRING load_assets : STRING
-- Loads all assest needed to show the editor. -- Loads all assest needed to show the editor
deferred deferred
end end
feature -- Javascript feature -- Javascript
javascript_replace_textarea (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_replace_textarea (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code that replaces a textarea with the editor. The editor instance should be saved in editor_variable. -- Javascript code that replaces a textarea with the editor. The editor instance should be saved in editor_variable
deferred deferred
end end
javascript_restore_textarea (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_restore_textarea (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code that restores a textarea -- Javascript code that restores a textarea
deferred deferred
end end
javascript_textarea_to_editor (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_textarea_to_editor (a_textarea : WSF_FORM_TEXTAREA): STRING
-- Javascript code to display the textarea as a WYSIWIG editor as soon as the document is loaded. -- Javascript code to display the textarea as a WYSIWIG editor as soon as the document is loaded
do do
Result := javascript_ready (javascript_replace_textarea (a_textarea)) Result := javascript_ready (javascript_replace_textarea (a_textarea))
end end
javascript_textarea_to_editor_if_selected (a_textarea: WSF_FORM_TEXTAREA; a_select_field: WSF_FORM_SELECT; a_value: STRING): STRING javascript_textarea_to_editor_if_selected (a_textarea: WSF_FORM_TEXTAREA; a_select_field : WSF_FORM_SELECT; a_value : STRING) : STRING
-- Javascript code to display the textarea as a WYSIWIG editor if a_select_field has a_value, -- Javascript code to display the textarea as a WYSIWIG editor if a_select_field has a_value
local local
initial_replace_code, on_select_replace_code: STRING initial_replace_code, on_select_replace_code: STRING
do do
-- Javascript that replaces the textarea if a_value is selected at load time -- Javascript that replaces the textarea if a_value is selected at load time
initial_replace_code := javascript_ready (javascript_if_selected (a_select_field, a_value, javascript_replace_textarea (a_textarea))) initial_replace_code := javascript_ready (javascript_if_selected (a_select_field, a_value, javascript_replace_textarea (a_textarea)))
-- Javascript code that replaces the textarea as soon as value is selected at a_select_field -- Javascript code that replaces the textarea as soon as value is selected at a_select_field
on_select_replace_code := javascript_ready( on_select_replace_code := javascript_ready(
javascript_init_editor_variable (a_textarea) + javascript_init_editor_variable (a_textarea) +
javascript_on_select (a_select_field, a_value, javascript_on_select (a_select_field, a_value,
@@ -55,56 +55,54 @@ feature -- Javascript
Result := initial_replace_code + " " + on_select_replace_code Result := initial_replace_code + " " + on_select_replace_code
end end
javascript_init_editor_variable (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_init_editor_variable (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- Returns the javascript code that initializes a local variable to store the editor instance. -- Returns the javascript code that initializes a local variable to store the editor instance
do do
Result := "var " + editor_variable (a_textarea) + "; " Result := "var " + editor_variable (a_textarea) + "; "
end end
javascript_if_selected (a_select_field: WSF_FORM_SELECT; a_value: STRING; a_code: STRING): STRING javascript_if_selected (a_select_field : WSF_FORM_SELECT; a_value : STRING; a_code : STRING) : STRING
-- Javascript that executes a_code if a_value is selected at a_select_field. -- Javascript that executes a_code if a_value is selected at a_select_field
do do
Result := "if($('#" + field_id (a_select_field) + "').val() == %"" + a_value + "%"){ " + a_code + " }" Result := "if($('#" + field_id (a_select_field) + "').val() == %"" + a_value + "%"){ " + a_code + " }"
end end
javascript_ready (a_code: STRING): STRING javascript_ready (a_code : STRING) : STRING
-- Wraps the given javascript code with a ready statement, -- Wraps the given javascript code with a ready statement, such that it's executed when the document has loaded
-- such that it's executed when the document has loaded.
do do
Result := "$(function() { " + a_code + " });" Result := "$(function() { " + a_code + " });"
end end
javascript_on_select (a_select_field: WSF_FORM_SELECT; a_value: STRING; a_then: STRING; a_else: STRING): STRING javascript_on_select (a_select_field : WSF_FORM_SELECT; a_value : STRING; a_then : STRING; a_else : STRING) : STRING
-- Javascript code that executes `a_then' if at the given `a_select_field' -- Javascript code that executes a_then if at the given select_field the given string value is selected, otherwise it executes a_else
-- the given string `a_value' is selected, otherwise it executes `a_else'.
do do
Result := "$('#" + field_id (a_select_field) + "').change(function(){" Result := "$('#" + field_id (a_select_field) + "').change(function(){" +
+ javascript_if_selected (a_select_field, a_value, a_then) javascript_if_selected (a_select_field, a_value, a_then) +
+ "else{" "else{" +
+ a_else a_else +
+ "}" "}" +
+ "});" "});"
end end
feature -- Helper feature -- Helper
field_id (a_select_field: WSF_FORM_SELECT): STRING field_id(a_select_field : WSF_FORM_SELECT) : STRING
-- Id of the given field. -- Returns the id of the given field
do do
if attached a_select_field.css_id as a_id then if attached a_select_field.css_id as a_id then
Result := a_id Result := a_id
else else
Result := a_select_field.name + "-select" Result := a_select_field.name + "-select"
end end
end end
editor_variable (a_textarea: WSF_FORM_TEXTAREA): STRING editor_variable (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- Returns the variable name that stores the editor instance of the given textarea -- Returns the variable name that stores the editor instance of the given textarea
do do
Result := "cms_ckeditor_" + a_textarea.name Result := "cms_ckeditor_" + a_textarea.name
end end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end
+6 -8
View File
@@ -12,7 +12,7 @@ inherit
feature -- Initialisation feature -- Initialisation
load_assets: STRING load_assets : STRING
-- <Precursor> -- <Precursor>
do do
Result := "<script src=%"//cdn.ckeditor.com/4.4.7/standard/ckeditor.js%"></script>" Result := "<script src=%"//cdn.ckeditor.com/4.4.7/standard/ckeditor.js%"></script>"
@@ -20,25 +20,23 @@ feature -- Initialisation
feature -- Javascript feature -- Javascript
javascript_replace_textarea (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_replace_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- <Precursor> -- <Precursor>
do do
-- Replaces the textarea with an editor instance. -- Replaces the textarea with an editor instance. Save the instance in a variable
-- Save the instance in a variable.
Result := "$(%"textarea[name="+ a_textarea.name +"]%").each(function() {" Result := "$(%"textarea[name="+ a_textarea.name +"]%").each(function() {"
Result.append (editor_variable (a_textarea) + " = CKEDITOR.replace(this);") Result.append (editor_variable (a_textarea) + " = CKEDITOR.replace(this);")
Result.append ("});") Result.append ("});")
end end
javascript_restore_textarea (a_textarea: WSF_FORM_TEXTAREA): STRING javascript_restore_textarea (a_textarea : WSF_FORM_TEXTAREA) : STRING
-- <Precursor> -- <Precursor>
do do
-- Replaces the textarea with an editor instance. -- Replaces the textarea with an editor instance. Save the instance in a variable
-- Save the instance in a variable.
Result := "if (" + editor_variable (a_textarea) + " != undefined) " + editor_variable (a_textarea) + ".destroy();" Result := "if (" + editor_variable (a_textarea) + " != undefined) " + editor_variable (a_textarea) + ".destroy();"
end end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end
+3 -20
View File
@@ -282,9 +282,7 @@ feature -- Head customization
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<link rel=%"stylesheet%" href=%"") s := "<link rel=%"stylesheet%" href=%""+ a_href + "%" type=%"text/css%""
s.append (a_href)
s.append ("%" type=%"text/css%"")
if a_media /= Void then if a_media /= Void then
s.append (" media=%""+ a_media + "%"") s.append (" media=%""+ a_media + "%"")
end end
@@ -292,24 +290,11 @@ feature -- Head customization
add_additional_head_line (s, False) add_additional_head_line (s, False)
end end
add_style_content (a_style_content: STRING)
-- Add style content `a_style_content' in the head, using <style> tag.
local
s: STRING_8
do
create s.make_from_string ("<style>%N")
s.append (a_style_content)
s.append ("%N</style>")
add_additional_head_line (s, True)
end
add_javascript_url (a_src: STRING) add_javascript_url (a_src: STRING)
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<script type=%"text/javascript%" src=%"") s := "<script type=%"text/javascript%" src=%"" + a_src + "%"></script>"
s.append (a_src)
s.append ("%"></script>")
add_additional_head_line (s, False) add_additional_head_line (s, False)
end end
@@ -317,9 +302,7 @@ feature -- Head customization
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<script type=%"text/javascript%">%N") s := "<script type=%"text/javascript%">%N" + a_script + "%N</script>"
s.append (a_script)
s.append ("%N</script>")
add_additional_head_line (s, True) add_additional_head_line (s, True)
end end
+9 -31
View File
@@ -144,17 +144,12 @@ feature -- Element change
title := s title := s
end end
add_additional_head_line (s: READABLE_STRING_8)
do
head_lines.extend (s)
end
add_meta_name_content (a_name: STRING; a_content: STRING) add_meta_name_content (a_name: STRING; a_content: STRING)
local local
s: STRING_8 s: STRING_8
do do
s := "<meta name=%"" + a_name + "%" content=%"" + a_content + "%" />" s := "<meta name=%"" + a_name + "%" content=%"" + a_content + "%" />"
add_additional_head_line (s) head_lines.extend (s)
end end
add_meta_http_equiv (a_http_equiv: STRING; a_content: STRING) add_meta_http_equiv (a_http_equiv: STRING; a_content: STRING)
@@ -162,56 +157,39 @@ feature -- Element change
s: STRING_8 s: STRING_8
do do
s := "<meta http-equiv=%"" + a_http_equiv + "%" content=%"" + a_content + "%" />" s := "<meta http-equiv=%"" + a_http_equiv + "%" content=%"" + a_content + "%" />"
add_additional_head_line (s) head_lines.extend (s)
end end
add_style (a_href: STRING; a_media: detachable STRING) add_style (a_href: STRING; a_media: detachable STRING)
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<link rel=%"stylesheet%" href=%"") s := "<link rel=%"stylesheet%" href=%""+ a_href + "%" type=%"text/css%""
s.append (a_href)
s.append ("%" type=%"text/css%"")
if a_media /= Void then if a_media /= Void then
s.append (" media=%""+ a_media + "%"") s.append (" media=%""+ a_media + "%"")
end end
s.append ("/>") s.append ("/>")
add_additional_head_line (s) head_lines.extend (s)
end
add_style_content (a_style_content: STRING)
-- Add style content `a_style_content' in the head, using <style> tag.
local
s: STRING_8
do
create s.make_from_string ("<style>%N")
s.append (a_style_content)
s.append ("%N</style>")
add_additional_head_line (s)
end end
add_javascript_url (a_src: STRING) add_javascript_url (a_src: STRING)
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<script type=%"text/javascript%" src=%"") s := "<script type=%"text/javascript%" src=%"" + a_src + "%"></script>"
s.append (a_src) head_lines.extend (s)
s.append ("%"></script>")
add_additional_head_line (s)
end end
add_javascript_content (a_script: STRING) add_javascript_content (a_script: STRING)
local local
s: STRING_8 s: STRING_8
do do
create s.make_from_string ("<script type=%"text/javascript%">%N") s := "<script type=%"text/javascript%">%N" + a_script + "%N</script>"
s.append (a_script) head_lines.extend (s)
s.append ("%N</script>")
add_additional_head_line (s)
end end
note note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software
+1 -1
View File
@@ -30,7 +30,7 @@ set ROC_TOOL_PATH=%~dp0
goto START goto START
:START :START
rem echo Calling %ROC_TOOL_PATH%roc.exe %* echo Calling %ROC_TOOL_PATH%roc.exe %*
call %ROC_TOOL_PATH%roc.exe %* call %ROC_TOOL_PATH%roc.exe %*
goto END goto END