WIP
parent
871cca4b6a
commit
9af5bd2229
|
@ -38,3 +38,5 @@
|
|||
border-right: 1px solid black;
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,5 +84,9 @@ body,p,div {
|
|||
min-height: 400px;
|
||||
}
|
||||
|
||||
#preview {
|
||||
float: right;
|
||||
right: 25px;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,10 +23,14 @@ class FileObject(WebObject):
|
|||
|
||||
class DiskFolder(WebObject,Persistence):
|
||||
|
||||
def __init__(self,path):
|
||||
self._path = path
|
||||
def __init__(self, path, readOnly = False):
|
||||
self.__path = path
|
||||
self.__readOnly = readOnly
|
||||
self.__files = {}
|
||||
|
||||
def __dir__(self):
|
||||
return os.listdir( self._path)
|
||||
return os.listdir( self.__path )
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -15,3 +15,6 @@ class WebCallable:
|
|||
else:
|
||||
request.getContentFile().write("<html><head><title>No Content</title></head><body>Sorry, no content here!</body></html>")
|
||||
|
||||
class WebCallableObject(WebCallable):
|
||||
pass
|
||||
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
from objectbroker import Persistence,NoPersistence,Aquisition,AquisitionProxy
|
||||
from hserver.api.WebCallable import WebCallable
|
||||
from hserver.api.WebCallable import WebCallable,WebCallableObject
|
||||
from hserver.types.FormApplyable import FormApplyable
|
||||
|
||||
from hserver.session.SessionHandler import SessionHandler
|
||||
|
||||
import hserver
|
||||
import hserver.api
|
||||
|
||||
class WebObject(WebCallable,Aquisition):
|
||||
from simplelog import log
|
||||
|
||||
class WebObject(WebCallableObject,FormApplyable,Aquisition):
|
||||
|
||||
WO_Accepts = None
|
||||
FA_Names = { "title": "title" }
|
||||
|
@ -65,6 +68,7 @@ class WebObject(WebCallable,Aquisition):
|
|||
return ls
|
||||
|
||||
def walk(self,request):
|
||||
log("walk: {0}".format(self))
|
||||
|
||||
for shandler in self.__sessionhandlers:
|
||||
shandler.applySession(request)
|
||||
|
@ -76,7 +80,9 @@ class WebObject(WebCallable,Aquisition):
|
|||
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
||||
|
||||
if (len(stack)==0) or (not isinstance(no,WebObject)):
|
||||
if (isinstance(no,WebCallable)):
|
||||
if (isinstance(no,WebCallableObject)):
|
||||
no(request, o=no)
|
||||
elif (isinstance(no,WebCallable)):
|
||||
no(request, o=self)
|
||||
else:
|
||||
raise hserver.HttpException(404,"%s in /%s" % (next,request.pathwalker().walked(-1)))
|
||||
|
@ -126,18 +132,10 @@ class WebObject(WebCallable,Aquisition):
|
|||
elif not hasattr(self, n):
|
||||
setattr( self, n, t() )
|
||||
|
||||
class NavWebObject(WebObject):
|
||||
class NavWebObject(WebObject,Persistence):
|
||||
|
||||
def __init__(self,title = None):
|
||||
WebObject.__init__(self)
|
||||
self.title = title
|
||||
|
||||
def title(self):
|
||||
t = getattr(self,"title",None)
|
||||
if t is None:
|
||||
return self.__aq_name
|
||||
return t
|
||||
|
||||
|
||||
def navigation(self,levels = 1):
|
||||
nav = {}
|
||||
|
|
|
@ -6,6 +6,8 @@ from hserver.api.WebObject import WebObject,NavWebObject
|
|||
from hserver.api.FileObject import FileObject
|
||||
from hserver.api.SimpleObject import SimpleObject
|
||||
|
||||
from hserver.types.FormApplyable import FormApplyable
|
||||
|
||||
from hserver.api.SessionHandlerObject import SessionHandlerObject
|
||||
from hserver.api.CookieSessionHandler import CookieSessionHandler
|
||||
|
||||
|
|
|
@ -8,11 +8,17 @@ from hserver.templates.Template import Template
|
|||
import hserver
|
||||
|
||||
from simplelog import log
|
||||
import simplelog
|
||||
|
||||
|
||||
from objectbroker import Serializer,XMLStore
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import json
|
||||
|
||||
import xml.etree.ElementTree
|
||||
|
||||
|
||||
class RootFolder(WebObject,Persistence):
|
||||
|
||||
|
@ -51,6 +57,8 @@ class RootFolder(WebObject,Persistence):
|
|||
|
||||
|
||||
except Exception as ex:
|
||||
log("JSON-RPC: Exception")
|
||||
simplelog.logException(ex)
|
||||
reply["result"] = None
|
||||
reply["exception"] = repr(ex)
|
||||
|
||||
|
@ -59,6 +67,8 @@ class RootFolder(WebObject,Persistence):
|
|||
log("JReply: {0}".format(jreply))
|
||||
request.getContentFile().write( jreply )
|
||||
|
||||
_hm_json = WebCallable( method = hm_json )
|
||||
|
||||
def objCreate(self,request,objTypeName,objName,objPath):
|
||||
if (objTypeName == ""):
|
||||
raise Exception("objTypeName must contain a valid type")
|
||||
|
@ -83,8 +93,16 @@ class RootFolder(WebObject,Persistence):
|
|||
|
||||
return True
|
||||
|
||||
def objExport(self,request, objPath):
|
||||
xs = XMLStore(None)
|
||||
s = Serializer(xs)
|
||||
|
||||
o = self.objPathWalk( request, objPath )
|
||||
|
||||
s.serialize( o._aq_object )
|
||||
|
||||
return xml.etree.ElementTree.tostring( xs.lastXml() ).decode("utf-8")
|
||||
|
||||
_hm_json = WebCallable( method = hm_json )
|
||||
|
||||
def objPathWalk(self, request, path):
|
||||
o = self
|
||||
|
|
|
@ -89,7 +89,7 @@ function editorApply(objPath){
|
|||
if (hm.editor.fields.hasOwnProperty( field )){
|
||||
formData.append( field, hm.editor.fields[ field ].value );
|
||||
}
|
||||
}
|
||||
}
|
||||
var reply = callURL( objPath + "/_hm_apply", formData, null, "POST" );
|
||||
} catch (e){
|
||||
alert(e);
|
||||
|
@ -102,6 +102,28 @@ function editorSave(){
|
|||
return false;
|
||||
}
|
||||
|
||||
function editorExport(){
|
||||
var objPath = hm.editor.objPath;
|
||||
var reply = callJson( "objExport", { "objPath" : pathSplit(objPath) } )
|
||||
|
||||
var a = document.createElement("a");
|
||||
a.setAttribute('href', "data:text/xml," + escape(reply.result));
|
||||
a.setAttribute('download', 'object.xml');
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
|
||||
}
|
||||
|
||||
function editorImport(){
|
||||
var files = $("importxmlfile").files;
|
||||
if (files.length == 0){
|
||||
alert("First, you need to select a file to import into this node!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -117,6 +139,7 @@ function objRemove( objPath ){
|
|||
|
||||
|
||||
|
||||
|
||||
function onAddObjectButton(button,objPath,parentID){
|
||||
var ctlObjName = "objName-" + parentID;
|
||||
var objName = $(ctlObjName).value;
|
||||
|
|
|
@ -3,8 +3,14 @@
|
|||
|
||||
<form onsubmit="return editorSave();">
|
||||
|
||||
<div class="block">
|
||||
<div class="block right side">
|
||||
<button class="button" onclick="editorSave();">Speichern</button>
|
||||
<button class="button" onclick="editorExport();">Exportieren</button>
|
||||
<div class="button slider right">Importieren
|
||||
<div>Importiere <input type="file" id="importxmlfile" name="importxmlfile"><br/>
|
||||
als <input type="text" id="objNameImport" value=""/>
|
||||
<button class="button" onclick="editorImport();">Importieren...</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
|
|
|
@ -14,11 +14,35 @@ h1,h2,h3,h4,h5 {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 3px;
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-width: 50%;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
button, .button, input[type=button], textarea {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
background-color: #E0E0FF;
|
||||
|
||||
border: 1px solid #202040;
|
||||
border-radius: 3px;
|
||||
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
height: 32px;
|
||||
|
||||
width: 100px;
|
||||
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
left: 75%;
|
||||
|
@ -60,8 +84,76 @@ div:hover > .pulldown {
|
|||
z-index: 1;
|
||||
}
|
||||
|
||||
.side {
|
||||
width: 110px;
|
||||
min-height: 40%;
|
||||
background-color: #0786BD;
|
||||
}
|
||||
|
||||
.side.right {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
padding: 8px;
|
||||
padding-left: 14px;
|
||||
border-left: 2px solid #0786BD;
|
||||
border-top: 2px solid #0786BD;
|
||||
border-bottom: 2px solid #0786BD;
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
.side.left {
|
||||
padding-right: 14px;
|
||||
border-right: 1px solid #0786BD;
|
||||
border-top: 1px solid #0786BD;
|
||||
border-bottom: 1px solid #0786BD;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
|
||||
background-color: #61c1fe;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
|
||||
transition: width 0.5s;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
padding: 10px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.slider * {
|
||||
visibility: hidden;
|
||||
}
|
||||
.slider:hover * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.slider.right {
|
||||
float: none;
|
||||
right: 0px;
|
||||
width: 90px;
|
||||
height: 22px;
|
||||
}
|
||||
.slider.right:hover {
|
||||
width: 600%;
|
||||
max-height: 1000%;
|
||||
}
|
||||
|
||||
.slider > div {
|
||||
|
||||
}
|
||||
|
||||
.slider > div > input {
|
||||
width: 160px;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
|
||||
.section {
|
||||
display: block;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.section > div {
|
||||
|
@ -84,22 +176,12 @@ div:hover > .pulldown {
|
|||
}
|
||||
|
||||
|
||||
.button, input, textarea {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border: 1px solid #202040;
|
||||
background-color: #E0E0FF;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.button.small {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 3px;
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
input.small {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
@ -114,6 +196,24 @@ textarea {
|
|||
display: block;
|
||||
}
|
||||
|
||||
.side > * {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100px;
|
||||
min-width: initial;
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
margin-bottom: 8px;
|
||||
|
||||
background-color: #61c1fe;
|
||||
color: white;
|
||||
|
||||
border: 1px solid #044357;
|
||||
border-radius: 4px;
|
||||
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
#menu {
|
||||
width: 90%;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
<%define node%>
|
||||
<div class="treenode">
|
||||
<div class="row">
|
||||
|
@ -8,6 +7,7 @@
|
|||
<%end%>
|
||||
<div class="button small">
|
||||
<div class="popup">
|
||||
Neues Objekt in <div class="bold"><%='/'.join([x._aq_name for x in node._aq_path])%></div> erstellen.
|
||||
<select size="1" id="objTypeName-<%=node._persistence_id()%>">
|
||||
<%iterate ot node.wo_accepts()%>
|
||||
<option value="<%='{0}.{1}'.format(ot.__module__,ot.__name__)%>"><%=ot.__name__%></option>
|
||||
|
|
|
@ -438,6 +438,8 @@ class Template(WebCallable):
|
|||
log("Template missing for <%include ...%>")
|
||||
|
||||
def findTemplate(self, expr):
|
||||
log("findTemplate({0})".format(expr))
|
||||
|
||||
if isinstance(expr, Template):
|
||||
return expr
|
||||
elif isinstance(expr[0], Template):
|
||||
|
@ -445,7 +447,7 @@ class Template(WebCallable):
|
|||
elif (not self.__provider is None) and (expr[0] in self.__provider):
|
||||
return self.__provider.provide( expr[0] )
|
||||
else:
|
||||
log("Template missing for <%include ...%>")
|
||||
log("Template missing for <%frame ...%>")
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -33,13 +33,16 @@ function saveSource(){
|
|||
|
||||
|
||||
</script>
|
||||
<div class="section">
|
||||
<div class="section-title">Quelltext</div>
|
||||
<div id="preview">
|
||||
<iframe id="preview-frame" name="preview" src=""></iframe>
|
||||
</div>
|
||||
|
||||
<textarea id="dpage_source" name="source" oninput="sourcechanged();"><%=self.source()%></textarea><br/>
|
||||
|
||||
<div id="preview">
|
||||
<iframe id="preview-frame" name="preview" src=""></iframe>
|
||||
</div>
|
||||
|
||||
<textarea id="dpage_source" name="source" oninput="sourcechanged();"><%=self.source()%></textarea><br/>
|
||||
|
||||
<script type="text/javascript">
|
||||
editorDeclareControl($("dpage_source"));
|
||||
</script>
|
||||
|
|
|
@ -15,7 +15,7 @@ class FormApplyable:
|
|||
|
||||
FA_Names = {}
|
||||
|
||||
def formApply(self,request):
|
||||
def formApply(self,request,o):
|
||||
fa_names = self.__collectNames()
|
||||
|
||||
for name in fa_names:
|
||||
|
@ -23,12 +23,13 @@ class FormApplyable:
|
|||
if fa_attr in request.form():
|
||||
oval = getattr( self, name, None)
|
||||
|
||||
log("formApply(): {0} = {1}".format( name, oval ))
|
||||
log("formApply(): {3} {0} = {1} : {2}".format( name, oval, request.form()[ fa_attr ].value(), o ))
|
||||
|
||||
if callable( oval ):
|
||||
log("call-intf")
|
||||
oval( request.form()[ fa_attr ].value() )
|
||||
else:
|
||||
setattr( self, name, request.form()[ fa_attr ].value())
|
||||
setattr( self, name, request.form()[ fa_attr ].value() )
|
||||
|
||||
|
||||
def __collectNames(self):
|
||||
|
@ -43,6 +44,6 @@ class FormApplyable:
|
|||
return fa_names
|
||||
|
||||
def __apply(self,request, o = None):
|
||||
self.formApply(request)
|
||||
self.formApply(request,o)
|
||||
|
||||
_hm_apply = WebCallable( method = __apply )
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit b0ab3694e3903b178a57b1ba95d7a8932671d828
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 729bbd81d755b830e6562ea52e006297511a15b6
|
Loading…
Reference in New Issue