forked from Botanical/BotanJS
Compare commits
No commits in common. "Astro" and "master" have entirely different histories.
@ -1,17 +0,0 @@
|
|||||||
.dockerignore
|
|
||||||
.git
|
|
||||||
.gitignore
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
*.pyc
|
|
||||||
Dockerfile
|
|
||||||
k8s/
|
|
||||||
cache/
|
|
||||||
image/
|
|
||||||
concourse/
|
|
||||||
k8s/
|
|
||||||
windows/
|
|
||||||
__pycache__
|
|
||||||
cache/*
|
|
||||||
logs/*
|
|
||||||
env/*
|
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
.DS_Store
|
|
||||||
*~
|
*~
|
||||||
*.swp
|
*.swp
|
||||||
*.pyc
|
*.pyc
|
||||||
|
24
Dockerfile
24
Dockerfile
@ -1,24 +0,0 @@
|
|||||||
FROM alpine:3.15.3
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
RUN mkdir -p /opt/utils
|
|
||||||
|
|
||||||
RUN apk add --update bash python3 uwsgi uwsgi-python openjdk11-jre-headless; python3 -m ensurepip
|
|
||||||
|
|
||||||
RUN echo "www-data:x:1001:1001:www-data:/var/www:/usr/sbin/nologin" >> /etc/passwd; echo "www-data:x:1001:" >> /etc/group
|
|
||||||
|
|
||||||
RUN pip3 install Flask redis compressinja Celery
|
|
||||||
|
|
||||||
ADD [ "https://github.com/tgckpg/BotanJS/releases/download/compressors/closure.jar" \
|
|
||||||
, "https://github.com/tgckpg/BotanJS/releases/download/compressors/yuicompressor.jar" \
|
|
||||||
, "/opt/utils/" ]
|
|
||||||
|
|
||||||
COPY . /app/
|
|
||||||
|
|
||||||
RUN chmod 644 /opt/utils/*.jar; \
|
|
||||||
chown www-data:www-data . -R
|
|
||||||
|
|
||||||
USER www-data
|
|
||||||
|
|
||||||
EXPOSE 5000
|
|
||||||
ENTRYPOINT ["setup/docker.start"]
|
|
29
README.md
29
README.md
@ -1,11 +1,8 @@
|
|||||||
# AstroJS for Blog
|
# BotanJS
|
||||||
[](https://build.s.k8s.astropenguin.net/teams/main/pipelines/astrojs)
|
A working concept of Js/Css framework for web browsers
|
||||||
|
|
||||||
The current backend Js/Css services for [my blog](https://blog.astropenguin.net)
|
### Showcase
|
||||||
|
- Pending
|
||||||
### Try it - Docker for windows (using windows container with nanoserver)
|
|
||||||
- docker -f windows/docker-compose.yml build
|
|
||||||
- docker -f windows/docker-compose.yml up
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
- Compressable by Closure Compiler (Advanced Compression)
|
- Compressable by Closure Compiler (Advanced Compression)
|
||||||
@ -13,13 +10,29 @@ The current backend Js/Css services for [my blog](https://blog.astropenguin.net)
|
|||||||
- Everything is merged into one file for that page
|
- Everything is merged into one file for that page
|
||||||
- css class inheritance
|
- css class inheritance
|
||||||
|
|
||||||
|
### Disclaimer
|
||||||
|
- This is a working concept. So it works on me. And may have a bunch of useless dependency. Use at your own risks!
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
- Will be added later
|
- Will be added later
|
||||||
|
|
||||||
### Prerequisties
|
### Prerequisties
|
||||||
- python3
|
- python3
|
||||||
- virtualenv ( optional )
|
- virtualenv
|
||||||
|
|
||||||
|
#### For Service.WebAPI
|
||||||
- pip install Flask
|
- pip install Flask
|
||||||
- pip install Celery
|
- pip install Celery
|
||||||
- pip install redis
|
- pip install redis
|
||||||
- pip install compressinja
|
- pip install compressinja
|
||||||
|
|
||||||
|
### Before start, run
|
||||||
|
```
|
||||||
|
virtualenv env
|
||||||
|
./botan-rebuild
|
||||||
|
```
|
||||||
|
|
||||||
|
#### To start just run ( in virtualenv )
|
||||||
|
```
|
||||||
|
./botan-start
|
||||||
|
```
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python3
|
#!env/bin/python
|
||||||
import os, sys
|
import os, sys
|
||||||
sys.path.append( os.path.abspath( "." ) )
|
sys.path.append( os.path.abspath( "." ) )
|
||||||
|
|
||||||
@ -8,10 +8,10 @@ from botanjs.config import Config as config
|
|||||||
SiteRoot = os.path.abspath( "." )
|
SiteRoot = os.path.abspath( "." )
|
||||||
|
|
||||||
# Setting the SiteRoot for config
|
# Setting the SiteRoot for config
|
||||||
config["Paths"]["SiteRoot"] = SiteRoot
|
config["Paths"]["SiteRoot"] = SiteRoot;
|
||||||
|
|
||||||
bmap = os.path.join( config["Paths"]["Cache"], "botanjs", "bmap.xml" )
|
bmap = os.path.join( config["Paths"]["Cache"], "botanjs", "bmap.xml" )
|
||||||
|
|
||||||
app.conf.update( broker_url = config["BotanJS"]["CeleryBroker"] )
|
app.conf.update( BROKER_URL = config["BotanJS"]["CeleryBroker"] )
|
||||||
|
|
||||||
JWork.buildClassMap.delay( config["BotanJS"]["SrcDir"], bmap )
|
JWork.buildClassMap.delay( config["BotanJS"]["SrcDir"], bmap )
|
||||||
|
57
botan-start.py
Executable file
57
botan-start.py
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
#!env/bin/python
|
||||||
|
|
||||||
|
import os, sys
|
||||||
|
from botanjs.config import Config as config, DEBUG
|
||||||
|
from subprocess import Popen
|
||||||
|
from botanjs.service.webapi import WebAPI
|
||||||
|
|
||||||
|
SiteRoot = os.path.abspath( "." )
|
||||||
|
|
||||||
|
# Setting the SiteRoot for config
|
||||||
|
config["Paths"]["SiteRoot"] = SiteRoot;
|
||||||
|
|
||||||
|
# Create the lock folder for celery
|
||||||
|
lockDir = os.path.join( SiteRoot, "env", "var", "run", "celery" )
|
||||||
|
|
||||||
|
os.makedirs( lockDir, exist_ok=True )
|
||||||
|
|
||||||
|
sys.path.append( os.path.abspath( "." ) )
|
||||||
|
|
||||||
|
RUNTIME_ENV = os.path.abspath( os.path.join( "env", "bin" ) )
|
||||||
|
if RUNTIME_ENV not in os.environ[ "PATH" ]:
|
||||||
|
os.environ[ "PATH" ] = RUNTIME_ENV + os.pathsep + os.environ[ "PATH" ]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
jwork = "botanjs.service.jwork"
|
||||||
|
nodeName = "botanNode1"
|
||||||
|
|
||||||
|
celOut = open( os.path.join( config["Paths"]["Log"], jwork + "-err.log" ), "a+" )
|
||||||
|
cel = Popen(
|
||||||
|
[
|
||||||
|
"celery", "multi", "restart", nodeName
|
||||||
|
, "-A", jwork, "worker"
|
||||||
|
, "--pidfile=" + os.path.join( lockDir, jwork + ".pid" )
|
||||||
|
, "--logfile=" + os.path.join( config["Paths"]["Log"], jwork + ".log" )
|
||||||
|
, "--workdir=" + config["Paths"]["Runtime"]
|
||||||
|
, "beat", "-l", "info"
|
||||||
|
]
|
||||||
|
, stdout = celOut
|
||||||
|
, stderr = celOut
|
||||||
|
)
|
||||||
|
|
||||||
|
celOut.close()
|
||||||
|
|
||||||
|
if not DEBUG and os.fork():
|
||||||
|
import logging
|
||||||
|
logging.basicConfig(
|
||||||
|
filename = os.path.join( config["Paths"]["Log"], "access.log" )
|
||||||
|
, level = logging.DEBUG
|
||||||
|
)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
WebAPI(
|
||||||
|
jsCache = config["Paths"]["Cache"]
|
||||||
|
, jsRoot = config["BotanJS"]["SrcDir"]
|
||||||
|
, brokerURL = config["BotanJS"]["CeleryBroker"]
|
||||||
|
)
|
@ -1,15 +1,12 @@
|
|||||||
import os, re, sys
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os;
|
||||||
|
import re;
|
||||||
|
import sys;
|
||||||
|
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from botanjs.config import DEBUG
|
|
||||||
|
|
||||||
if DEBUG:
|
|
||||||
from botanjs.utils import checksum_r as checksum
|
|
||||||
else:
|
|
||||||
from botanjs.utils import checksum
|
|
||||||
|
|
||||||
RegEx_N = re.compile( r"""
|
RegEx_N = re.compile( r"""
|
||||||
.*
|
.*
|
||||||
__namespace
|
__namespace
|
||||||
@ -139,7 +136,7 @@ class ClassMap:
|
|||||||
|
|
||||||
return True;
|
return True;
|
||||||
|
|
||||||
def drawMap( self, ns, ci, ce, cf, chksum ):
|
def drawMap( self, ns, ci, ce, cf ):
|
||||||
nsNode = self.getNode( ns )
|
nsNode = self.getNode( ns )
|
||||||
|
|
||||||
# Source every:
|
# Source every:
|
||||||
@ -153,8 +150,6 @@ class ClassMap:
|
|||||||
|
|
||||||
if not srcEvery:
|
if not srcEvery:
|
||||||
nsNode.setAttribute( "src", cf )
|
nsNode.setAttribute( "src", cf )
|
||||||
nsNode.setAttribute( "js", chksum["js"] )
|
|
||||||
nsNode.setAttribute( "css", chksum["css"] )
|
|
||||||
|
|
||||||
for ex in ce:
|
for ex in ce:
|
||||||
_t = eDef[ ex[0] ]
|
_t = eDef[ ex[0] ]
|
||||||
@ -169,8 +164,6 @@ class ClassMap:
|
|||||||
cNode.appendChild( impNode )
|
cNode.appendChild( impNode )
|
||||||
|
|
||||||
cNode.setAttribute( "src", cf )
|
cNode.setAttribute( "src", cf )
|
||||||
cNode.setAttribute( "js", chksum["js"] )
|
|
||||||
cNode.setAttribute( "css", chksum["css"] )
|
|
||||||
|
|
||||||
# the file dose not export classes
|
# the file dose not export classes
|
||||||
# Hence it import for itself
|
# Hence it import for itself
|
||||||
@ -194,11 +187,7 @@ class ClassMap:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
ns, ci, ce = classMeta( classFile )
|
ns, ci, ce = classMeta( classFile )
|
||||||
|
|
||||||
chksum = {}
|
|
||||||
chksum[ "js" ] = checksum( classFile )
|
|
||||||
chksum[ "css" ] = checksum( classFile[:-2] + "css" )
|
|
||||||
|
|
||||||
classFile = classFile.replace( self.R + os.path.sep, "" )
|
classFile = classFile.replace( self.R + os.path.sep, "" )
|
||||||
self.drawMap( ns, ci, ce, classFile, chksum )
|
self.drawMap( ns, ci, ce, classFile )
|
||||||
return self.DOM.toxml()
|
return self.DOM.toxml()
|
||||||
|
|
||||||
|
16
botanjs/compressor/closure.py
Normal file → Executable file
16
botanjs/compressor/closure.py
Normal file → Executable file
@ -1,14 +1,13 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from sys import platform
|
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
from botanjs.config import Config as config
|
from botanjs.config import Config as config
|
||||||
from botanjs.service.jwork import log
|
|
||||||
|
|
||||||
COMPILER = config[ "BotanJS" ][ "ClosureCompiler" ]
|
COMPILER = config[ "BotanJS" ][ "ClosureCompiler" ]
|
||||||
|
|
||||||
AVAILABLE = os.path.isfile( COMPILER )
|
if not os.path.isfile( COMPILER ):
|
||||||
|
raise Exception( "Compiler not found" )
|
||||||
|
|
||||||
|
|
||||||
COMPILER_OPTIONS = [
|
COMPILER_OPTIONS = [
|
||||||
@ -24,7 +23,7 @@ class Wrapper:
|
|||||||
E = ""
|
E = ""
|
||||||
|
|
||||||
def __init__( self ):
|
def __init__( self ):
|
||||||
self.C = "java -jar -Xmx64M "+ COMPILER + " " + " ".join( COMPILER_OPTIONS )
|
self.C = "java -jar "+ COMPILER + " " + " ".join( COMPILER_OPTIONS )
|
||||||
|
|
||||||
def scanExterns( self, sdir ):
|
def scanExterns( self, sdir ):
|
||||||
for root, dirs, files in os.walk( sdir ):
|
for root, dirs, files in os.walk( sdir ):
|
||||||
@ -42,15 +41,12 @@ class Wrapper:
|
|||||||
break
|
break
|
||||||
|
|
||||||
def compress( self, loc ):
|
def compress( self, loc ):
|
||||||
|
|
||||||
if not AVAILABLE:
|
|
||||||
log.error( "Compiler not found" )
|
|
||||||
return
|
|
||||||
|
|
||||||
content = ""
|
content = ""
|
||||||
with open( loc, "rb" ) as f:
|
with open( loc, "rb" ) as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
with NamedTemporaryFile( delete = ( not platform == "win32" ) ) as f:
|
with NamedTemporaryFile() as f:
|
||||||
f.write( content[12:-5] )
|
f.write( content[12:-5] )
|
||||||
os.system( self.C + self.E + " --js " + f.name + " --js_output_file " + loc[:-3] + ".c.js" )
|
os.system( self.C + self.E + " --js " + f.name + " --js_output_file " + loc[:-3] + ".c.js" )
|
||||||
|
|
||||||
|
|
||||||
|
6
botanjs/compressor/yui.py
Normal file → Executable file
6
botanjs/compressor/yui.py
Normal file → Executable file
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from sys import platform
|
|
||||||
from botanjs.config import Config as config
|
from botanjs.config import Config as config
|
||||||
|
|
||||||
COMPILER = config[ "BotanJS" ][ "YuiCompressor" ]
|
COMPILER = config[ "BotanJS" ][ "YuiCompressor" ]
|
||||||
@ -21,8 +20,5 @@ class Wrapper:
|
|||||||
self.C = "java -jar " + COMPILER + " " + " ".join( COMPILER_OPTIONS )
|
self.C = "java -jar " + COMPILER + " " + " ".join( COMPILER_OPTIONS )
|
||||||
|
|
||||||
def compress( self, loc ):
|
def compress( self, loc ):
|
||||||
|
|
||||||
if platform == "win32":
|
|
||||||
loc = loc.replace( "C:", "" ).replace( "\\\\", "/" )
|
|
||||||
|
|
||||||
os.system( self.C + " " + loc + " -o " + loc[:-4] + ".c.css" )
|
os.system( self.C + " " + loc + " -o " + loc[:-4] + ".c.css" )
|
||||||
|
|
||||||
|
12
botanjs/config.py
Normal file → Executable file
12
botanjs/config.py
Normal file → Executable file
@ -1,15 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import configparser, os
|
import configparser
|
||||||
|
|
||||||
Config = configparser.ConfigParser( interpolation = configparser.ExtendedInterpolation() )
|
Config = configparser.ConfigParser( interpolation = configparser.ExtendedInterpolation() )
|
||||||
Config.read( "settings.ini" )
|
Config.read( "settings.ini" )
|
||||||
|
|
||||||
DEBUG = os.getenv( "DEBUG" )
|
DEBUG = Config[ "Env" ][ "Debug" ]
|
||||||
if DEBUG is None:
|
|
||||||
DEBUG = Config.getboolean( "Env", "Debug" )
|
|
||||||
else:
|
|
||||||
Config[ "Env" ][ "Debug" ] = str( DEBUG == "1" )
|
|
||||||
|
|
||||||
REDIS_CONN = os.getenv( "REDIS_CONN" )
|
|
||||||
if not REDIS_CONN is None:
|
|
||||||
Config[ "Redis" ][ "ConnStr" ] = REDIS_CONN
|
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
class log:
|
class log:
|
||||||
|
def info( self, *args ):
|
||||||
@staticmethod
|
|
||||||
def info( *args ):
|
|
||||||
print( *args )
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def error( *args ):
|
|
||||||
print( *args )
|
print( *args )
|
||||||
|
|
||||||
class dummyTask( object ):
|
class dummyTask( object ):
|
||||||
@ -24,7 +18,7 @@ class dummyTask( object ):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class dummyConf:
|
class dummyConf:
|
||||||
def update( self, broker_url = None ):
|
def update( self, BROKER_URL = None ):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class app:
|
class app:
|
||||||
|
@ -16,11 +16,8 @@ class Resolver:
|
|||||||
EX_FUNC = "method"
|
EX_FUNC = "method"
|
||||||
EX_CLASS = "class"
|
EX_CLASS = "class"
|
||||||
|
|
||||||
_rLookup = None
|
|
||||||
|
|
||||||
def __init__( self, classMap ):
|
def __init__( self, classMap ):
|
||||||
self.classMap = classMap
|
self.classMap = classMap
|
||||||
self._rLookup = {}
|
|
||||||
self._reload()
|
self._reload()
|
||||||
|
|
||||||
def _reload( self ):
|
def _reload( self ):
|
||||||
@ -33,23 +30,13 @@ class Resolver:
|
|||||||
|
|
||||||
def resource( self, elem ):
|
def resource( self, elem ):
|
||||||
if "src" in elem.attrib:
|
if "src" in elem.attrib:
|
||||||
key = elem.attrib[ "src" ]
|
return elem.attrib[ "src" ]
|
||||||
if not key in self._rLookup:
|
|
||||||
self._rLookup[ key ] = {
|
|
||||||
"src": elem.attrib[ "src" ]
|
|
||||||
, "js": elem.attrib[ "js" ]
|
|
||||||
, "css": elem.attrib[ "css" ]
|
|
||||||
}
|
|
||||||
return self._rLookup[ key ]
|
|
||||||
|
|
||||||
parent = self.parentMap[ elem ]
|
parent = self.parentMap[ elem ]
|
||||||
|
|
||||||
if parent is not None:
|
if parent != None:
|
||||||
return self.resource( parent )
|
return self.resource( parent )
|
||||||
|
|
||||||
def locate( self, key ):
|
|
||||||
return self._rLookup.get( key )
|
|
||||||
|
|
||||||
def resolve( self, c, classList ):
|
def resolve( self, c, classList ):
|
||||||
self.resolved = []
|
self.resolved = []
|
||||||
self.__resolve( c, classList )
|
self.__resolve( c, classList )
|
||||||
@ -112,9 +99,7 @@ class BotanClassResolver:
|
|||||||
|
|
||||||
classMap = ""
|
classMap = ""
|
||||||
flagCompress = True
|
flagCompress = True
|
||||||
oModeIfSizelt = 50 * 1024
|
|
||||||
returnHash = False
|
returnHash = False
|
||||||
returnDynamic = False
|
|
||||||
resv = None
|
resv = None
|
||||||
|
|
||||||
def __init__( self, jwork, BotanRoot, classMap, cacheRoot ):
|
def __init__( self, jwork, BotanRoot, classMap, cacheRoot ):
|
||||||
@ -137,17 +122,12 @@ class BotanClassResolver:
|
|||||||
|
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def BotanCache( self, srcFile, fileHash, hashContentDynamic ):
|
def BotanCache( self, t ):
|
||||||
|
content = ""
|
||||||
|
with open( t, "r" ) as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
for _ in [0]:
|
return content
|
||||||
if hashContentDynamic and os.path.getsize( srcFile ) < self.oModeIfSizelt:
|
|
||||||
break
|
|
||||||
|
|
||||||
if self.returnHash:
|
|
||||||
return fileHash
|
|
||||||
|
|
||||||
with open( srcFile, "r" ) as f:
|
|
||||||
return f.read()
|
|
||||||
|
|
||||||
def cleanList( self, lista ):
|
def cleanList( self, lista ):
|
||||||
olist = []
|
olist = []
|
||||||
@ -166,35 +146,37 @@ class BotanClassResolver:
|
|||||||
if src not in classFiles:
|
if src not in classFiles:
|
||||||
classFiles.append( src )
|
classFiles.append( src )
|
||||||
|
|
||||||
def cssLookup( self, classList, cssList ):
|
def cssLookup( self, jsList, cssList ):
|
||||||
|
|
||||||
for cdef in classList:
|
for f in jsList:
|
||||||
f = cdef[ "src" ]
|
possibleList = []
|
||||||
|
|
||||||
cssFile = os.path.splitext( f )[0] + ".css"
|
cssFile = os.path.splitext( f )[0] + ".css"
|
||||||
|
|
||||||
cssGroup = []
|
if cssFile not in possibleList:
|
||||||
if not cdef[ "css" ] == "1":
|
possibleList.append( cssFile )
|
||||||
cssGroup.append( cdef )
|
|
||||||
|
|
||||||
f = f.split( PY_SEP )
|
f = f.split( PY_SEP )
|
||||||
l = len( f )
|
l = len( f )
|
||||||
|
|
||||||
for i in range( 1, l ):
|
for i in range( 1, l ):
|
||||||
key = PY_SEP.join( x for x in f[:-i] ) + PY_SEP + "_this.js"
|
cssFile = PY_SEP.join( x for x in f[:-i] ) + PY_SEP + "@_this.css"
|
||||||
_def = self.resv.locate( key )
|
if cssFile not in possibleList:
|
||||||
|
possibleList.append( cssFile )
|
||||||
|
|
||||||
if _def and not _def[ "css" ] == "1":
|
possibleList.sort()
|
||||||
cssGroup.append( _def )
|
|
||||||
|
for f in possibleList:
|
||||||
|
f = f.replace( "@_this.css", "_this.css" )
|
||||||
|
if os.path.exists( os.path.join( self.R, f ) ):
|
||||||
|
cssList.append( f )
|
||||||
|
|
||||||
cssGroup.sort( key = lambda x : x[ "src" ] )
|
|
||||||
cssList.extend( cssGroup )
|
|
||||||
|
|
||||||
def getCache( self, fileList, cName, mode ):
|
def getCache( self, fileList, cName, mode ):
|
||||||
if self.CR == None:
|
if self.CR == None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
md5 = hashlib.md5( bytearray( "|".join( x[mode] for x in fileList ), "utf-8" ) ).hexdigest()
|
md5 = hashlib.md5( bytearray( "".join( fileList ), "utf-8" ) ).hexdigest()
|
||||||
|
|
||||||
cName[0] = oFHash = md5 + "." + mode
|
cName[0] = oFHash = md5 + "." + mode
|
||||||
cFHash = md5 + ".c." + mode
|
cFHash = md5 + ".c." + mode
|
||||||
@ -204,14 +186,19 @@ class BotanClassResolver:
|
|||||||
# Compressed file
|
# Compressed file
|
||||||
cFile = os.path.join( self.CR, cFHash )
|
cFile = os.path.join( self.CR, cFHash )
|
||||||
|
|
||||||
cCached = self.useCache( cFile )
|
dates = list(
|
||||||
|
os.path.getmtime( os.path.join( self.R, x ) )
|
||||||
|
if os.path.exists( os.path.join( self.R, x ) ) else -1
|
||||||
|
for x in fileList
|
||||||
|
)
|
||||||
|
|
||||||
if self.flagCompress and cCached:
|
# Root file date
|
||||||
return self.BotanCache( cFile, cFHash, self.returnDynamic )
|
dates.append( os.path.getmtime( os.path.join( self.R, "_this.js" ) ) );
|
||||||
|
|
||||||
if self.useCache( oFile ):
|
if self.flagCompress and self.useCache( cFile, dates ):
|
||||||
|
return cFHash if self.returnHash else self.BotanCache( cFile )
|
||||||
|
|
||||||
if not cCached:
|
elif self.useCache( oFile, dates ):
|
||||||
self.JWork.saveCache(
|
self.JWork.saveCache(
|
||||||
oFile
|
oFile
|
||||||
# Content is None to initiate a compression
|
# Content is None to initiate a compression
|
||||||
@ -220,12 +207,19 @@ class BotanClassResolver:
|
|||||||
, os.path.join( self.R, "externs" )
|
, os.path.join( self.R, "externs" )
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.BotanCache( oFile, oFHash, False )
|
return oFHash if self.returnHash else self.BotanCache( oFile )
|
||||||
|
|
||||||
return None
|
def useCache( self, f, dList ):
|
||||||
|
if not os.path.exists( f ):
|
||||||
|
return False
|
||||||
|
|
||||||
def useCache( self, f ):
|
t = os.path.getmtime( f )
|
||||||
return os.path.exists( f )
|
|
||||||
|
for i in dList:
|
||||||
|
if t < i:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def compileJs( self, cList, xList ):
|
def compileJs( self, cList, xList ):
|
||||||
md5 = [ None ]
|
md5 = [ None ]
|
||||||
@ -235,14 +229,14 @@ class BotanClassResolver:
|
|||||||
|
|
||||||
cacheFile = self.getCache( cList, md5, "js" )
|
cacheFile = self.getCache( cList, md5, "js" )
|
||||||
|
|
||||||
if cacheFile is not None:
|
if cacheFile != None:
|
||||||
return cacheFile;
|
return cacheFile;
|
||||||
|
|
||||||
# The root file
|
# The root file
|
||||||
outputJs = self.BotanFile( "_this.js" )
|
outputJs = self.BotanFile( "_this.js" )
|
||||||
|
|
||||||
|
|
||||||
for f in cList:
|
for f in cList:
|
||||||
f = f[ "src" ]
|
|
||||||
path = (
|
path = (
|
||||||
os.path.splitext( f )[0]
|
os.path.splitext( f )[0]
|
||||||
.replace( PY_SEP, "." )
|
.replace( PY_SEP, "." )
|
||||||
@ -254,7 +248,7 @@ class BotanClassResolver:
|
|||||||
|
|
||||||
outputJs = wrapScope( outputJs )
|
outputJs = wrapScope( outputJs )
|
||||||
|
|
||||||
self.JWork.saveCache(
|
[ self.JWork.saveCache if self.returnHash else self.JWork.saveCache ][0] (
|
||||||
os.path.join( self.CR, md5[0] )
|
os.path.join( self.CR, md5[0] )
|
||||||
, outputJs
|
, outputJs
|
||||||
, "js"
|
, "js"
|
||||||
@ -281,16 +275,17 @@ class BotanClassResolver:
|
|||||||
md5 = [ None ]
|
md5 = [ None ]
|
||||||
cacheFile = self.getCache( cList, md5, "css" )
|
cacheFile = self.getCache( cList, md5, "css" )
|
||||||
|
|
||||||
if cacheFile is not None:
|
if cacheFile != None:
|
||||||
return cacheFile;
|
return cacheFile;
|
||||||
|
|
||||||
struct = "/* @ */"
|
outputCss = ""
|
||||||
outputCss = struct + self.BotanFile( "_this.css" )
|
|
||||||
|
|
||||||
for f in self.cleanList( cList ):
|
for f in self.cleanList( cList ):
|
||||||
outputCss += self.BotanFile( f["src"][:-2] + "css" )
|
outputCss += self.BotanFile( f )
|
||||||
|
|
||||||
self.JWork.saveCache( os.path.join( self.CR, md5[0] ), outputCss, "css" )
|
[ self.JWork.saveCache if self.returnHash else self.JWork.saveCache ][0] (
|
||||||
|
os.path.join( self.CR, md5[0] ), outputCss, "css"
|
||||||
|
)
|
||||||
|
|
||||||
if self.returnHash:
|
if self.returnHash:
|
||||||
return md5[0]
|
return md5[0]
|
||||||
@ -304,26 +299,13 @@ class BotanClassResolver:
|
|||||||
flag = mode[0]
|
flag = mode[0]
|
||||||
requestAPIs = code
|
requestAPIs = code
|
||||||
|
|
||||||
# Return compressed contents if possible
|
|
||||||
# otherwise return raw contents
|
|
||||||
if flag == "o":
|
if flag == "o":
|
||||||
mode = mode[1:]
|
mode = mode[1:]
|
||||||
|
|
||||||
# Return raw contents only
|
|
||||||
elif flag == "r":
|
elif flag == "r":
|
||||||
mode = mode[1:]
|
mode = mode[1:]
|
||||||
self.flagCompress = False
|
self.flagCompress = False
|
||||||
|
|
||||||
# Return hashed filenames only
|
|
||||||
elif flag == "h":
|
|
||||||
mode = mode[1:]
|
|
||||||
self.returnHash = True
|
|
||||||
|
|
||||||
# Return hashed filenames if content is larger than self.oModeIfSizelt bytes
|
|
||||||
# otherwise act as "o" mode
|
|
||||||
else:
|
else:
|
||||||
self.returnHash = True
|
self.returnHash = True
|
||||||
self.returnDynamic = True
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
requestAPIs = (
|
requestAPIs = (
|
||||||
@ -347,8 +329,7 @@ class BotanClassResolver:
|
|||||||
|
|
||||||
for apis in requestAPIs:
|
for apis in requestAPIs:
|
||||||
|
|
||||||
if not apis:
|
if apis == None: continue
|
||||||
continue
|
|
||||||
|
|
||||||
classList = []
|
classList = []
|
||||||
lookupList = imports
|
lookupList = imports
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
|
from botanjs.compressor.closure import Wrapper as ClosureWrapper
|
||||||
|
from botanjs.compressor.yui import Wrapper as YUIWrapper
|
||||||
from botanjs.classmap import ClassMap
|
from botanjs.classmap import ClassMap
|
||||||
|
|
||||||
if os.getenv( "UNIT_TEST" ) == "1":
|
CeleryExists = True
|
||||||
CeleryExists = False
|
|
||||||
else:
|
|
||||||
CeleryExists = True
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from celery import Celery
|
from celery import Celery
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -19,7 +17,7 @@ if CeleryExists:
|
|||||||
|
|
||||||
if os.path.exists( "settings.ini" ):
|
if os.path.exists( "settings.ini" ):
|
||||||
from botanjs.config import Config
|
from botanjs.config import Config
|
||||||
app.conf.update( broker_url = Config["BotanJS"]["CeleryBroker"] )
|
app.conf.update( BROKER_URL = Config["BotanJS"]["CeleryBroker"] )
|
||||||
|
|
||||||
else:
|
else:
|
||||||
from botanjs.dummy import app
|
from botanjs.dummy import app
|
||||||
@ -36,11 +34,10 @@ class JWork:
|
|||||||
if mode == "js":
|
if mode == "js":
|
||||||
JWork.compressJs.delay( location, externs )
|
JWork.compressJs.delay( location, externs )
|
||||||
elif mode == "css":
|
elif mode == "css":
|
||||||
JWork.compressCss( location )
|
JWork.compressCss.delay( location )
|
||||||
|
|
||||||
@app.task()
|
@app.task()
|
||||||
def compressJs( md5, externs ):
|
def compressJs( md5, externs ):
|
||||||
from botanjs.compressor.closure import Wrapper as ClosureWrapper
|
|
||||||
log.info( "Compress js: " + md5 )
|
log.info( "Compress js: " + md5 )
|
||||||
w = ClosureWrapper()
|
w = ClosureWrapper()
|
||||||
w.scanExterns( externs )
|
w.scanExterns( externs )
|
||||||
@ -48,7 +45,6 @@ class JWork:
|
|||||||
|
|
||||||
@app.task()
|
@app.task()
|
||||||
def compressCss( md5 ):
|
def compressCss( md5 ):
|
||||||
from botanjs.compressor.yui import Wrapper as YUIWrapper
|
|
||||||
log.info( "Compress css: " + md5 )
|
log.info( "Compress css: " + md5 )
|
||||||
w = YUIWrapper()
|
w = YUIWrapper()
|
||||||
w.compress( md5 )
|
w.compress( md5 )
|
||||||
@ -58,6 +54,5 @@ class JWork:
|
|||||||
log.info( "Building Class Map" )
|
log.info( "Building Class Map" )
|
||||||
c = ClassMap( src )
|
c = ClassMap( src )
|
||||||
|
|
||||||
os.makedirs( os.path.dirname( location ), exist_ok = True )
|
|
||||||
with open( location, "w" ) as f:
|
with open( location, "w" ) as f:
|
||||||
f.write( c.build() )
|
f.write( c.build() )
|
||||||
|
20
botanjs/service/webapi.py
Normal file → Executable file
20
botanjs/service/webapi.py
Normal file → Executable file
@ -1,10 +1,11 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask import Response
|
from flask import Response
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from flask import request
|
from flask import request
|
||||||
from botanjs.service.jclassresv import BotanClassResolver as JCResv
|
from botanjs.service.jclassresv import BotanClassResolver as JCResv
|
||||||
from botanjs.service.jwork import app as CeleryApp, JWork
|
from botanjs.service.jwork import app as CeleryApp, JWork
|
||||||
from botanjs.config import Config
|
from botanjs.config import Config, DEBUG
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -23,28 +24,25 @@ class WebAPI:
|
|||||||
self.BMap = os.path.join( self.BCache, "bmap.xml" )
|
self.BMap = os.path.join( self.BCache, "bmap.xml" )
|
||||||
|
|
||||||
if brokerURL != None:
|
if brokerURL != None:
|
||||||
CeleryApp.conf.update( broker_url = brokerURL )
|
CeleryApp.conf.update( BROKER_URL = brokerURL )
|
||||||
|
|
||||||
self.app = Flask( __name__, static_url_path = "/cache/botanjs", static_folder = self.BCache )
|
self.app = Flask( __name__, static_url_path = self.BCache, static_folder = self.BCache )
|
||||||
self.app.jinja_env.add_extension( "compressinja.html.HtmlCompressor" )
|
self.app.jinja_env.add_extension( "compressinja.html.HtmlCompressor" )
|
||||||
|
|
||||||
self.app.add_url_rule( "/" , view_func = self.index )
|
self.app.add_url_rule( "/" , view_func = self.index )
|
||||||
self.app.add_url_rule( "/<mode>/" , view_func = lambda mode: self.api_request( mode, "zpayload" ) )
|
self.app.add_url_rule( "/<mode>/" , view_func = lambda mode: self.api_request( mode, "zpayload" ) )
|
||||||
self.app.add_url_rule( "/<mode>/<path:code>" , view_func = self.api_request )
|
self.app.add_url_rule( "/<mode>/<path:code>" , view_func = self.api_request )
|
||||||
|
|
||||||
def run( self, *args, **kwargs ):
|
self.app.run(
|
||||||
JWork.buildClassMap( self.BRoot, self.BMap )
|
host = Config[ "Service" ][ "BindAddress" ]
|
||||||
return self.app.run( *args, **kwargs )
|
, port = int( Config[ "Service" ][ "Port" ] )
|
||||||
|
, debug = DEBUG )
|
||||||
|
|
||||||
def index( self ):
|
def index( self ):
|
||||||
return "Hello, this is the BotanJS Service API.", 200
|
return "Hello, this is the BotanJS Service API.", 200
|
||||||
|
|
||||||
def api_request( self, mode, code ):
|
def api_request( self, mode, code ):
|
||||||
|
|
||||||
if mode == "rebuild":
|
|
||||||
JWork.buildClassMap.delay( self.BRoot, self.BMap )
|
|
||||||
return "OK", 200
|
|
||||||
|
|
||||||
if code == "zpayload":
|
if code == "zpayload":
|
||||||
code = request.args.get( "p" )
|
code = request.args.get( "p" )
|
||||||
|
|
||||||
@ -58,8 +56,6 @@ class WebAPI:
|
|||||||
srvHandler = JCResv( JWork, self.BRoot, self.BMap, self.BCache )
|
srvHandler = JCResv( JWork, self.BRoot, self.BMap, self.BCache )
|
||||||
return Response( srvHandler.getAPI( code, mode = mode ), mimetype = t )
|
return Response( srvHandler.getAPI( code, mode = mode ), mimetype = t )
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self.app.config[ "DEBUG" ]:
|
|
||||||
raise
|
|
||||||
return str(e), 404
|
return str(e), 404
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,554 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.utils} */
|
|
||||||
var utils = __import( "System.utils" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMObject} */
|
|
||||||
var IDOMObject = __import( "Dandelion.IDOMObject" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {Astro.Blog.Components.Bubble} */
|
|
||||||
var Bubble = __import( "Astro.Blog.Components.Bubble" );
|
|
||||||
|
|
||||||
var opostData = __import( "System.Net.postData" );
|
|
||||||
var prettyDate = __import( "Astro.utils.Date.pretty" );
|
|
||||||
|
|
||||||
var Visualizer = ns[ NS_INVOKE ]( "Visualizer" );
|
|
||||||
var Flag = ns[ NS_INVOKE ]( "Flag" );
|
|
||||||
|
|
||||||
|
|
||||||
// Editor Override
|
|
||||||
var postData = function( processor, data, success, failed )
|
|
||||||
{
|
|
||||||
data[ "editor" ] = 1;
|
|
||||||
opostData( processor, data, success, failed );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wrappers for every plugins
|
|
||||||
var PluginBundles = function( article, plugins )
|
|
||||||
{
|
|
||||||
this.plugins = plugins;
|
|
||||||
for( var i in this.plugins )
|
|
||||||
{
|
|
||||||
/* @type {Astro.Blog.AstroEdit.IPlugins} */
|
|
||||||
var g = this.plugins[i];
|
|
||||||
g.bindArticle = article;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PluginBundles.prototype.setForView = function( pluginId, data )
|
|
||||||
{
|
|
||||||
for( var i in this.plugins )
|
|
||||||
{
|
|
||||||
var p = this.plugins[i];
|
|
||||||
if( p.id == pluginId )
|
|
||||||
{
|
|
||||||
p.setForView( data );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PluginBundles.prototype.getData = function( pluginId, data )
|
|
||||||
{
|
|
||||||
for( var i in this.plugins )
|
|
||||||
{
|
|
||||||
var p = this.plugins[i];
|
|
||||||
if( p.id == pluginId )
|
|
||||||
{
|
|
||||||
return p.getData( data );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var Article = function( processorSet, plugins )
|
|
||||||
{
|
|
||||||
var pBubble = new Bubble();
|
|
||||||
|
|
||||||
var Draft = ns[ NS_INVOKE ]( "Draft" );
|
|
||||||
|
|
||||||
var _title = "";
|
|
||||||
var _content = "";
|
|
||||||
|
|
||||||
//// Classes & obj
|
|
||||||
var _visualizer = null;
|
|
||||||
var timestamp = new Date();
|
|
||||||
|
|
||||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
|
||||||
var ArticleModel = {
|
|
||||||
title: ""
|
|
||||||
, slug: ""
|
|
||||||
, content: ""
|
|
||||||
, date_modified: timestamp
|
|
||||||
, date_published: timestamp
|
|
||||||
, date_created: timestamp
|
|
||||||
, archived: false
|
|
||||||
, tags: null
|
|
||||||
, section: null
|
|
||||||
, draft: true
|
|
||||||
, article_id: false
|
|
||||||
};
|
|
||||||
|
|
||||||
var ae_content = Dand.id( "ae_content" );
|
|
||||||
var ae_title = Dand.id( "ae_title" );
|
|
||||||
|
|
||||||
// Article info
|
|
||||||
var ae_cdate = Dand.id( "ae_cdate" );
|
|
||||||
var ae_mdate = Dand.id( "ae_mdate" );
|
|
||||||
var ae_pdate = Dand.id( "ae_pdate" );
|
|
||||||
var ae_status = Dand.id( "ae_status" );
|
|
||||||
var ae_backup = Dand.id( "ae_backup_btn" );
|
|
||||||
var ae_publish = Dand.id( "ae_publish_btn" );
|
|
||||||
var ae_preview = Dand.id( "ae_preview" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.AstroEdit} */
|
|
||||||
var a_conf = Config.get( "AstroEdit" );
|
|
||||||
var base_path = utils.siteProto( Config.get( "BasePath" ) );
|
|
||||||
|
|
||||||
/*{{{ preview fields */
|
|
||||||
var ae_p_fields = {
|
|
||||||
mtime: set_field_name( Dand.wrap( "input" ), "date_modified" )
|
|
||||||
, ptime: set_field_name( Dand.wrap( "input" ), "date_published" )
|
|
||||||
, title: set_field_name( Dand.wrap( "input" ), "title" )
|
|
||||||
, content: set_field_name( Dand.wrap( "input" ), "content" )
|
|
||||||
, tags: set_field_name( Dand.wrap( "input" ), "tags" )
|
|
||||||
, section: set_field_name( Dand.wrap( "input" ), "section" )
|
|
||||||
};
|
|
||||||
|
|
||||||
// Initialize id
|
|
||||||
var __article_id = false;
|
|
||||||
var canSave = false;
|
|
||||||
|
|
||||||
var temp;
|
|
||||||
|
|
||||||
for ( var i in ae_p_fields ) ae_preview.appendChild( ae_p_fields[i] );
|
|
||||||
/* End preview fields }}}*/
|
|
||||||
|
|
||||||
/*{{{ Button sections */
|
|
||||||
var ae_stitles = Dand.glass( "ae_stitle", true );
|
|
||||||
var ae_panel_section = Dand.glass( "ae_panel_section", true );
|
|
||||||
|
|
||||||
var l = ae_stitles.length;
|
|
||||||
for( var i = 0; i < l; i ++ )
|
|
||||||
{
|
|
||||||
var t = ae_stitles[i];
|
|
||||||
var p = ae_panel_section[i];
|
|
||||||
// If they are snippets or sections
|
|
||||||
if( i == 2 || i == 3 )
|
|
||||||
{
|
|
||||||
p.style.height = "auto";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
t.addEventListener( "Click", function( e )
|
|
||||||
{
|
|
||||||
var p = this.p;
|
|
||||||
if( this.t.expanded = !this.t.expanded )
|
|
||||||
{
|
|
||||||
p.style.height = "auto";
|
|
||||||
Cycle.next(
|
|
||||||
function(){
|
|
||||||
p.style.height = this.h + "px";
|
|
||||||
}.bind({ h: p.element.clientHeight })
|
|
||||||
);
|
|
||||||
p.style.height = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p.style.height = 0;
|
|
||||||
}
|
|
||||||
}.bind({ t: t, p: p }) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ae_stitles[0].element.click();
|
|
||||||
/* End Button sections }}}*/
|
|
||||||
|
|
||||||
// Install plugins
|
|
||||||
plugins = new PluginBundles( this, plugins );
|
|
||||||
|
|
||||||
var enableSaveFunction = function ()
|
|
||||||
{
|
|
||||||
ae_backup.className = "ae_iValue ae_dodgerblue flsf";
|
|
||||||
canSave = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
, disableSaveFunction = function ()
|
|
||||||
{
|
|
||||||
ae_backup.className = "ae_iValue ae_disabled flsf";
|
|
||||||
canSave = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
, contentUpdate = function ()
|
|
||||||
{
|
|
||||||
if( !canSave ) enableSaveFunction();
|
|
||||||
// (_visualizer.saveRaw() != _content) ? enableSaveFunction() : disableSaveFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
//// private methods
|
|
||||||
////// Handlers ///////
|
|
||||||
|
|
||||||
, saveSuccess = function ( obj )
|
|
||||||
{
|
|
||||||
disableSaveFunction();
|
|
||||||
ae_mdate.innerHTML = prettyDate( new Date( obj.date_modified ) );
|
|
||||||
|
|
||||||
// Replace state of the content and title
|
|
||||||
ArticleModel.title = _title;
|
|
||||||
ArticleModel.content = _content;
|
|
||||||
ArticleModel.date_modified = obj.date_modified;
|
|
||||||
|
|
||||||
// If this is a published article
|
|
||||||
// we need to set the ref_id for ArticleModel
|
|
||||||
// then set current id to draft's id
|
|
||||||
if( ArticleModel.article_id != obj.article_id )
|
|
||||||
{
|
|
||||||
ArticleModel.draft = true;
|
|
||||||
ArticleModel.ref_id = __article_id;
|
|
||||||
ArticleModel.article_id = obj.article_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set article id if this is a new document
|
|
||||||
if ( obj.article_id )
|
|
||||||
ArticleModel.article_id = __article_id = obj.article_id;
|
|
||||||
|
|
||||||
window.history.replaceState( ArticleModel, "", base_path + "astroedit/" + __article_id + "/" );
|
|
||||||
}
|
|
||||||
|
|
||||||
, publishSuccess = function ( obj )
|
|
||||||
{
|
|
||||||
saveSuccess( obj );
|
|
||||||
|
|
||||||
ae_publish.innerHTML = "Done edit";
|
|
||||||
ae_backup.innerHTML = "Backup(Ctrl + s)";
|
|
||||||
|
|
||||||
ArticleModel.date_published = obj.date_published;
|
|
||||||
ae_pdate.innerHTML = prettyDate( new Date( obj.date_published ) );
|
|
||||||
|
|
||||||
this.contentUpdate && saveSuccess( obj );
|
|
||||||
|
|
||||||
new MessageBox(
|
|
||||||
"AstroEdit"
|
|
||||||
, "You have successfully published your article!"
|
|
||||||
, "Stay here", "Exit and goto article"
|
|
||||||
, publishAction
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, publishAction = function ( stay )
|
|
||||||
{
|
|
||||||
if ( !stay )
|
|
||||||
{
|
|
||||||
var op = window.open( base_path + "article/id-view/" + ArticleModel.article_id + "/" );
|
|
||||||
Cycle.next( function() {
|
|
||||||
if( op ) window.close();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, restoreArticle = function( obj )
|
|
||||||
{
|
|
||||||
debug.Info("[Document] Looking for stored data");
|
|
||||||
if ( obj )
|
|
||||||
{
|
|
||||||
debug.Info("[Document] .. data found");
|
|
||||||
// Set stored article id
|
|
||||||
__article_id = obj.article_id;
|
|
||||||
setArticle( obj );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!( ArticleModel && 0 < ArticleModel.article_id ))
|
|
||||||
{
|
|
||||||
debug.Info("[Document] .. data not found");
|
|
||||||
// This is a state of new article
|
|
||||||
var d = Math.floor(new Date().getTime()/1000);
|
|
||||||
__article_id = false;
|
|
||||||
setArticle({
|
|
||||||
title:""
|
|
||||||
, content:""
|
|
||||||
, date_modified: d
|
|
||||||
, date_published: 0
|
|
||||||
, date_created: d
|
|
||||||
, archived: false
|
|
||||||
, tags: null
|
|
||||||
, draft: true
|
|
||||||
, article_id: false
|
|
||||||
});
|
|
||||||
window.history.replaceState( ArticleModel, "", base_path + "astroedit/new/" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** @param {_AstJson_.AJaxGetArticle} */
|
|
||||||
, showArticle = function( obj )
|
|
||||||
{
|
|
||||||
if ( obj && obj.entry )
|
|
||||||
{
|
|
||||||
debug.Info( "[Document] Article Loaded" );
|
|
||||||
if ( obj.entry.ref_id )
|
|
||||||
{
|
|
||||||
// This is a backup item
|
|
||||||
__article_id = obj.article_id;
|
|
||||||
|
|
||||||
pBubble.setColor( "royalblue" );
|
|
||||||
pBubble.pop( "Using backup entry" );
|
|
||||||
Cycle.delay( function () { pBubble.blurp() }, 3000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
setArticle( obj.entry );
|
|
||||||
__statePusher( obj.entry, __article_id );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug.Info( "[Document] Article: " + String( __article_id ) + " not found on server." );
|
|
||||||
__article_id = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, setArticle = function ( entry )
|
|
||||||
{
|
|
||||||
ArticleModel = entry;
|
|
||||||
ae_title.value = _title = ArticleModel.title;
|
|
||||||
|
|
||||||
_visualizer.visualizeData( _content = ArticleModel.content );
|
|
||||||
|
|
||||||
ae_mdate.innerHTML = prettyDate( new Date( ArticleModel.date_modified ) );
|
|
||||||
ae_cdate.innerHTML = prettyDate( new Date( ArticleModel.date_created ) );
|
|
||||||
|
|
||||||
ae_pdate.innerHTML = ArticleModel.date_published
|
|
||||||
? prettyDate( new Date( ArticleModel.date_published ) )
|
|
||||||
: "Not published."
|
|
||||||
;
|
|
||||||
|
|
||||||
ae_status.innerHTML =
|
|
||||||
( ArticleModel.archived ? "Archived. " : "" )
|
|
||||||
+ ( ArticleModel.draft ? "In draft" : "Published" )
|
|
||||||
;
|
|
||||||
|
|
||||||
ae_publish.innerHTML = ArticleModel.draft ? "Publish" : "Done edit";
|
|
||||||
ae_backup.innerHTML = ( ArticleModel.draft ? "Save" : "Backup" ) + "(Ctrl + s)";
|
|
||||||
|
|
||||||
plugins.setForView( "tags", ArticleModel.tags );
|
|
||||||
plugins.setForView( "section", ArticleModel.section );
|
|
||||||
}
|
|
||||||
|
|
||||||
, deleteDraft = function ( confirmed )
|
|
||||||
{
|
|
||||||
if ( confirmed )
|
|
||||||
{
|
|
||||||
var _data = {
|
|
||||||
"draft": ArticleModel.draft ? 1 : 0
|
|
||||||
, "article_id": __article_id
|
|
||||||
, "del": 1
|
|
||||||
};
|
|
||||||
|
|
||||||
postData( processorSet, _data, deleteSuccess, serverFailed );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, deleteSuccess = function ( obj )
|
|
||||||
{
|
|
||||||
var loc = window.location;
|
|
||||||
loc.replace(
|
|
||||||
loc.href.replace(
|
|
||||||
"/" + ArticleModel.article_id
|
|
||||||
, ArticleModel.ref_id ? ( "/" + ArticleModel.ref_id ) : ""
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
, serverFailed = function ( obj )
|
|
||||||
{
|
|
||||||
pBubble.setColor( "red" );
|
|
||||||
pBubble.pop( obj ? obj["mesg"] : "Server Error" );
|
|
||||||
Cycle.delay( function () { pBubble.blurp() }, 3000 );
|
|
||||||
}
|
|
||||||
|
|
||||||
, contentEmpty = function ()
|
|
||||||
{
|
|
||||||
return !Boolean( ae_content.hasChildNodes() );
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
// Bind properties
|
|
||||||
|
|
||||||
this.saveOrBackup = function ()
|
|
||||||
{
|
|
||||||
if ( canSave )
|
|
||||||
{
|
|
||||||
// Store current content and title
|
|
||||||
_title = ae_title.value.trim();
|
|
||||||
_content = _visualizer.saveRaw();
|
|
||||||
|
|
||||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
|
||||||
var _data =
|
|
||||||
{
|
|
||||||
article_id: __article_id ? __article_id : ""
|
|
||||||
, title: _title
|
|
||||||
, content: _content
|
|
||||||
, draft: 1
|
|
||||||
, tags: plugins.getData( "tags" )
|
|
||||||
, section: plugins.getData( "section" )
|
|
||||||
};
|
|
||||||
|
|
||||||
postData( processorSet, _data, saveSuccess, serverFailed );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.load = function ( aid, statePusher )
|
|
||||||
{
|
|
||||||
if( aid && __article_id != aid )
|
|
||||||
{
|
|
||||||
debug.Info( "[Document] Loading article: " + aid );
|
|
||||||
__statePusher = statePusher;
|
|
||||||
postData(
|
|
||||||
a_conf.paths.get_article
|
|
||||||
, { article_id: __article_id = aid }
|
|
||||||
, showArticle
|
|
||||||
, serverFailed
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getArticleId = function () { return __article_id; }
|
|
||||||
|
|
||||||
this.preview = function ()
|
|
||||||
{
|
|
||||||
ae_p_fields.title.value = ae_title.value;
|
|
||||||
ae_p_fields.content.value = _visualizer.saveRaw();
|
|
||||||
ae_p_fields.mtime.value = ArticleModel.date_modified;
|
|
||||||
ae_p_fields.ptime.value = Number( ArticleModel.date_published )
|
|
||||||
? ArticleModel.date_published
|
|
||||||
: Math.floor( 0.001*( new Date().getTime() ) )
|
|
||||||
;
|
|
||||||
ae_p_fields.tags.value = plugins.getData( "tags" );
|
|
||||||
ae_p_fields.section.value = plugins.getData( "section" );
|
|
||||||
|
|
||||||
ae_preview.submit();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.invoke = function (_class)
|
|
||||||
{
|
|
||||||
if ( _class instanceof Draft ) _ae_draft = _class;
|
|
||||||
if ( _class instanceof Visualizer )
|
|
||||||
{
|
|
||||||
_visualizer = _class;
|
|
||||||
_visualizer.setContentDiv( ae_content );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveAndPublish = function ()
|
|
||||||
{
|
|
||||||
if ( contentEmpty() ) return;
|
|
||||||
|
|
||||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
|
||||||
var _data = {
|
|
||||||
article_id: __article_id ? __article_id : ""
|
|
||||||
, draft: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( !ArticleModel.draft )
|
|
||||||
{
|
|
||||||
// This is a published article
|
|
||||||
canSave = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( canSave )
|
|
||||||
{
|
|
||||||
// Store current content and title
|
|
||||||
_title = ae_title.value.trim();
|
|
||||||
_content = _visualizer.saveRaw();
|
|
||||||
|
|
||||||
_data.title = _title;
|
|
||||||
_data.content = _content;
|
|
||||||
_data.tags = plugins.getData( "tags" );
|
|
||||||
_data.section = plugins.getData( "section" );
|
|
||||||
|
|
||||||
postData( processorSet, _data, publishSuccess.bind({ contentUpdate: true }), serverFailed );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Do not submit uneccessary data!
|
|
||||||
postData( processorSet, _data, publishSuccess, serverFailed );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.drop = function ()
|
|
||||||
{
|
|
||||||
if( ArticleModel.draft )
|
|
||||||
{
|
|
||||||
new MessageBox(
|
|
||||||
"Delete draft"
|
|
||||||
, "Are you sure you want to delete this draft? (Published article will only remove backup draft.)"
|
|
||||||
, "Delete", "No"
|
|
||||||
, deleteDraft
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new MessageBox(
|
|
||||||
"Delete Draft"
|
|
||||||
, "There is no draft to delete"
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.updateContent = contentUpdate;
|
|
||||||
|
|
||||||
// Setting Ctrl+s functions
|
|
||||||
new IDOMObject(document).addEventListener(
|
|
||||||
new EventKey("KeyDown", function(e)
|
|
||||||
{
|
|
||||||
// key Ctrl(17)
|
|
||||||
if(e.ctrlKey == true && e.which == 83)
|
|
||||||
{
|
|
||||||
// key s (83)
|
|
||||||
this.saveOrBackup();
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
}.bind(this))
|
|
||||||
);
|
|
||||||
|
|
||||||
IDOMElement( ae_backup ).addEventListener( "Click", this.saveOrBackup );
|
|
||||||
|
|
||||||
window.addEventListener(
|
|
||||||
"popstate"
|
|
||||||
, function( event )
|
|
||||||
{
|
|
||||||
debug.Info( "[Document] Pop State fired" );
|
|
||||||
restoreArticle( event.state );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
ae_title.oninput = function ()
|
|
||||||
{
|
|
||||||
( ae_title.value != _title ) ? enableSaveFunction() : disableSaveFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = IDOMElement(ae_content);
|
|
||||||
|
|
||||||
temp.addEventListener( "Input", function() { enableSaveFunction(); } );
|
|
||||||
|
|
||||||
document.body.appendChild( pBubble.init() );
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
var set_field_name = function ( elem, value )
|
|
||||||
{
|
|
||||||
elem.name = value;
|
|
||||||
elem.type = "hidden";
|
|
||||||
return elem;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Article", Article );
|
|
||||||
})();
|
|
@ -1,158 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
/** @param {Astro.Blog.AstroEdit.Article} article */
|
|
||||||
var Draft = function ( article, draftsUri )
|
|
||||||
{
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Article} */
|
|
||||||
var Article = ns[ NS_INVOKE ]( "Article" );
|
|
||||||
|
|
||||||
if ( !( article instanceof Article ) ) return;
|
|
||||||
|
|
||||||
// Drafts Container
|
|
||||||
var ae_expand = Dand.id("ae_expand")
|
|
||||||
, ae_drafts = Dand.id("ae_user_drafts")
|
|
||||||
, ae_drafts_h = null
|
|
||||||
|
|
||||||
////// Draft Section
|
|
||||||
, showDrafts = function ()
|
|
||||||
{
|
|
||||||
showDrafts = function() { };
|
|
||||||
// One-time trigger only.
|
|
||||||
getDraftList({offset: 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
, getDraftList = function ( p )
|
|
||||||
{
|
|
||||||
postData( draftsUri, p, listDraft.bind(p), draftFailed );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {_AstJson_.AJaxGetDrafts} obj */
|
|
||||||
, listDraft = function ( obj )
|
|
||||||
{
|
|
||||||
var entries = obj.entries, entry;
|
|
||||||
|
|
||||||
for ( var i in entries )
|
|
||||||
{
|
|
||||||
/** @param {_AstJson_.AJaxGetDrafts.entry} */
|
|
||||||
entry = entries[i];
|
|
||||||
// Insert entries
|
|
||||||
ae_drafts.appendChild(
|
|
||||||
entry = Dand.wrapc(
|
|
||||||
"ae_dEntry"
|
|
||||||
, [
|
|
||||||
Dand.wrapc(
|
|
||||||
"ae_dEntry_title fls"
|
|
||||||
, entry.active
|
|
||||||
?
|
|
||||||
[
|
|
||||||
Dand.textNode( entry.title )
|
|
||||||
, Dand.wrap( "span", null, "ae_dActive_bubble", "\u25CF" )
|
|
||||||
]
|
|
||||||
: entry.title
|
|
||||||
)
|
|
||||||
, Dand.wrapc( "ae_dEntry_content flsf", entry.content )
|
|
||||||
, Dand.wrapc( "ae_dEntry_date fsf", entry.date )
|
|
||||||
]
|
|
||||||
, entry.active
|
|
||||||
? [ new IKey ( "value", entry._id ), new IKey( "active" ) ]
|
|
||||||
: new IKey( "value", entry._id ) )
|
|
||||||
);
|
|
||||||
|
|
||||||
// Register on click function
|
|
||||||
entry.addEventListener( "click", function() {
|
|
||||||
article.load( this.getAttribute( "value" ), __pushState );
|
|
||||||
}.bind( entry ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
ae_drafts_h = ae_drafts.clientHeight;
|
|
||||||
ae_drafts.style.height = 0;
|
|
||||||
|
|
||||||
Cycle.next(function(){
|
|
||||||
// This doesn't make sense
|
|
||||||
// but we need to actually access the clientHeight
|
|
||||||
// to get the height animation working
|
|
||||||
ae_drafts.clientHeight;
|
|
||||||
ae_drafts.style.height = String( ae_drafts_h ) + "px";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
, draftFailed = function (obj)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handlers
|
|
||||||
, setupExpand = function ()
|
|
||||||
{
|
|
||||||
ae_expand.className = "ae_expand_btn";
|
|
||||||
var panel = Dand.id("ae_minor_panel");
|
|
||||||
panel.onmouseover = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.height = "20px";
|
|
||||||
}
|
|
||||||
panel.onmouseout = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.height = "";
|
|
||||||
}
|
|
||||||
panel.onclick = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.height = "";
|
|
||||||
ae_drafts.style.height = String(ae_drafts_h) + "px";
|
|
||||||
Cycle.delay(setupCollapse , 250);
|
|
||||||
|
|
||||||
// Disable mouse events
|
|
||||||
panel.onmouseover = panel.onmouseout = panel.onclick = null;
|
|
||||||
|
|
||||||
showDrafts();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, setupCollapse = function ()
|
|
||||||
{
|
|
||||||
ae_expand.className = "ae_callapse_btn";
|
|
||||||
Cycle.delay(function()
|
|
||||||
{
|
|
||||||
ae_expand.onclick = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.backgroundColor = "";
|
|
||||||
ae_drafts.style.height = "0";
|
|
||||||
Cycle.delay(setupExpand, 250);
|
|
||||||
|
|
||||||
// Disable mouse events
|
|
||||||
ae_expand.onmouseover = ae_expand.onmouseout = ae_expand.onclick = null;
|
|
||||||
}
|
|
||||||
ae_expand.onmouseover = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.backgroundColor = "rgba(255, 255, 255, 0.2)";
|
|
||||||
}
|
|
||||||
ae_expand.onmouseout = function()
|
|
||||||
{
|
|
||||||
ae_expand.style.backgroundColor = "";
|
|
||||||
}
|
|
||||||
}, 250);
|
|
||||||
}
|
|
||||||
// End Handlers
|
|
||||||
|
|
||||||
|
|
||||||
, __pushState = function ( obj, article_id )
|
|
||||||
{
|
|
||||||
window.history.pushState( obj, "", "/astroedit/" + article_id + "/" );
|
|
||||||
}
|
|
||||||
|
|
||||||
setupExpand();
|
|
||||||
article.invoke( this );
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Draft", Draft );
|
|
||||||
})();
|
|
@ -1,27 +0,0 @@
|
|||||||
.flag_active {
|
|
||||||
color: white;
|
|
||||||
opacity: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_flag_delete {
|
|
||||||
color: white;
|
|
||||||
padding: 0 0.5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_flag_delete:hover {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_flag_add {
|
|
||||||
color: white;
|
|
||||||
cursor: default;
|
|
||||||
font-weight: 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_flag_add:hover {
|
|
||||||
color: dodgerblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_flags > span {
|
|
||||||
float: left;
|
|
||||||
}
|
|
@ -1,190 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
/* @type {AstroEdit.IPlugins} */
|
|
||||||
var Flag = function ( id, target, flagConf )
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
var stage = Dand.id( target );
|
|
||||||
var ae_addFlag = Dand.glass( "ae_flag_add" , true, stage )[0];
|
|
||||||
var ae_flags = Dand.glass( "ae_flags" , false, stage )[0];
|
|
||||||
|
|
||||||
// Store flags for future use
|
|
||||||
var flags = {};
|
|
||||||
|
|
||||||
////// Handlers
|
|
||||||
ae_addFlag.addEventListener(
|
|
||||||
"Click", function ( e )
|
|
||||||
{
|
|
||||||
e.stopPropagation();
|
|
||||||
// Input fields
|
|
||||||
var ae_flagInput;
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Add new flag(s)"
|
|
||||||
, Dand.wrape([
|
|
||||||
Dand.wrapc(
|
|
||||||
"v_instruction flsf"
|
|
||||||
, "Flags are separated by \\n. (existing flags will be ignored.)"
|
|
||||||
)
|
|
||||||
, ae_flagInput = Dand.wrap( "textarea", null, "v_snippet_input" )
|
|
||||||
])
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, parseFlags.bind( ae_flagInput )
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
var deleteFlag = function (e)
|
|
||||||
{
|
|
||||||
e.stopPropagation();
|
|
||||||
var p = { stage: this.parentNode };
|
|
||||||
p[ id ] = this.nodeValue;
|
|
||||||
p[ "id" ] = id;
|
|
||||||
postData( flagConf.URICount, p, confirmDelete.bind( p ), serverFailed );
|
|
||||||
};
|
|
||||||
|
|
||||||
var confirmDelete = function (obj)
|
|
||||||
{
|
|
||||||
new MessageBox(
|
|
||||||
"Delete Flag"
|
|
||||||
, [
|
|
||||||
Dand.wrapc("ae_blockswitch",
|
|
||||||
[
|
|
||||||
Dand.textNode( "Are you sure you want to delete " )
|
|
||||||
, Dand.wrap( "span", null, "flag_active", Dand.textNode( this[ id ] ) )
|
|
||||||
, Dand.textNode( " ?." )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, obj.count > 0
|
|
||||||
? Dand.wrape([
|
|
||||||
Dand.textNode( "This will affect " )
|
|
||||||
, Dand.wrap(
|
|
||||||
"span", null, "ae_affected_count", Dand.textNode( obj.count )
|
|
||||||
)
|
|
||||||
, Dand.textNode(" article(s).")
|
|
||||||
])
|
|
||||||
: null
|
|
||||||
]
|
|
||||||
, "Delete", "No"
|
|
||||||
, doDelete.bind( this )
|
|
||||||
).show();
|
|
||||||
};
|
|
||||||
|
|
||||||
var doDelete = function( confirmed )
|
|
||||||
{
|
|
||||||
if ( confirmed )
|
|
||||||
{
|
|
||||||
this[ "del" ] = 1;
|
|
||||||
postData(
|
|
||||||
flagConf.URISet
|
|
||||||
, this
|
|
||||||
, deleteSuccess.bind( this )
|
|
||||||
, serverFailed
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var deleteSuccess = function(obj)
|
|
||||||
{
|
|
||||||
// Remove element
|
|
||||||
this.stage.parentNode.removeChild( this.stage );
|
|
||||||
// Delete reference
|
|
||||||
delete flags[ this[ id ] ];
|
|
||||||
};
|
|
||||||
|
|
||||||
var parseFlags = function ()
|
|
||||||
{
|
|
||||||
// Filter invalid flags
|
|
||||||
var nflags = this.value.trim().match(/[^\n]+/g), d, e;
|
|
||||||
for (var i in nflags)
|
|
||||||
{
|
|
||||||
if(!flags[(i = nflags[i]).toLowerCase()])
|
|
||||||
{
|
|
||||||
flags[i] = Dand.wrap("span", null, "flag_active",
|
|
||||||
[d = Dand.wrap("span", null, "ae_flag_delete", "\u00D7"), e = Dand.textNode(i)]
|
|
||||||
);
|
|
||||||
// Seperator
|
|
||||||
ae_flags.appendChild(Dand.textNode(" "));
|
|
||||||
ae_flags.appendChild(flags[i]);
|
|
||||||
|
|
||||||
flags[i].onclick = function() { toggleFlag(this) }.bind(flags[i]);
|
|
||||||
d.onclick = deleteFlag.bind(e);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug.Info("Flag exist: " + i);
|
|
||||||
// Hightlight these flags
|
|
||||||
flags[i.toLowerCase()].className = "flag_active";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleFlag = function (flag)
|
|
||||||
{
|
|
||||||
var isEnabled = flag.className == "flag_active" ? true : false;
|
|
||||||
flag.className = isEnabled ? "ae_disabled" : "flag_active";
|
|
||||||
};
|
|
||||||
|
|
||||||
var serverFailed = function (obj) { };
|
|
||||||
|
|
||||||
var cflag, ae_children = ae_flags.childNodes;
|
|
||||||
for (var i in ae_children)
|
|
||||||
{
|
|
||||||
if((cflag = ae_children[i]).nodeType == 1)
|
|
||||||
{
|
|
||||||
flags[cflag.lastChild.nodeValue.toLowerCase()] = cflag;
|
|
||||||
IDOMElement( cflag ).addEventListener( "Click", function() { toggleFlag( this ); }.bind( cflag ) );
|
|
||||||
// Bind the last child (x button) to firstChild (textNode: flagname)
|
|
||||||
IDOMElement( cflag.firstChild ).addEventListener( "Click", deleteFlag.bind( cflag.lastChild ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getData = function ()
|
|
||||||
{
|
|
||||||
// Compile flag list
|
|
||||||
var tlist = [];
|
|
||||||
|
|
||||||
// Return names
|
|
||||||
for (var i in flags)
|
|
||||||
{
|
|
||||||
if(flags[i].className == "flag_active")
|
|
||||||
tlist[tlist.length] = flags[i].lastChild.nodeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tlist.join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setForView = function ( flagList )
|
|
||||||
{
|
|
||||||
// Disable all flags first
|
|
||||||
for ( var i in flags ) flags[i].className = "ae_disabled";
|
|
||||||
|
|
||||||
// Set flags from flagList
|
|
||||||
for ( i in flagList )
|
|
||||||
if ( flagList[i] ) flags[flagList[i].toLowerCase()].className = "flag_active";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Flag.prototype.getSetData = function () { };
|
|
||||||
Flag.prototype.setForView = function ( flagList ) { };
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Flag", Flag );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,415 +0,0 @@
|
|||||||
#siteLibrary {
|
|
||||||
position: fixed;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
top: calc(-100% - 5px);
|
|
||||||
}
|
|
||||||
|
|
||||||
#siteLibrary:hover {
|
|
||||||
top: calc(-100% + 1.5em);
|
|
||||||
}
|
|
||||||
|
|
||||||
#asl_viewer {
|
|
||||||
width: calc(100% - 300px);
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_colls.canvasGeneral {
|
|
||||||
color: #BBB;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral.asl_colls > div > span.c75 { width: 75%; }
|
|
||||||
.canvasGeneral.asl_colls > div > span.c25 { width: 25%; }
|
|
||||||
|
|
||||||
.asl_header {
|
|
||||||
width: 100%;
|
|
||||||
height: 20px;
|
|
||||||
|
|
||||||
top: 100%;
|
|
||||||
margin-top: -20px;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#asl_viewer > #canvasView {
|
|
||||||
position: absolute;
|
|
||||||
min-height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_viewer {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
background: #EEE;
|
|
||||||
|
|
||||||
-moz-box-shadow: 0 7px 5px black;
|
|
||||||
-webkit-box-shadow: 0 7px 5px black;
|
|
||||||
box-shadow: 0 7px 5px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_contentMenu {
|
|
||||||
bottom: 0;
|
|
||||||
position: absolute;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_contentMenu > span {
|
|
||||||
margin: 0 0.2em;
|
|
||||||
padding: 0.5em 0.5em;
|
|
||||||
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
background-color: rgba(0, 0, 0, 0.6);
|
|
||||||
font-family: custom-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_contentMenu > span:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_contentMenu > span[current] {
|
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_smask {
|
|
||||||
height: 10px;
|
|
||||||
background-color: royalblue;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
bottom: -5px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_smask:before {content: '';
|
|
||||||
width: 100%;
|
|
||||||
height: 20px;
|
|
||||||
|
|
||||||
top: -10px;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
z-index: -1;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_smask[expand] {
|
|
||||||
background-image: url(/assets/blog/layout-images/collapse.png);
|
|
||||||
background-position: center 2.5px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_smask[expand]:hover {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#siteLibrary .asl_title, .asl_intitle {
|
|
||||||
font-size: 1.5em;
|
|
||||||
|
|
||||||
font-family: custom-sans;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
background-color: royalblue;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#siteLibrary .asl_title {
|
|
||||||
padding: 0.3em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_contentPanel {
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
height: calc(100% - 2.5em);
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#siteLibrary .asl_title {
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;;
|
|
||||||
|
|
||||||
right: 350px;
|
|
||||||
bottom: -1.7em;
|
|
||||||
|
|
||||||
-moz-box-shadow: 2px 2px 5px black;
|
|
||||||
-webkit-box-shadow: 2px 2px 5px black;
|
|
||||||
box-shadow: 2px 2px 5px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** ASL Canvases ***/
|
|
||||||
.canvasImage > span {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
|
|
||||||
margin: 0.2em;
|
|
||||||
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
border: 1px solid transparent;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: middle;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span:before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
height: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span img {
|
|
||||||
vertical-align: middle;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span:after {
|
|
||||||
content: attr(data-title);
|
|
||||||
background-color: rgba(0,0,0,0.6);
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: -2em;
|
|
||||||
font-size: 0.8em;
|
|
||||||
width: 100%;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
-webkit-transition: all .25s ease-out;
|
|
||||||
-moz-transition: all .25s ease-out;
|
|
||||||
-o-transition: all .25s ease-out;
|
|
||||||
transition: all .25s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span:hover:after {
|
|
||||||
bottom: 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span[selected] {
|
|
||||||
background-color: lightblue;
|
|
||||||
border-color: royalblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span > span {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasImage > span > span:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.2) !important;
|
|
||||||
border-color: #444 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ci_album {
|
|
||||||
-moz-box-shadow: 2px 3px 0 0 black;
|
|
||||||
-webkit-box-shadow: 2px 3px 0 0 black;
|
|
||||||
box-shadow: 2px 3px 0 0 #666;
|
|
||||||
border: 1px solid #666 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.canvasGeneral {
|
|
||||||
padding: 0.2em;
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral > div {
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral > div:hover {
|
|
||||||
background-color: rgba(0, 0 ,0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral > div > span {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
width: 30%;
|
|
||||||
padding: 0.2em 0;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral > div > span:last-child {
|
|
||||||
width: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.canvasGeneral > div[selected] {
|
|
||||||
background-color: orangered;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** End ASL Canvases ***/
|
|
||||||
|
|
||||||
/*** Uploader ***/
|
|
||||||
#asl_uploader {
|
|
||||||
width: 300px;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
#asl_u_head {
|
|
||||||
position: absolute;
|
|
||||||
background: #EEE;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.upldr_title {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_fwrapper {
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
/*
|
|
||||||
-moz-box-shadow: inset 0 0 20px black;
|
|
||||||
-webkit-box-shadow: inset 0 0 20px black;
|
|
||||||
box-shadow: inset 0 0 20px black;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_fileList {
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: #444;;
|
|
||||||
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_fileList > div {
|
|
||||||
/* 0.5em for fwrapper padding */
|
|
||||||
margin-right: 50%;
|
|
||||||
padding: 0.5em;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_uItem:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_uItemStat {
|
|
||||||
padding: 0 0.5em 0 0;
|
|
||||||
color: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_split {
|
|
||||||
position: relative;
|
|
||||||
height: 80px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_split > div {
|
|
||||||
height: 100%;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_left {
|
|
||||||
float: left;
|
|
||||||
width: 135px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_right {
|
|
||||||
float: right;
|
|
||||||
width: calc(100% - 135px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_fileName {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_preview {
|
|
||||||
padding: 0.2em;
|
|
||||||
background-color: white;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Progress indicator */
|
|
||||||
.asl_progress {
|
|
||||||
padding: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_ptext {
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_pbar {
|
|
||||||
background-color: white;
|
|
||||||
position: relative;
|
|
||||||
height: 1em;
|
|
||||||
margin-top: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_pbar_fill {
|
|
||||||
background: greenyellow;
|
|
||||||
position: absolute;
|
|
||||||
width: 0%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_go_up {
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
|
|
||||||
border-top: 0 solid transparent;
|
|
||||||
border-bottom: 0.5em solid transparent;
|
|
||||||
border-left: 0.5em solid #FFF;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_btn {
|
|
||||||
padding: 0.3em;
|
|
||||||
text-align: center;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_btn:hover {
|
|
||||||
background-color: rgba( 0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.asl_instruction {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
@ -1,768 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Components.Mouse.ContextMenu} */
|
|
||||||
var ContextMenu = __import( "Components.Mouse.ContextMenu" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMObject} */
|
|
||||||
var IDOMObject = __import( "Dandelion.IDOMObject" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
var prettyDate = __import( "Astro.utils.Date.pretty" );
|
|
||||||
|
|
||||||
var SiteLibrary = function ( basePath, processorGet, processorSet )
|
|
||||||
{
|
|
||||||
var view_index = []
|
|
||||||
, currentView
|
|
||||||
, inCollection = 0
|
|
||||||
, indexingItem
|
|
||||||
, itemSelected = false
|
|
||||||
, holdingCtrl = false
|
|
||||||
, holdingShift = false
|
|
||||||
|
|
||||||
/** @type {_AstConf_.SiteFile} */
|
|
||||||
, config = Conf.get( "SiteFile" )
|
|
||||||
|
|
||||||
, contentPanel = Dand.id("asl_viewer")
|
|
||||||
, canvasView
|
|
||||||
, contextMenu
|
|
||||||
, stage = Dand.id( "siteLibrary", true )
|
|
||||||
, asl_smask = Dand.id( "asl_smask", true )
|
|
||||||
|
|
||||||
|
|
||||||
, getItemKeys = function (data)
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
new DataKey("id", data.id)
|
|
||||||
, new IKey("data-title", data.name)
|
|
||||||
, new IKey("data-author", data.author)
|
|
||||||
, new DataKey("hash", data.hash)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
, bindData = function(target, source, data)
|
|
||||||
{
|
|
||||||
IDOMElement(source).addEventListener(new EventKey("MouseDown", function (e)
|
|
||||||
{
|
|
||||||
// pass neccessary informations for contextMenu to read
|
|
||||||
target.idata = this;
|
|
||||||
|
|
||||||
if(e.which == 1 || (e.which == 3 && !this.stage.hasAttribute("selected")))
|
|
||||||
{
|
|
||||||
// Mousedown event will bubble up to parent node, set itemselected to true
|
|
||||||
itemSelected = true;
|
|
||||||
|
|
||||||
if( !holdingCtrl ) deselectAllItem.bind( target )();
|
|
||||||
|
|
||||||
if(holdingShift) rangedSelect();
|
|
||||||
else indexingItem = this.stage;
|
|
||||||
|
|
||||||
|
|
||||||
selectItem.bind(target)();
|
|
||||||
}
|
|
||||||
}.bind(
|
|
||||||
{
|
|
||||||
stage: source
|
|
||||||
, id: data.id
|
|
||||||
, href: data.src_location
|
|
||||||
, hash: data.hash
|
|
||||||
, author: data.author
|
|
||||||
, name: data.name
|
|
||||||
, date: data.date_created
|
|
||||||
, isCollection: 0 < data.cCount
|
|
||||||
}
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////// Canvas builders
|
|
||||||
, resetCanvas = function (name)
|
|
||||||
{
|
|
||||||
if(canvasView)
|
|
||||||
{
|
|
||||||
contentPanel.removeChild(canvasView);
|
|
||||||
contentPanel.appendChild(canvasView = Dand.wrap(null, "canvasView", name || canvasView.getAttribute("class"), null, new DataKey("name", currentView)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
contentPanel.appendChild(canvasView = Dand.wrap(null, "canvasView", name, null, new DataKey("name", currentView)));
|
|
||||||
}
|
|
||||||
|
|
||||||
IDOMElement(canvasView).addEventListener(
|
|
||||||
new EventKey("Click", function (e)
|
|
||||||
{
|
|
||||||
if(e.which == 1)
|
|
||||||
{
|
|
||||||
if(!itemSelected)
|
|
||||||
{
|
|
||||||
deselectAllItem.bind(canvasView)();
|
|
||||||
canvasView.idata = null;
|
|
||||||
}
|
|
||||||
itemSelected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
, buildAudioCanvas = function (e)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
resetCanvas("canvasAudio");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {_AstJson_.AJaxGetFiles} */
|
|
||||||
, buildImageCanvas = function ( e )
|
|
||||||
{
|
|
||||||
var f = e.files;
|
|
||||||
resetCanvas( "canvasImage" );
|
|
||||||
|
|
||||||
for( var i in f )
|
|
||||||
{
|
|
||||||
/** @param {_AstJson_.AJaxGetFiles.file} */
|
|
||||||
var file = f[i];
|
|
||||||
// id: i, name: file.name, hash: file.hash, sorce: file.src_location, date: file.date_created
|
|
||||||
var img = Number( file.cCount )
|
|
||||||
|
|
||||||
////// Album item
|
|
||||||
? Dand.wrap(
|
|
||||||
"span", "img_" + Perf.uuid, "ci_album"
|
|
||||||
, Dand.wrapna( "img", new IKey( "src", basePath + "image/s100/" + file.hash + ".jpg" ) )
|
|
||||||
, [
|
|
||||||
new IKey("title"
|
|
||||||
, "Album: " + file.name
|
|
||||||
+ "\n" + file.cCount + " file(s)"
|
|
||||||
+ "\nDate: " + prettyDate( new Date( file.date_created ), true )
|
|
||||||
+ "\nCreated by: " + file.author
|
|
||||||
)
|
|
||||||
, new IKey("collection", 1)
|
|
||||||
].concat( getItemKeys( file ) )
|
|
||||||
)
|
|
||||||
//////// Normal filele
|
|
||||||
: Dand.wrap(
|
|
||||||
"span", "img_" + Perf.uuid, null
|
|
||||||
, Dand.wrapna( "img", new IKey( "src", basePath + "image/s100/" + file.hash + ".jpg" ) )
|
|
||||||
, [
|
|
||||||
new IKey("title"
|
|
||||||
, "File: " + file.name
|
|
||||||
+ "\nDate: " + prettyDate( new Date( file.date_created ), true )
|
|
||||||
+ "\nCreated by: " + file.author
|
|
||||||
)
|
|
||||||
].concat( getItemKeys( file ) )
|
|
||||||
);
|
|
||||||
|
|
||||||
canvasView.appendChild( img );
|
|
||||||
bindData( canvasView, img, file );
|
|
||||||
}
|
|
||||||
|
|
||||||
contextMenu = new ContextMenu(canvasView, [
|
|
||||||
new EventKey("Open", openAction)
|
|
||||||
, {
|
|
||||||
name: "Copy"
|
|
||||||
, items: [
|
|
||||||
new EventKey("Copy source link", copyItemLink)
|
|
||||||
, new EventKey("Copy hash", copyHash)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
name: "Selection"
|
|
||||||
, items: [
|
|
||||||
{
|
|
||||||
name: "Select"
|
|
||||||
, items: [
|
|
||||||
new EventKey("all", selectAllItem)
|
|
||||||
, new EventKey("none", deselectAllItem)
|
|
||||||
, new EventKey("Invert selection", reverseSelection)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
,{
|
|
||||||
name: "By type"
|
|
||||||
, items:
|
|
||||||
[
|
|
||||||
new EventKey("Only albums", selectAllCollections)
|
|
||||||
, new EventKey("Only files", selectAllFiles)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, {
|
|
||||||
name: "Action"
|
|
||||||
, items: [
|
|
||||||
new EventKey("Group selected file(s)", setCollection)
|
|
||||||
, new EventKey("Add file(s) to collection", insertCollection)
|
|
||||||
// TODO: in-group file action changes
|
|
||||||
, new EventKey("Move file(s) to collection", function(){})
|
|
||||||
, new EventKey("Remove files(s) from collection", excludeCollection)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
,new EventKey("Refresh", refreshCanvas)
|
|
||||||
, new EventKey("Rename", popupRename)
|
|
||||||
, new EventKey("Delete", confirmDelete)
|
|
||||||
], "RMB");
|
|
||||||
}
|
|
||||||
|
|
||||||
// General file, list view
|
|
||||||
/** @param {_AstJson_.AJaxGetFiles} */
|
|
||||||
, buildGeneralCanvas = function ( e )
|
|
||||||
{
|
|
||||||
if( !e ) return;
|
|
||||||
var f = e.files, dateStamp;
|
|
||||||
resetCanvas( "canvasGeneral" );
|
|
||||||
|
|
||||||
for(var i in f)
|
|
||||||
{
|
|
||||||
/** @param {_AstJson_.AJaxGetFiles.file} */
|
|
||||||
var file = f[i];
|
|
||||||
dateStamp = Dand.wrap( "span" );
|
|
||||||
dateStamp.innerHTML = prettyDate( new Date( file.date_created ) ) ;
|
|
||||||
|
|
||||||
var li = Dand.wrap(
|
|
||||||
null, "g_item" + Perf.uuid, null
|
|
||||||
, [
|
|
||||||
Dand.wrapne( "span", file.name )
|
|
||||||
, dateStamp
|
|
||||||
, Dand.wrapne( "span", file.author )
|
|
||||||
]
|
|
||||||
, getItemKeys( file )
|
|
||||||
);
|
|
||||||
|
|
||||||
canvasView.appendChild( li );
|
|
||||||
bindData( canvasView, li, file );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
contextMenu = new ContextMenu(canvasView, [
|
|
||||||
{
|
|
||||||
name: "Copy"
|
|
||||||
, items: [
|
|
||||||
new EventKey("Copy source link", copyItemLink)
|
|
||||||
, new EventKey("Copy hash", copyHash)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
, new EventKey("Delete file", confirmDelete)
|
|
||||||
], "RMB");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, selHasCollection = false
|
|
||||||
|
|
||||||
// Return the selected files
|
|
||||||
, selections = function(return_id) {
|
|
||||||
var s = [];
|
|
||||||
selHasCollection = false;
|
|
||||||
|
|
||||||
IDOMElement(canvasView).foreach(1, function(elem) {
|
|
||||||
// Save the hashes
|
|
||||||
if(elem.hasAttribute("selected"))
|
|
||||||
{
|
|
||||||
s[s.length] = return_id ? IDOMElement(elem).getDAttribute("id") : elem;
|
|
||||||
if(elem.hasAttribute("collection")) selHasCollection = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Menu item handlers
|
|
||||||
, confirmDelete = function ()
|
|
||||||
{
|
|
||||||
|
|
||||||
new MessageBox("Confirm delete"
|
|
||||||
, [
|
|
||||||
Dand.wrape("Are you sure you want to delete the selected item(s)?")
|
|
||||||
, Dand.wrape("Warning: This action cannot be undone! Make sure you have de-referenced them from your articles.", new IKey("style", "color: yellow;"))
|
|
||||||
]
|
|
||||||
, "Delete it", "No"
|
|
||||||
, requestDelete.bind({files: selections()})).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, popupRename = function ()
|
|
||||||
{
|
|
||||||
var name_field = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"));
|
|
||||||
new MessageBox("Rename \"" + canvasView.idata.name + "\"", name_field, "OK", "Cancel", requestRename.bind(
|
|
||||||
{
|
|
||||||
name: name_field
|
|
||||||
, stage: canvasView.idata.stage
|
|
||||||
, isCollection: canvasView.idata.isCollection
|
|
||||||
}
|
|
||||||
)).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, copyItemLink = function () { return config.f_host + canvasView.idata.href; }
|
|
||||||
, copyHash = function ()
|
|
||||||
{
|
|
||||||
var data = canvasView.idata;
|
|
||||||
return data.isCollection ? data.id : data.hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
, openAction = function ()
|
|
||||||
{
|
|
||||||
if(canvasView.idata.isCollection) openCollection(IDOMElement(canvasView.idata.stage).getDAttribute("id"));
|
|
||||||
else window.open( config.f_host + canvasView.idata.href);
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ContextMenu Handlers: Selections
|
|
||||||
, selectItem = function()
|
|
||||||
{
|
|
||||||
canvasView.idata.stage.hasAttribute("selected") ? canvasView.idata.stage.removeAttribute("selected") : canvasView.idata.stage.setAttribute("selected", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
, selectAllItem = function ()
|
|
||||||
{
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
target.setAttribute("selected", 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
, selectAllCollections = function ()
|
|
||||||
{
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
target.hasAttribute("collection") ? target.setAttribute("selected", 1) : target.removeAttribute("selected");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
, selectAllFiles = function ()
|
|
||||||
{
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
target.hasAttribute("collection") ? target.removeAttribute("selected") : target.setAttribute("selected", 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
, rangedSelect = function ()
|
|
||||||
{
|
|
||||||
var items = canvasView.childNodes;
|
|
||||||
var k = indexingItem;
|
|
||||||
if(Array.prototype.indexOf.call(items, k) < Array.prototype.indexOf.call(items, canvasView.idata.stage))
|
|
||||||
{
|
|
||||||
while(k != canvasView.idata.stage)
|
|
||||||
{
|
|
||||||
k.setAttribute("selected", 1);
|
|
||||||
k = k.nextSibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while(k != canvasView.idata.stage)
|
|
||||||
{
|
|
||||||
k.setAttribute("selected", 1);
|
|
||||||
k = k.previousSibling;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, deselectAllItem = function ()
|
|
||||||
{
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
target.removeAttribute("selected");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
, reverseSelection = function ()
|
|
||||||
{
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
target.hasAttribute("selected") ? target.removeAttribute("selected") : target.setAttribute("selected", 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ContextMenu Handlers: Collections
|
|
||||||
, setCollection = function ()
|
|
||||||
{
|
|
||||||
var s = selections( true )
|
|
||||||
var name_field = Dand.wrap(
|
|
||||||
"input", null
|
|
||||||
, "v_snippet_input_single", null
|
|
||||||
, new IKey( "type", "text" )
|
|
||||||
);
|
|
||||||
|
|
||||||
new MessageBox(
|
|
||||||
"Collection name"
|
|
||||||
, name_field
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, requestCollection.bind({ name: name_field, files: s.join(",") })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, openCollection = function ( id ) {
|
|
||||||
refreshCanvas( id, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
, excludeCollection = function() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, insertCollection = function() {
|
|
||||||
var collections = []
|
|
||||||
, ul = Dand.wrapc( "canvasGeneral asl_colls" )
|
|
||||||
;
|
|
||||||
|
|
||||||
// Get current albums to list
|
|
||||||
IDOMElement(canvasView).foreach(1, function(target)
|
|
||||||
{
|
|
||||||
if(target.hasAttribute("collection"))
|
|
||||||
{
|
|
||||||
|
|
||||||
var t = IDOMElement(target)
|
|
||||||
// item structure
|
|
||||||
, li = Dand.wrap(
|
|
||||||
null, "g_item" + Perf.uuid, null
|
|
||||||
, [
|
|
||||||
Dand.wrap("span", null, "c75", t.getDAttribute("title") )
|
|
||||||
, Dand.wrap("span", null, "c25", t.getDAttribute("author") )
|
|
||||||
]
|
|
||||||
, new DataKey("id", t.getDAttribute("id"))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set selection behaviour
|
|
||||||
IDOMElement(li).addEventListener("Click", function(e) {
|
|
||||||
IDOMElement(ul).foreach(1, function(elem) { elem.hasAttribute("selected") && elem.removeAttribute("selected"); });
|
|
||||||
this.setAttribute("selected", 1);
|
|
||||||
}.bind(li));
|
|
||||||
|
|
||||||
ul.appendChild(li);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
new MessageBox("Select a collection", ul, "OK", "Cancel", requestInsert.bind({ albumList: ul, collection: selections(true) })).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
//// ContextMenu Handlers: General actions
|
|
||||||
, requestRename = function( confirmed )
|
|
||||||
{
|
|
||||||
if( confirmed )
|
|
||||||
{
|
|
||||||
var pData = {
|
|
||||||
"name": this.name.value
|
|
||||||
, "id": IDOMElement( this.stage ).getDAttribute( "id" )
|
|
||||||
};
|
|
||||||
|
|
||||||
if(this.isCollection) pData.group = "rename";
|
|
||||||
else pData.file = "rename";
|
|
||||||
|
|
||||||
postData( processorSet, pData, refreshCanvas, loadFailed );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, requestDelete = function (confirmed)
|
|
||||||
{
|
|
||||||
if(confirmed || this.reConfirmed)
|
|
||||||
{
|
|
||||||
if(this.files.length < 2)
|
|
||||||
{
|
|
||||||
var file = this.files[0];
|
|
||||||
if(selHasCollection)
|
|
||||||
{
|
|
||||||
new MessageBox("Also delete files?"
|
|
||||||
, "Do you also want to delete the files within the collections?"
|
|
||||||
, "Delete all files", "Only delete collection"
|
|
||||||
, delCollection.bind(file)).show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
postData(
|
|
||||||
processorSet
|
|
||||||
, { "file": "remove", "hash": IDOMElement(file).getDAttribute("hash") }
|
|
||||||
, fileDeleted.bind(file), loadFailed
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!this.reConfirmed && selHasCollection)
|
|
||||||
{
|
|
||||||
// Set the reconfirmation attr
|
|
||||||
this.reConfirmed = true;
|
|
||||||
|
|
||||||
new MessageBox("Also delete files?"
|
|
||||||
, "You have also selected collection(s), do you want to also delete files inside?"
|
|
||||||
, "Delete all files", "Only delete collection"
|
|
||||||
, requestDelete.bind(this)).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var files = this.files;
|
|
||||||
|
|
||||||
for(var i in files)
|
|
||||||
{
|
|
||||||
if(files[i].hasAttribute("collection"))
|
|
||||||
{
|
|
||||||
// redirect confirmation to delCollection handler
|
|
||||||
// delete all things when true
|
|
||||||
delCollection.bind(files[i])(confirmed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// redirect to self
|
|
||||||
requestDelete.bind({files: [files[i]]})(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, requestInsert = function(confirmed)
|
|
||||||
{
|
|
||||||
if( confirmed )
|
|
||||||
{
|
|
||||||
var selectedAlbum = IDOMElement(
|
|
||||||
IDOMElement( this.albumList ).first( 1, function(elem) {
|
|
||||||
return elem.hasAttribute("selected");
|
|
||||||
} ) ).getDAttribute( "id" );
|
|
||||||
|
|
||||||
postData(
|
|
||||||
processorSet
|
|
||||||
, { "group": "insert", "id": selectedAlbum , "files": this.collection.join(",") }
|
|
||||||
, refreshCanvas, loadFailed
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, delCollection = function (confirmed)
|
|
||||||
{
|
|
||||||
var album_id = IDOMElement(this).getDAttribute("id");
|
|
||||||
if( confirmed )
|
|
||||||
{
|
|
||||||
postData( processorGet, { group: "get", aid: album_id }, getFilestoDelete.bind( this ), loadFailed );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
postData( processorSet, { group: "remove", id: album_id }, refreshCanvas, loadFailed );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, getFilestoDelete = function ( e )
|
|
||||||
{
|
|
||||||
var l = Object.keys(e.files).length
|
|
||||||
, fc = 0
|
|
||||||
, _self = this
|
|
||||||
, echoDeleted = function()
|
|
||||||
{
|
|
||||||
debug.Info("[ASL] File deleted: " + this.name);
|
|
||||||
fc ++;
|
|
||||||
if(l == fc) delCollection.bind(_self)(false);
|
|
||||||
}
|
|
||||||
, deleteFailed = function ()
|
|
||||||
{
|
|
||||||
debug.Error( new Error( "[ASL] Failed to delete: " + this.name ) );
|
|
||||||
fc ++;
|
|
||||||
if(l == fc) delCollection.bind(_self)(false);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
for(var i in e.files)
|
|
||||||
{
|
|
||||||
postData(
|
|
||||||
processorSet
|
|
||||||
, { "file": "remove", "hash": e.files[i]}, echoDeleted.bind({ "name": i })
|
|
||||||
, deleteFailed.bind({ "name": i })
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, fileDeleted = function () { this.parentNode.removeChild(this); }
|
|
||||||
|
|
||||||
, requestCollection = function ()
|
|
||||||
{
|
|
||||||
if(this.name.value)
|
|
||||||
{
|
|
||||||
postData(
|
|
||||||
processorSet
|
|
||||||
, { "group": "create", "name": this.name.value, "files": this.files }
|
|
||||||
, refreshCanvas, loadFailed
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
////// End canvas builders
|
|
||||||
|
|
||||||
, refreshCanvas = function ( view, openCollection )
|
|
||||||
{
|
|
||||||
if( typeof view != "string" && !openCollection ) view = null;
|
|
||||||
|
|
||||||
// prepare postData
|
|
||||||
/** @type {_AstJson_.AJaxGetFiles.Request} */
|
|
||||||
var pdata = {};
|
|
||||||
|
|
||||||
if( openCollection )
|
|
||||||
{
|
|
||||||
// Set and remove to prevent invalid content set to currentView
|
|
||||||
inCollection = view;
|
|
||||||
view = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentView = view || ( currentView || "application" );
|
|
||||||
|
|
||||||
//// postData parameters
|
|
||||||
// if we are in collection
|
|
||||||
if( inCollection )
|
|
||||||
{
|
|
||||||
pdata.group = "list";
|
|
||||||
pdata.aid = inCollection;
|
|
||||||
}
|
|
||||||
// else we are in root
|
|
||||||
else pdata.listFiles = currentView;
|
|
||||||
|
|
||||||
|
|
||||||
switch( currentView )
|
|
||||||
{
|
|
||||||
case "image":
|
|
||||||
postData( processorGet, pdata, buildImageCanvas, loadFailed );
|
|
||||||
break;
|
|
||||||
case "audio":
|
|
||||||
postData( processorGet, pdata, buildAudioCanvas, loadFailed );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
postData( processorGet, pdata, buildGeneralCanvas, loadFailed );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {_AstJson_.AJaxGetFiles} e */
|
|
||||||
, panelSwitch = function ( e )
|
|
||||||
{
|
|
||||||
if( view_index.length < 1 )
|
|
||||||
{
|
|
||||||
var menuBar = Dand.id( "asl_contentMenu" )
|
|
||||||
, f = e.files, first;
|
|
||||||
|
|
||||||
// button mime/type ( counts )
|
|
||||||
for( var i in f )
|
|
||||||
{
|
|
||||||
var elem = Dand.wrap(
|
|
||||||
"span", null, "asl_menuItem"
|
|
||||||
, i + "(" + f[i] + ")"
|
|
||||||
, new DataKey( "name", i ) );
|
|
||||||
|
|
||||||
view_index[view_index.length] = [i, elem];
|
|
||||||
menuBar.appendChild(elem);
|
|
||||||
|
|
||||||
IDOMElement(elem).addEventListener(new EventKey("Click", switchView.bind(IDOMElement(elem))));
|
|
||||||
|
|
||||||
if( !first ) first = [ i, elem ];
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !first )
|
|
||||||
{
|
|
||||||
debug.Info( "No files" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// begin load index
|
|
||||||
refreshCanvas( first[0] );
|
|
||||||
// Set style
|
|
||||||
first[1].setAttribute("current", 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Should update the menu buttons
|
|
||||||
debug.Info( "Should update the menu buttons" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, switchView = function ()
|
|
||||||
{
|
|
||||||
// Do nothing if current
|
|
||||||
if(this.getDAttribute("name") == currentView) return;
|
|
||||||
|
|
||||||
|
|
||||||
for(var i in view_index)
|
|
||||||
{
|
|
||||||
if(view_index[i][0] == currentView)
|
|
||||||
{
|
|
||||||
view_index[i][1].removeAttribute("current");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// switching view, reset collection
|
|
||||||
inCollection = 0;
|
|
||||||
|
|
||||||
this.setAttribute("current", 1);
|
|
||||||
refreshCanvas(this.getDAttribute("name"));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, showLibrary = new EventKey("Click"
|
|
||||||
, function ()
|
|
||||||
{
|
|
||||||
stage.style.top = "0";
|
|
||||||
asl_smask.setAttribute( "expand", 1 );
|
|
||||||
|
|
||||||
// Switch behaviour
|
|
||||||
stage.removeEventListener( showLibrary );
|
|
||||||
|
|
||||||
Cycle.delay(function () {
|
|
||||||
Dand.id( "ae_body" ).style.display = Dand.id( "ae_panel" ).style.display = "none";
|
|
||||||
asl_smask.addEventListener( hideLibrary );
|
|
||||||
|
|
||||||
// load library statistics
|
|
||||||
loadLibStats( panelSwitch, loadFailed );
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
, hideLibrary = new EventKey(
|
|
||||||
"Click"
|
|
||||||
, function ()
|
|
||||||
{
|
|
||||||
stage.style.top = "";
|
|
||||||
asl_smask.removeAttribute( "expand" );
|
|
||||||
|
|
||||||
// Switch behaviour
|
|
||||||
asl_smask.removeEventListener( hideLibrary );
|
|
||||||
|
|
||||||
Dand.id("ae_body").style.display = Dand.id( "ae_panel" ).style.display = "";
|
|
||||||
|
|
||||||
Cycle.delay(function () {
|
|
||||||
stage.addEventListener( showLibrary );
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
, loadFailed = function (e)
|
|
||||||
{
|
|
||||||
// TODO: make some notifications here
|
|
||||||
}
|
|
||||||
|
|
||||||
, loadLibStats = function ( handler, failedHandler )
|
|
||||||
{
|
|
||||||
postData( processorGet, { "countTypes": 1 }, handler, failedHandler );
|
|
||||||
}
|
|
||||||
|
|
||||||
, keyHold = function(e) { holdingCtrl = e.ctrlKey; holdingShift = e.shiftKey; }
|
|
||||||
, dKeyUp = new EventKey( "KeyUp", keyHold )
|
|
||||||
, dKeyDown = new EventKey( "KeyDown", keyHold )
|
|
||||||
;
|
|
||||||
|
|
||||||
Dand.id( "asl_homeBtn", true ).addEventListener( "click", function( e ) { refreshCanvas( 0, true ); } );
|
|
||||||
Dand.id( "asl_refresh", true ).addEventListener( "click", function( e ) { refreshCanvas( 0 ); } );
|
|
||||||
new IDOMObject( document ).addEventListeners([ dKeyUp, dKeyDown ]);
|
|
||||||
stage.addEventListener(showLibrary);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "SiteLibrary", SiteLibrary );
|
|
||||||
})();
|
|
@ -1,71 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.SmartInput.CandidateAction" );
|
|
||||||
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var getData = __import( "System.Net.getData" );
|
|
||||||
var prettyDate = __import( "Astro.utils.Date.pretty" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.AstroEdit} */
|
|
||||||
var Conf = Config.get( "AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
|
|
||||||
var ArticleRefs = function ( visualizer, key )
|
|
||||||
{
|
|
||||||
this.visualizer = visualizer;
|
|
||||||
this.key = key;
|
|
||||||
this.__cands = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
ArticleRefs.prototype.GetCandidates = function( handler )
|
|
||||||
{
|
|
||||||
var _self = this;
|
|
||||||
getData( Conf.paths.list_articles, function( e ) {
|
|
||||||
e = JSON.parse( e );
|
|
||||||
|
|
||||||
for( var i in e.entries )
|
|
||||||
{
|
|
||||||
var ent = e.entries[i];
|
|
||||||
_self.__cands[ ent.title ] = { "desc": ent.content, id: ent.id };
|
|
||||||
}
|
|
||||||
|
|
||||||
handler( _self.__cands );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
ArticleRefs.prototype.Process = function( key )
|
|
||||||
{
|
|
||||||
var cand = this.__cands[ key ];
|
|
||||||
if( !cand ) return false;
|
|
||||||
|
|
||||||
this.visualizer.insertSnippet( "articlelink", { value: cand.id } );
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ArticleRefs.prototype.Retreat = function( sender, e )
|
|
||||||
{
|
|
||||||
return sender.value == "" && e.keyCode == 8; // Backspace
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
|
|
||||||
var ArticleContent = function ( visualizer, key )
|
|
||||||
{
|
|
||||||
ArticleRefs.call( this, visualizer, key );
|
|
||||||
};
|
|
||||||
|
|
||||||
__extends( ArticleContent, ArticleRefs );
|
|
||||||
|
|
||||||
ArticleContent.prototype.Process = function( key )
|
|
||||||
{
|
|
||||||
var cand = this.__cands[ key ];
|
|
||||||
if( !cand ) return false;
|
|
||||||
|
|
||||||
this.visualizer.insertSnippet( "articlecontent", { value: cand.id } );
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "ArticleContent", ArticleContent );
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "ArticleReference", ArticleRefs );
|
|
||||||
})();
|
|
@ -1,37 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.SmartInput.CandidateAction" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
|
|
||||||
var Footnote = function ( visualizer, key )
|
|
||||||
{
|
|
||||||
this.visualizer = visualizer;
|
|
||||||
this.key = key;
|
|
||||||
};
|
|
||||||
|
|
||||||
Footnote.prototype.GetCandidates = function( handler )
|
|
||||||
{
|
|
||||||
handler( false );
|
|
||||||
};
|
|
||||||
|
|
||||||
Footnote.prototype.Process = function( content )
|
|
||||||
{
|
|
||||||
this.visualizer.insertSnippet( "footnote", { "value": content } );
|
|
||||||
};
|
|
||||||
|
|
||||||
Footnote.prototype.Retreat = function( sender, e )
|
|
||||||
{
|
|
||||||
return sender.value == "" && e.keyCode == 8; // Backspace
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Footnote", Footnote );
|
|
||||||
})();
|
|
@ -1,28 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.SmartInput.CandidateAction" );
|
|
||||||
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
|
|
||||||
var Heading = function ( visualizer, key )
|
|
||||||
{
|
|
||||||
this.visualizer = visualizer;
|
|
||||||
this.key = key;
|
|
||||||
};
|
|
||||||
|
|
||||||
Heading.prototype.GetCandidates = function( handler )
|
|
||||||
{
|
|
||||||
handler( false );
|
|
||||||
};
|
|
||||||
|
|
||||||
Heading.prototype.Process = function( content )
|
|
||||||
{
|
|
||||||
this.visualizer.insertSnippet( "heading", { "size": this.key, "value": content } );
|
|
||||||
};
|
|
||||||
|
|
||||||
Heading.prototype.Retreat = function( sender, e )
|
|
||||||
{
|
|
||||||
return sender.value == "" && e.keyCode == 8; // Backspace
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Heading", Heading );
|
|
||||||
})();
|
|
@ -1,21 +0,0 @@
|
|||||||
.smartbar-candidates {
|
|
||||||
padding: 0.5em;
|
|
||||||
background-color: rgba( 0, 0, 0, 0.2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
.smartbar-candidates .cn {
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.smartbar-candidates .cn:hover {
|
|
||||||
background-color: rgba( 0, 0, 0, 0.2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
.smartbar-candidates .cn[data-selected="1"] {
|
|
||||||
background-color: orangered;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cn .desc {
|
|
||||||
margin-left: 0.5em;
|
|
||||||
opacity: 0.65;
|
|
||||||
}
|
|
@ -1,521 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion.IDOMObject} */
|
|
||||||
var IDOMObject = __import( "Dandelion.IDOMObject" );
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.Net.ClassLoader} */
|
|
||||||
var Loader = __import( "System.Net.ClassLoader" );
|
|
||||||
/** @type {System.utils} */
|
|
||||||
var utils = __import( "System.utils" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var moduleNs = "Astro.Blog.AstroEdit.SmartInput.CandidateAction.";
|
|
||||||
var service_uri = Config.get( "ServiceUri" );
|
|
||||||
|
|
||||||
var Destructor = function( target )
|
|
||||||
{
|
|
||||||
this.target = target;
|
|
||||||
this.target.Disposed = false;
|
|
||||||
this.destructSequence = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
Destructor.prototype.Register = function( destruct )
|
|
||||||
{
|
|
||||||
this.destructSequence.push( destruct );
|
|
||||||
};
|
|
||||||
|
|
||||||
Destructor.prototype.Destruct = function()
|
|
||||||
{
|
|
||||||
for( var i in this.destructSequence )
|
|
||||||
{
|
|
||||||
this.destructSequence[i]();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.target.Disposed = true;
|
|
||||||
this.destructSequence = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
var KeyHandler = function( sender, handler )
|
|
||||||
{
|
|
||||||
return function( e )
|
|
||||||
{
|
|
||||||
e = e || window.event;
|
|
||||||
if ( e.keyCode ) code = e.keyCode;
|
|
||||||
else if ( e.which ) code = e.which;
|
|
||||||
|
|
||||||
handler( sender, e );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// {{{ Candidates Class
|
|
||||||
var Candidates = function( title, desc, defs )
|
|
||||||
{
|
|
||||||
this.title = title;
|
|
||||||
this.desc = desc;
|
|
||||||
this.__cands = [];
|
|
||||||
this.__defs = defs || {};
|
|
||||||
this.Empty = !defs;
|
|
||||||
};
|
|
||||||
|
|
||||||
Candidates.prototype.Get = function()
|
|
||||||
{
|
|
||||||
if( this.__cands.length ) return this.__cands;
|
|
||||||
|
|
||||||
for( var i in this.__defs )
|
|
||||||
{
|
|
||||||
/** @param {Astro.Blog.AstroEdit.SmartInput.Definition} */
|
|
||||||
var c = this.__defs[i];
|
|
||||||
this.__cands.push( Dand.wrapc( "cn", [ i, Dand.wrapc( "desc", c.desc ) ], new DataKey( "key", i ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.__cands;
|
|
||||||
};
|
|
||||||
|
|
||||||
Candidates.prototype.Reset = function()
|
|
||||||
{
|
|
||||||
var Cands = this.Get();
|
|
||||||
for( var i in Cands )
|
|
||||||
{
|
|
||||||
var c = IDOMElement( Cands[i] );
|
|
||||||
c.setAttribute( new DataKey( "selected", 0 ) );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Candidates.prototype.Filtered = function()
|
|
||||||
{
|
|
||||||
var Cands = this.Get();
|
|
||||||
var selected = [];
|
|
||||||
for( var i in Cands )
|
|
||||||
{
|
|
||||||
var c = IDOMElement( Cands[i] );
|
|
||||||
c.setAttribute( new DataKey( "selected", 0 ) );
|
|
||||||
|
|
||||||
if( c.style.display != "none" )
|
|
||||||
{
|
|
||||||
selected.push( c );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return selected;
|
|
||||||
};
|
|
||||||
|
|
||||||
Candidates.prototype.Selected = function()
|
|
||||||
{
|
|
||||||
var Cands = this.Get();
|
|
||||||
for( var i in Cands )
|
|
||||||
{
|
|
||||||
var c = IDOMElement( Cands[i] );
|
|
||||||
if( c.getDAttribute( "selected" ) == "1" )
|
|
||||||
{
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
/** @param {Astro.Blog.AstroEdit.Visualizer} */
|
|
||||||
var SmartInput = function( visualizer )
|
|
||||||
{
|
|
||||||
this.Present = false;
|
|
||||||
var destructor = new Destructor( this );
|
|
||||||
|
|
||||||
var _self = this;
|
|
||||||
var insert = function() { return Dand.textNode( "" ); };
|
|
||||||
|
|
||||||
var ModLevels = [];
|
|
||||||
var BindingBox = null;
|
|
||||||
|
|
||||||
ModLevels.Cands = function() { return ModLevels[0][0]; };
|
|
||||||
ModLevels.Action = function() { return ModLevels[0][1]; };
|
|
||||||
ModLevels.Retreat = function() { return ModLevels[0][2]; };
|
|
||||||
|
|
||||||
var __title = null;
|
|
||||||
var title = function( reload )
|
|
||||||
{
|
|
||||||
if( !reload && __title ) return __title;
|
|
||||||
|
|
||||||
var l = ModLevels.length - 1;
|
|
||||||
var t = ModLevels[ l ][0].title;
|
|
||||||
|
|
||||||
for( var i = 0; i < l; i ++ )
|
|
||||||
{
|
|
||||||
var Mod = ModLevels[i];
|
|
||||||
t = t + " > " + Mod[0].title;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( __title )
|
|
||||||
{
|
|
||||||
__title.textContent = t;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
__title = Dand.wrape( t );
|
|
||||||
}
|
|
||||||
|
|
||||||
return __title;
|
|
||||||
};
|
|
||||||
var __stage = null;
|
|
||||||
var stage = function( incoming )
|
|
||||||
{
|
|
||||||
if( __stage )
|
|
||||||
{
|
|
||||||
if( incoming )
|
|
||||||
{
|
|
||||||
IDOMElement( __stage[1] ).clear();
|
|
||||||
|
|
||||||
var ThisCands = ModLevels.Cands().Get();
|
|
||||||
if( ThisCands.length )
|
|
||||||
{
|
|
||||||
IDOMElement( __stage[1] ).loot( Dand.wrape( ThisCands ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return __stage;
|
|
||||||
}
|
|
||||||
var Cands = ModLevels.Cands();
|
|
||||||
|
|
||||||
var Command = Dand.wrap(
|
|
||||||
"input", null, "v_snippet_input_single"
|
|
||||||
, null, IKey.quickDef( "type", "text", "placeholder", Cands.desc, "value", "`" )
|
|
||||||
);
|
|
||||||
|
|
||||||
var CandList = Dand.wrap( "div", null, "compx smartbar-candidates", Cands.Get() );
|
|
||||||
|
|
||||||
Command.selectionStart = Command.selectionEnd = 1;
|
|
||||||
|
|
||||||
return __stage = [ Command, CandList ];
|
|
||||||
};
|
|
||||||
|
|
||||||
var CandidateCycle = -1;
|
|
||||||
var KeywordTyped = 0;
|
|
||||||
var shiftTabbed = false;
|
|
||||||
|
|
||||||
var HandleInput = function( sender, e )
|
|
||||||
{
|
|
||||||
// Don't handle if holding shift or ctrl key
|
|
||||||
if( e.shiftKey || e.ctrlKey )
|
|
||||||
{
|
|
||||||
// Except the Shift + Tab, we need to cycle this
|
|
||||||
shiftTabbed = e.shiftKey && e.keyCode == 9;
|
|
||||||
|
|
||||||
if( !shiftTabbed ) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( e.keyCode )
|
|
||||||
{
|
|
||||||
case 192: // `
|
|
||||||
// If we are not are the first level, do nothing
|
|
||||||
if( 1 < ModLevels.length ) break;
|
|
||||||
|
|
||||||
// Closing the quote, that means this is a block-quoted text
|
|
||||||
e.preventDefault();
|
|
||||||
insert = undefined;
|
|
||||||
|
|
||||||
// Hitting ` twice escapes the ` character itself
|
|
||||||
var v = sender.value.substr( 1 );
|
|
||||||
if( v == "" )
|
|
||||||
{
|
|
||||||
insert = function() { return Dand.textNode( "`" ); };
|
|
||||||
BindingBox.close( true );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
BindingBox.close();
|
|
||||||
// Insert the code snippet with inline flag
|
|
||||||
visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 13: // Enter
|
|
||||||
// Not closing the quote, either a direct text or the first matched action
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// No candidates, directly pass the input text to the processor
|
|
||||||
if( ModLevels.Cands().Empty && 1 < ModLevels.length )
|
|
||||||
{
|
|
||||||
ModLevels.Action()( sender.value.substr( 1 ) );
|
|
||||||
BindingBox.close();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var selected = ModLevels.Cands().Selected();
|
|
||||||
// Check if matched an action first
|
|
||||||
if( selected )
|
|
||||||
{
|
|
||||||
insert = undefined;
|
|
||||||
var close = ModLevels.Action()( selected.getDAttribute( "key" ) );
|
|
||||||
if( close ) BindingBox.close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Insert this text directly
|
|
||||||
var v = Dand.textNode( sender.value.substr( 1 ) );
|
|
||||||
insert = function() { return v; };
|
|
||||||
BindingBox.close( true );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 27: // Esc
|
|
||||||
BindingBox.close();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 9: // Tab
|
|
||||||
// Hitting tab will cycle around the candidates
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var c = ModLevels.Cands().Filtered();
|
|
||||||
var l = c.length;
|
|
||||||
if( !l ) break;
|
|
||||||
|
|
||||||
CandidateCycle += e.shiftKey ? -1 : 1;
|
|
||||||
|
|
||||||
if( CandidateCycle == l )
|
|
||||||
{
|
|
||||||
CandidateCycle = 0;
|
|
||||||
}
|
|
||||||
else if( CandidateCycle == -1 )
|
|
||||||
{
|
|
||||||
CandidateCycle = c.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ThisCandidate = c[ CandidateCycle ];
|
|
||||||
ThisCandidate.setAttribute( new DataKey( "selected", 1 ) );
|
|
||||||
|
|
||||||
var CyclingKeyword = ThisCandidate.getDAttribute( "key" );
|
|
||||||
|
|
||||||
sender.value = "`" + CyclingKeyword;
|
|
||||||
|
|
||||||
// Check if only 1 matched
|
|
||||||
if( c.length == 1 && KeywordTyped == sender.value.length )
|
|
||||||
{
|
|
||||||
insert = undefined;
|
|
||||||
ModLevels.Action()( ThisCandidate.getDAttribute( "key" ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
sender.setSelectionRange( KeywordTyped, sender.value.length );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ModLevels.Cands().Filtered();
|
|
||||||
CandidateCycle = -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var TestEmpty = function( sender, e )
|
|
||||||
{
|
|
||||||
if( ModLevels.Retreat()( sender, e ) )
|
|
||||||
{
|
|
||||||
_self.RetreatLevel( sender );
|
|
||||||
if( !ModLevels.length ) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search exact matched Candidates
|
|
||||||
switch( e.keyCode )
|
|
||||||
{
|
|
||||||
case 9: // Tab, do nothing
|
|
||||||
break;
|
|
||||||
case 16: // Shift, check if shiftTabbed
|
|
||||||
if( shiftTabbed )
|
|
||||||
{
|
|
||||||
shiftTabbed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if( CandidateCycle == -1 )
|
|
||||||
{
|
|
||||||
KeywordTyped = sender.value.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
var c = ModLevels.Cands().Get();
|
|
||||||
var keyword = sender.value.substr( 1 );
|
|
||||||
for( var i in c )
|
|
||||||
{
|
|
||||||
var Cand = IDOMElement( c[i] );
|
|
||||||
var t = Cand.getDAttribute( "key" );
|
|
||||||
Cand.style.display = t.match( new RegExp( keyword, "i" ) ) ? "" : "none";
|
|
||||||
|
|
||||||
// Highlight the exact match
|
|
||||||
if( t.match( new RegExp( "^" + keyword + "$", "i" ) ) )
|
|
||||||
{
|
|
||||||
Cand.setAttribute( new DataKey( "selected", 1 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var ClosePanel = function( confirmed )
|
|
||||||
{
|
|
||||||
visualizer.restoreSelection();
|
|
||||||
|
|
||||||
if( confirmed && insert != undefined )
|
|
||||||
visualizer.insertAtCaret( insert() );
|
|
||||||
|
|
||||||
// Posponing this prevents the BackQuoteBinding firing
|
|
||||||
Cycle.next( function() {
|
|
||||||
_self.Present = false;
|
|
||||||
destructor.Destruct();
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
// Advance the input level by CandidateAction
|
|
||||||
this.advanceLevel = function( Candidates, Action, Retreat )
|
|
||||||
{
|
|
||||||
if( ModLevels.length )
|
|
||||||
{
|
|
||||||
ModLevels[0].selected = ModLevels.Cands().Selected().getDAttribute( "key" );
|
|
||||||
}
|
|
||||||
|
|
||||||
ModLevels.unshift([ Candidates, Action, Retreat ]);
|
|
||||||
|
|
||||||
if( 1 < ModLevels.length )
|
|
||||||
{
|
|
||||||
CandidateCycle = -1;
|
|
||||||
stage( Candidates );
|
|
||||||
title( true );
|
|
||||||
stage()[0].value = "`";
|
|
||||||
stage()[0].setAttribute( "placeholder", ModLevels.Cands().desc );
|
|
||||||
BindingBox.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.RetreatLevel = function( sender )
|
|
||||||
{
|
|
||||||
if( ModLevels.length == 1 )
|
|
||||||
{
|
|
||||||
BindingBox.close();
|
|
||||||
destructor.Destruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
ModLevels.shift();
|
|
||||||
|
|
||||||
if( ModLevels.length )
|
|
||||||
{
|
|
||||||
var Cands = ModLevels.Cands();
|
|
||||||
var input = stage( Cands )[0];
|
|
||||||
title( true );
|
|
||||||
input.value
|
|
||||||
= "`" + Cands.Selected().getDAttribute( "key" );
|
|
||||||
|
|
||||||
input.setAttribute( "placeholder", Cands.desc );
|
|
||||||
|
|
||||||
input.selectionStart = 1;
|
|
||||||
input.selectionEnd = input.value.length;
|
|
||||||
BindingBox.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Show = function()
|
|
||||||
{
|
|
||||||
if( _self.Present ) return;
|
|
||||||
visualizer.saveSelection();
|
|
||||||
|
|
||||||
_self.Present = true;
|
|
||||||
|
|
||||||
var MsgBox = new MessageBox(
|
|
||||||
title()
|
|
||||||
, Dand.wrape( stage() )
|
|
||||||
, "Back", false
|
|
||||||
, ClosePanel
|
|
||||||
);
|
|
||||||
|
|
||||||
MsgBox.show();
|
|
||||||
|
|
||||||
var Command = stage()[0];
|
|
||||||
BindingBox = MsgBox;
|
|
||||||
|
|
||||||
Command.focus();
|
|
||||||
|
|
||||||
var DCommand = IDOMElement( Command );
|
|
||||||
var KDown = KeyHandler( Command, HandleInput );
|
|
||||||
var KUp = KeyHandler( Command, TestEmpty );
|
|
||||||
|
|
||||||
DCommand.addEventListener( "KeyDown", KDown );
|
|
||||||
DCommand.addEventListener( "KeyUp", KUp );
|
|
||||||
|
|
||||||
destructor.Register( function() {
|
|
||||||
DCommand.removeEventListener( "KeyDown", KDown );
|
|
||||||
DCommand.removeEventListener( "KeyUp", KUp );
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var MasterInput = function( visualizer )
|
|
||||||
{
|
|
||||||
var Cands = {
|
|
||||||
"Article Reference": { module: "ArticleReference", desc: "Links to other article" }
|
|
||||||
, "Article Content": { module: "ArticleContent", desc: "Put contents of an article" }
|
|
||||||
, "facts": { module: "Facts", desc: "Facts, a fact bubble popup when mouseover" }
|
|
||||||
, "footnote": { module: "Footnote", desc: "Footnote, a footnote displayed at the end of article" }
|
|
||||||
, "h1": { module: "Heading", options: 1, desc: "Heading, size 1" }
|
|
||||||
, "h2": { module: "Heading", options: 2, desc: "Heading, size 2" }
|
|
||||||
, "h3": { module: "Heading", options: 3, desc: "Heading, size 3" }
|
|
||||||
, "h4": { module: "Heading", options: 4, desc: "Heading, size 4" }
|
|
||||||
, "h5": { module: "Heading", options: 5, desc: "Heading, size 5" }
|
|
||||||
};
|
|
||||||
|
|
||||||
var LoadModule = function( mod )
|
|
||||||
{
|
|
||||||
var ldr = new Loader( service_uri, "o" );
|
|
||||||
var ModItem = Cands[ mod ];
|
|
||||||
ldr.load( moduleNs + ModItem.module, function( e ) { ModuleLoaded( mod, e ); } );
|
|
||||||
};
|
|
||||||
|
|
||||||
var InputBox = null;
|
|
||||||
var ModuleLoaded = function( sender, e )
|
|
||||||
{
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
|
|
||||||
var module = new ( __import( e ) )( visualizer, sender );
|
|
||||||
|
|
||||||
var ModItem = Cands[ sender ];
|
|
||||||
|
|
||||||
module.GetCandidates( function( x ) {
|
|
||||||
InputBox.advanceLevel(
|
|
||||||
new Candidates( ModItem.module, ModItem.desc, x )
|
|
||||||
, module.Process.bind( module )
|
|
||||||
, module.Retreat.bind( module )
|
|
||||||
);
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
var BackQuoteBinding = function ( sender, e )
|
|
||||||
{
|
|
||||||
if( !InputBox || InputBox.Disposed )
|
|
||||||
{
|
|
||||||
InputBox = new SmartInput( visualizer );
|
|
||||||
InputBox.advanceLevel(
|
|
||||||
// First level Candidates
|
|
||||||
new Candidates( "Quick Access", "Keyword", Cands )
|
|
||||||
, LoadModule
|
|
||||||
, function( sender, e ) { return sender.value == ""; }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !InputBox.Present && code == 192 )
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
InputBox.Show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
IDOMObject( document ).addEventListener( "KeyDown", KeyHandler( document, BackQuoteBinding ), false );
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "SmartInput", MasterInput );
|
|
||||||
})();
|
|
@ -1,241 +0,0 @@
|
|||||||
(function( ){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {Components.Mouse.ContextMenu} */
|
|
||||||
var ContextMenu = __import( "Components.Mouse.ContextMenu" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMObject} */
|
|
||||||
var IDOMObject = __import( "Dandelion.IDOMObject" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
|
|
||||||
var postFile = __import( "System.Net.postFile" );
|
|
||||||
|
|
||||||
|
|
||||||
var Uploader = function ( set_file_uri )
|
|
||||||
{
|
|
||||||
/** @type {_AstConf_.SiteFile} */
|
|
||||||
var config = Conf.get( "SiteFile" );
|
|
||||||
|
|
||||||
// linkage
|
|
||||||
var busy = false
|
|
||||||
, placedFiles = []
|
|
||||||
, currentFile
|
|
||||||
|
|
||||||
|
|
||||||
// Prepare structure for dockpanel
|
|
||||||
, ptext = Dand.id( "asl_ptext" )
|
|
||||||
, pbar = Dand.id( "asl_pbar_fill" )
|
|
||||||
, ppreview = Dand.id( "asl_preview" )
|
|
||||||
, pfileName = Dand.id( "asl_fileName" )
|
|
||||||
, instruction = Dand.id( "asl_instruction" )
|
|
||||||
, p_status = Dand.id( "asl_u_head" )
|
|
||||||
|
|
||||||
, fileList = Dand.id( "asl_fileList" )
|
|
||||||
, stage = Dand.id( "asl_uploader" )
|
|
||||||
|
|
||||||
|
|
||||||
, uploadProgress = function(e)
|
|
||||||
{
|
|
||||||
var done = e.position || e.loaded
|
|
||||||
, total = e.totalSize || e.total
|
|
||||||
, percentage = String( Math.floor( done / total * 1000 )/10 ) + "%";
|
|
||||||
|
|
||||||
// Set progress
|
|
||||||
ptext.innetText
|
|
||||||
= ptext.textContent
|
|
||||||
= pbar.style.width
|
|
||||||
= percentage;
|
|
||||||
}
|
|
||||||
|
|
||||||
, uploadComplete = function ( response )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var obj = JSON.parse( response );
|
|
||||||
if(obj.status)
|
|
||||||
{
|
|
||||||
currentFile.setStatus( "ok", config.f_host + obj.destination );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
currentFile.setStatus( "error", obj.message );
|
|
||||||
}
|
|
||||||
new ContextMenu( currentFile.stage, currentFile.menuKeys, "LMB", stage );
|
|
||||||
}
|
|
||||||
catch ( ex )
|
|
||||||
{
|
|
||||||
currentFile.setStatus( "error", ex.message );
|
|
||||||
debug.Error( ex );
|
|
||||||
}
|
|
||||||
beginUpload();
|
|
||||||
}
|
|
||||||
|
|
||||||
, beginUpload = function()
|
|
||||||
{
|
|
||||||
busy = true;
|
|
||||||
if( placedFiles.length )
|
|
||||||
{
|
|
||||||
currentFile = placedFiles.pop();
|
|
||||||
if( currentFile )
|
|
||||||
{
|
|
||||||
var file = currentFile.file;
|
|
||||||
|
|
||||||
pfileName.textContent = pfileName.innetText = file.name;
|
|
||||||
|
|
||||||
var fd = new FormData();
|
|
||||||
fd.append( "uploadFile", file );
|
|
||||||
postFile( set_file_uri, fd, { progress: uploadProgress, complete: uploadComplete } );
|
|
||||||
|
|
||||||
currentFile.setStatus("active");
|
|
||||||
instruction.style.marginTop = "-80px";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// deleted file, skip it
|
|
||||||
beginUpload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
busy = false;
|
|
||||||
instruction.style.marginTop = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, clearFileList = function ()
|
|
||||||
{
|
|
||||||
while( fileList.hasChildNodes() )
|
|
||||||
{
|
|
||||||
fileList.removeChild( fileList.firstChild );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, retryUpload = function ()
|
|
||||||
{
|
|
||||||
this.setStatus("pending");
|
|
||||||
placedFiles[placedFiles.length] = this;
|
|
||||||
new ContextMenu( this.stage, this.menuKeys, "RMB", stage );
|
|
||||||
if( !busy ) beginUpload();
|
|
||||||
}
|
|
||||||
|
|
||||||
, removeItem = function ()
|
|
||||||
{
|
|
||||||
this.stage.style.marginTop = "-2em";
|
|
||||||
this.stage.style.opacity = "0";
|
|
||||||
|
|
||||||
if( placedFiles.indexOf(this) != -1 )
|
|
||||||
{
|
|
||||||
delete placedFiles[placedFiles.indexOf(this)];
|
|
||||||
}
|
|
||||||
|
|
||||||
Cycle.delay(function () {
|
|
||||||
fileList.removeChild(this);
|
|
||||||
}.bind(this.stage), 250);
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
fileList.style.paddingTop = String(p_status.clientHeight) + "px";
|
|
||||||
|
|
||||||
|
|
||||||
var docDom = IDOMObject( document );
|
|
||||||
// Drag/drop handlers
|
|
||||||
docDom.addEventListener( "DragOver", function ( e )
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
this.className = "dragged_over";
|
|
||||||
} );
|
|
||||||
docDom.addEventListener( "DragEnd", function () { this.className = ""; } );
|
|
||||||
docDom.addEventListener( "Drop", function ( e )
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
this.className = "";
|
|
||||||
|
|
||||||
// Push files
|
|
||||||
var list = e.dataTransfer.files;
|
|
||||||
for(var i in list)
|
|
||||||
{
|
|
||||||
if(list[i].type != undefined)
|
|
||||||
{
|
|
||||||
var fileItem = new ASLFileItem(list[i], {clear: clearFileList, remove: removeItem, retry: retryUpload});
|
|
||||||
placedFiles[placedFiles.length] = fileItem;
|
|
||||||
|
|
||||||
fileList.appendChild(fileItem.stage);
|
|
||||||
new ContextMenu(fileItem.stage, fileItem.menuKeys, "LMB", stage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!busy) beginUpload();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
var ASLFileItem = function (file, callbacks)
|
|
||||||
{
|
|
||||||
var statusblob = Dand.wrap("span", null, "asl_uItemStat", "\u25CF")
|
|
||||||
, msg
|
|
||||||
, _items = [
|
|
||||||
new EventKey("Remove this item", callbacks.remove.bind(this)) // Reserved for remove item
|
|
||||||
, null // Reserved for retry/ Open link
|
|
||||||
, null // Reserved for get Error message
|
|
||||||
, new EventKey("Clear all", callbacks.clear)
|
|
||||||
]
|
|
||||||
|
|
||||||
, popMessage = function ()
|
|
||||||
{
|
|
||||||
new MessageBox("Upload error", msg).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, getFileLink = function ()
|
|
||||||
{
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
this.stage = Dand.wrap( null, "asl_item" + Perf.uuid, "asl_uItem", [ statusblob, Dand.textNode(file.name) ] );
|
|
||||||
this.file = file;
|
|
||||||
this.menuKeys = _items;
|
|
||||||
|
|
||||||
this.setStatus = function (st, message)
|
|
||||||
{
|
|
||||||
msg = message;
|
|
||||||
switch(st)
|
|
||||||
{
|
|
||||||
case "active":
|
|
||||||
statusblob.style.color = "cornflowerblue";
|
|
||||||
break;
|
|
||||||
case "error":
|
|
||||||
statusblob.style.color = "red";
|
|
||||||
|
|
||||||
_items[1] = new EventKey( "Retry", callbacks.retry.bind(this) );
|
|
||||||
_items[2] = new EventKey( "Whats wrong ?", popMessage );
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "ok":
|
|
||||||
statusblob.style.color = "greenyellow";
|
|
||||||
|
|
||||||
_items[1] = new EventKey( "Copy file link", getFileLink );
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:// pending
|
|
||||||
delete _items[1];
|
|
||||||
delete _items[2];
|
|
||||||
statusblob.style.color = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Uploader", Uploader );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,5 +0,0 @@
|
|||||||
.v_boundary[data-type="AcquireLib"] > span {
|
|
||||||
background-color: #444;
|
|
||||||
color: white;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
|
|
||||||
var acquirelib = function(insertSnippet, snippetWrap, createContext, override)
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var input_text = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"));
|
|
||||||
|
|
||||||
if (this._stage)
|
|
||||||
{
|
|
||||||
input_text.value = this._text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Acquire library" + ( this._stage ? " (Edit)" : "" )
|
|
||||||
, Dand.wrape([ Dand.wrapc( "v_instruction flsf", "Module" ) , input_text ])
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ text:input_text, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function (submitted, override)
|
|
||||||
{
|
|
||||||
var src = override ? override.value : this.text.value
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if (submitted && src)
|
|
||||||
{
|
|
||||||
// Shared clause
|
|
||||||
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
if (!src) return;
|
|
||||||
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrap(
|
|
||||||
'span', null, "flsf"
|
|
||||||
, "AcquireLib: " + src
|
|
||||||
, [ new DataKey( "value", src ) ]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap("AcquireLib", temp, false, 'span'), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement(stage).setAttribute( new DataKey("value", src) );
|
|
||||||
|
|
||||||
stage.removeChild(stage.firstChild);
|
|
||||||
stage.appendChild(Dand.textNode("AcquireLib: " + src));
|
|
||||||
|
|
||||||
// set temp back to stage
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {_text: src, _stage: temp};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext(i, j, handler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
var element = IDOMElement(stage);
|
|
||||||
return "[acquirelib]" + element.getDAttribute("value") + "[/acquirelib]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( acquirelib, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "AcquireLib", acquirelib );
|
|
||||||
})();
|
|
@ -1,7 +0,0 @@
|
|||||||
.v_boundary[data-type="ArticleContent"] {
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_boundary[data-type="ArticleContent"] span.info {
|
|
||||||
color: #f15a24;
|
|
||||||
}
|
|
@ -1,160 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.AstroEdit} */
|
|
||||||
var config = null;
|
|
||||||
|
|
||||||
var ArticleContent = function ( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
config = Config.get( "AstroEdit" );
|
|
||||||
if( !config ) throw new Error( "config is not defined" );
|
|
||||||
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"ArticleContent"
|
|
||||||
, Dand.wrape([
|
|
||||||
Dand.wrapc( "v_instruction", "ArticleContent id:" )
|
|
||||||
, v_snippetInput
|
|
||||||
])
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({
|
|
||||||
id: v_snippetInput
|
|
||||||
, stage: this._stage
|
|
||||||
})
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function ( submitted, override )
|
|
||||||
{
|
|
||||||
|
|
||||||
var id, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
id = unescapeStr( override.value );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = this.id.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var ACInfo = [ "ArticleContent[ ", Dand.wrap( "span", null, "info", id ), " ]" ];
|
|
||||||
if ( submitted && id )
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
temp = Dand.wrapne( "span"
|
|
||||||
, ACInfo
|
|
||||||
, new DataKey( "value", id )
|
|
||||||
);
|
|
||||||
|
|
||||||
insertSnippet(
|
|
||||||
j = snippetWrap(
|
|
||||||
"ArticleContent"
|
|
||||||
, temp
|
|
||||||
, false, "span"
|
|
||||||
)
|
|
||||||
, !!override
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var stg = IDOMElement( stage );
|
|
||||||
|
|
||||||
stg.clear();
|
|
||||||
stg.loot( Dand.wrape( ACInfo ) );
|
|
||||||
stg.setAttribute( new DataKey( "value", id ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {
|
|
||||||
_id: id
|
|
||||||
, _stage: temp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get title of this article
|
|
||||||
postData(
|
|
||||||
config.paths.get_article
|
|
||||||
, { article_id: id }
|
|
||||||
|
|
||||||
/** @param {_AstJson_.AJaxGetArticle} */
|
|
||||||
, function( e )
|
|
||||||
{
|
|
||||||
ACInfo[1].firstChild.textContent = e.entry.title;
|
|
||||||
}
|
|
||||||
, function()
|
|
||||||
{
|
|
||||||
ACInfo[1].firstChild.textContent = "ERROR";
|
|
||||||
} );
|
|
||||||
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
stage = IDOMElement( stage );
|
|
||||||
var options = "";
|
|
||||||
var opt;
|
|
||||||
|
|
||||||
return "[articlecontent]"
|
|
||||||
+ escapeStr( stage.getDAttribute( "value" ) )
|
|
||||||
+ "[/articlecontent]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( ArticleContent, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "ArticleContent", ArticleContent );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,9 +0,0 @@
|
|||||||
.v_boundary[data-type="ArticleLink"]:before {
|
|
||||||
content: "[";
|
|
||||||
}
|
|
||||||
.v_boundary[data-type="ArticleLink"] {
|
|
||||||
color: #f15a24;
|
|
||||||
}
|
|
||||||
.v_boundary[data-type="ArticleLink"]:after {
|
|
||||||
content: "]";
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.AstroEdit} */
|
|
||||||
var config = null;
|
|
||||||
|
|
||||||
var ArticleLink = function ( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
config = Config.get( "AstroEdit" );
|
|
||||||
if( !config ) throw new Error( "config is not defined" );
|
|
||||||
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) )
|
|
||||||
, input_title = Dand.wrap( "input", null, "v_snippet_input_single", null, new IKey( "type", "text" ) )
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._id;
|
|
||||||
input_title.value = this._title;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Link to article"
|
|
||||||
, Dand.wrape([
|
|
||||||
Dand.wrapc( "v_instruction", "Article id:" )
|
|
||||||
, v_snippetInput
|
|
||||||
, Dand.wrapc( "v_instruction", "Title override:" )
|
|
||||||
, input_title
|
|
||||||
])
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({
|
|
||||||
id: v_snippetInput
|
|
||||||
, title: input_title
|
|
||||||
, stage: this._stage
|
|
||||||
})
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function ( submitted, override )
|
|
||||||
{
|
|
||||||
|
|
||||||
var id, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
id = unescapeStr( override.value );
|
|
||||||
title = unescapeStr( override.title ) || "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
id = this.id.value;
|
|
||||||
title = this.title.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( submitted && id )
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
temp = Dand.wrapne( "span"
|
|
||||||
, title || "ArticleLink[" + id + "]"
|
|
||||||
, [
|
|
||||||
new DataKey( "value", id )
|
|
||||||
, new DataKey( "title", title )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
insertSnippet(
|
|
||||||
j = snippetWrap( "ArticleLink", temp, false, "span" )
|
|
||||||
, !!override
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stage.firstChild.textContent = title || "ArticleLink[" + id + "]";
|
|
||||||
|
|
||||||
IDOMElement( stage ).setAttribute([
|
|
||||||
new DataKey( "value", id )
|
|
||||||
, new DataKey( "title", title )
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the default title if not defined
|
|
||||||
if( !title )
|
|
||||||
{
|
|
||||||
postData(
|
|
||||||
config.paths.get_article
|
|
||||||
, { article_id: id }
|
|
||||||
|
|
||||||
/** @param {_AstJson_.AJaxGetArticle} */
|
|
||||||
, function( e )
|
|
||||||
{
|
|
||||||
j.firstChild.textContent = e.entry.title;
|
|
||||||
}
|
|
||||||
, function()
|
|
||||||
{
|
|
||||||
j.firstChild.textContent = "ArticleLink[ ERROR ]";
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {
|
|
||||||
_id: id
|
|
||||||
, _title: title
|
|
||||||
, _stage: temp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
stage = IDOMElement( stage );
|
|
||||||
var options = "";
|
|
||||||
var opt;
|
|
||||||
|
|
||||||
if( opt = stage.getDAttribute( "title" ) )
|
|
||||||
{
|
|
||||||
options += " title=\"" + escapeStr( opt ) + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "[articlelink" + options + "]"
|
|
||||||
+ escapeStr( stage.getDAttribute( "value" ) )
|
|
||||||
+ "[/articlelink]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( ArticleLink, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "ArticleLink", ArticleLink );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,12 +0,0 @@
|
|||||||
.v_boundary[data-inline="on"][data-type="Code"] {
|
|
||||||
display: inline-block;
|
|
||||||
background-color: #EEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_box[data-inline="on"] .v_description {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_box[data-inline="on"] {
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
@ -1,214 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var code = function ( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
, codeLangs = IKey.quickDef(
|
|
||||||
"Plain text" , "plain"
|
|
||||||
, "AS3" , "as3"
|
|
||||||
, "bash" , "bash"
|
|
||||||
, "C#" , "csharp"
|
|
||||||
, "C/C++" , "cpp"
|
|
||||||
, "CSS" , "css"
|
|
||||||
, "php" , "php"
|
|
||||||
, "Python" , "python"
|
|
||||||
, "Perl" , "perl"
|
|
||||||
, "Ruby" , "ruby"
|
|
||||||
, "Html/Xml" , "xml"
|
|
||||||
, "Java" , "java"
|
|
||||||
, "JavaScript" , "js"
|
|
||||||
, "SQL" , "sql"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Private methods
|
|
||||||
, compileListItems = function ()
|
|
||||||
{
|
|
||||||
var arr = [];
|
|
||||||
for ( i in codeLangs )
|
|
||||||
{
|
|
||||||
arr[ arr.length ] = Dand.wrapne(
|
|
||||||
"option"
|
|
||||||
, codeLangs[i].keyName
|
|
||||||
, new IKey( "value", codeLangs[i].keyValue )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Snippet Class structure: handler & visualizer
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" )
|
|
||||||
, v_codelang = Dand.wrap( "select", null, "v_select flsf", compileListItems() )
|
|
||||||
, input_inline = Dand.wrapna( "input", new IKey( "type", "checkbox" ) );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
if ( this._lang )
|
|
||||||
{
|
|
||||||
for ( i = 0; i < codeLangs.length; i ++ )
|
|
||||||
{
|
|
||||||
if ( codeLangs[i].keyValue == this._lang )
|
|
||||||
{
|
|
||||||
v_codelang.selectedIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v_snippetInput.value = this._content || "";
|
|
||||||
input_inline.checked = ( this._inline == "on" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remember the last choice
|
|
||||||
if ( typeof( this.pSnippeCodeChoice ) == "number" )
|
|
||||||
v_codelang.selectedIndex = this.pSnippeCodeChoice;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
( this._stage ? "Edit" : "Insert" ) + " code snippet"
|
|
||||||
, Dand.wrapc(
|
|
||||||
"v_trimmer"
|
|
||||||
, [
|
|
||||||
Dand.wrapc( "v_instruction", v_codelang )
|
|
||||||
, v_snippetInput
|
|
||||||
, Dand.wrape( Dand.wrapne( "label", [ input_inline, "Inline" ] ) )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, "OK", "Cancel"
|
|
||||||
// Switcher
|
|
||||||
, visualizer.bind({ code:v_snippetInput, inline: input_inline, lang: v_codelang, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @type override {_AstXObject_.AstroEdit.Visualizer.Snippet.Code.Override} */
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
var lang, code, inline
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
lang = unescapeStr( override.lang );
|
|
||||||
code = unescapeStr( override.value );
|
|
||||||
inline = override.inline;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lang = this.lang[this.pSnippeCodeChoice = this.lang.selectedIndex].value;
|
|
||||||
code = this.code.value;
|
|
||||||
inline = this.inline.checked ? "on" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var langName;
|
|
||||||
for( var i in codeLangs )
|
|
||||||
{
|
|
||||||
if( codeLangs[i].keyValue == lang )
|
|
||||||
{
|
|
||||||
langName = codeLangs[i].keyName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( submitted && code )
|
|
||||||
{
|
|
||||||
if ( !stage )
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc(
|
|
||||||
"v_box"
|
|
||||||
, [
|
|
||||||
Dand.wrapne( "pre", code )
|
|
||||||
, Dand.wrapc( "v_description", "Script language: " + langName )
|
|
||||||
]
|
|
||||||
, [
|
|
||||||
new DataKey( "value", code )
|
|
||||||
, new DataKey( "lang", lang )
|
|
||||||
, new DataKey( "inline", inline )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
insertSnippet( j = snippetWrap( "Code", temp ), Boolean( override ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute(
|
|
||||||
[
|
|
||||||
new DataKey( "value", code )
|
|
||||||
, new DataKey( "lang", lang )
|
|
||||||
, new DataKey( "inline", inline )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
temp = stage.firstChild;
|
|
||||||
temp.removeChild( temp.firstChild );
|
|
||||||
stage.firstChild.appendChild( Dand.textNode( code ) );
|
|
||||||
|
|
||||||
temp = stage.lastChild;
|
|
||||||
temp.removeChild( temp.firstChild );
|
|
||||||
temp.appendChild( Dand.textNode( "Script language: " + langName ) );
|
|
||||||
|
|
||||||
temp = stage;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _inline: inline, _lang: lang, _content: code, _stage: temp };
|
|
||||||
|
|
||||||
// Set the inline style
|
|
||||||
IDOMElement( j ).setAttribute( new DataKey( "inline", inline ) );
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
// [code lang=\"" + lang + "\"]" + code + "[/code]"
|
|
||||||
var element = IDOMElement( stage )
|
|
||||||
, props= [ "lang", "inline" ];
|
|
||||||
|
|
||||||
return "[code"
|
|
||||||
+ compileProp( element, props )
|
|
||||||
+ "]"
|
|
||||||
+ escapeStr( element.getDAttribute( "value" ) )
|
|
||||||
+ "[/code]"
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( code, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Code", code );
|
|
||||||
})();
|
|
@ -1,3 +0,0 @@
|
|||||||
.v_boundary[data-type="Footnote"] {
|
|
||||||
color: #f15a24;
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
|
|
||||||
var footnote = function( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._mText;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Insert Footnote"
|
|
||||||
, v_snippetInput
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ mText: v_snippetInput, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
|
|
||||||
var mText, stage = this.stage;
|
|
||||||
|
|
||||||
mText = override ? unescapeStr( override.value ) : this.mText.value;
|
|
||||||
|
|
||||||
if (submitted && mText)
|
|
||||||
{
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapne( "span", "^", [
|
|
||||||
new DataKey( "value", mText )
|
|
||||||
]);
|
|
||||||
|
|
||||||
insertSnippet(
|
|
||||||
j = snippetWrap( "Footnote", temp, false, "span" )
|
|
||||||
, Boolean( override )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute(new DataKey( "value", mText ));
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _mText: mText, _stage: temp };
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
// [footnote][/footnote]
|
|
||||||
return "[footnote]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/footnote]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( footnote, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Footnote", footnote );
|
|
||||||
})();
|
|
@ -1,178 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var heading = function ( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
, Sizes = IKey.quickDef(
|
|
||||||
"h1", "h1"
|
|
||||||
, "h2", "h2"
|
|
||||||
, "h3", "h3"
|
|
||||||
, "h4", "h4"
|
|
||||||
, "h5", "h5"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Private methods
|
|
||||||
, compileListItems = function ()
|
|
||||||
{
|
|
||||||
var arr = [];
|
|
||||||
for ( i in Sizes )
|
|
||||||
{
|
|
||||||
arr[ arr.length ] = Dand.wrapne(
|
|
||||||
"option"
|
|
||||||
, Sizes[i].keyName
|
|
||||||
, new IKey( "value", Sizes[i].keyValue )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Snippet Class structure: handler & visualizer
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text") )
|
|
||||||
, v_headingsize = Dand.wrap( "select", null, "v_select flsf", compileListItems() );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
if ( this._size )
|
|
||||||
{
|
|
||||||
for ( i = 0; i < Sizes.length; i ++ )
|
|
||||||
{
|
|
||||||
if ( Sizes[i].keyValue == this._size )
|
|
||||||
{
|
|
||||||
v_headingsize.selectedIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v_snippetInput.value = this._content || "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Remember the last choice
|
|
||||||
if ( typeof( this.pSnippeHeadingChoice ) == "number" )
|
|
||||||
v_headingsize.selectedIndex = this.pSnippeHeadingChoice;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
( this._stage ? "Edit" : "Insert" ) + " heading text"
|
|
||||||
, Dand.wrapc(
|
|
||||||
"v_trimmer"
|
|
||||||
, [
|
|
||||||
v_snippetInput
|
|
||||||
, Dand.wrapc( "v_instruction", v_headingsize )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, "OK", "Cancel"
|
|
||||||
// Switcher
|
|
||||||
, visualizer.bind({ heading:v_snippetInput, size: v_headingsize, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function ( submitted, override )
|
|
||||||
{
|
|
||||||
var size, heading
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
size = unescapeStr( override.size );
|
|
||||||
heading = unescapeStr( override.value );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size = this.size[this.pSnippeHeadingChoice = this.size.selectedIndex].value;
|
|
||||||
heading = this.heading.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
var size;
|
|
||||||
for( var i in Sizes )
|
|
||||||
{
|
|
||||||
if( Sizes[i].keyValue == size )
|
|
||||||
{
|
|
||||||
size = Sizes[i].keyName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( submitted && heading )
|
|
||||||
{
|
|
||||||
if ( !stage )
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapne( "span", Dand.wrapne( size, heading ), [
|
|
||||||
new DataKey( "value", heading )
|
|
||||||
, new DataKey( "size", size )
|
|
||||||
]);
|
|
||||||
|
|
||||||
insertSnippet( j = snippetWrap( "Heading", temp ), Boolean( override ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute([
|
|
||||||
new DataKey( "value", heading )
|
|
||||||
, new DataKey( "size", size )
|
|
||||||
]);
|
|
||||||
|
|
||||||
stage.removeChild( stage.firstChild );
|
|
||||||
stage.appendChild( Dand.wrapne( size, heading ) );
|
|
||||||
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _size: size, _content: heading, _stage: temp };
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
var element = IDOMElement( stage )
|
|
||||||
, props = [ "size" ];
|
|
||||||
|
|
||||||
return "[heading"
|
|
||||||
+ compileProp( element, props )
|
|
||||||
+ "]"
|
|
||||||
+ escapeStr( element.getDAttribute( "value" ) )
|
|
||||||
+ "[/heading]"
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( heading, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Heading", heading );
|
|
||||||
})();
|
|
@ -1,107 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
|
|
||||||
var html = function( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Insert Html snippet"
|
|
||||||
, v_snippetInput
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ code: v_snippetInput, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
var code, stage = this.stage;
|
|
||||||
|
|
||||||
code = override ? unescapeStr( override.value ) : this.code.value;
|
|
||||||
|
|
||||||
if (submitted && code)
|
|
||||||
{
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc(
|
|
||||||
"v_box"
|
|
||||||
, [
|
|
||||||
Dand.wrapne( "pre", code )
|
|
||||||
, Dand.wrapc( "v_description", "Raw Html Codes" )
|
|
||||||
]
|
|
||||||
, [
|
|
||||||
new DataKey( "value", code )
|
|
||||||
, new IKey( "style", "max-height: 150px;" )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap("Html", temp), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute(new DataKey( "value", code ));
|
|
||||||
|
|
||||||
temp = stage.firstChild;
|
|
||||||
temp.removeChild(temp.firstChild);
|
|
||||||
stage.firstChild.appendChild(Dand.textNode( code ));
|
|
||||||
|
|
||||||
temp = stage;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _code: code, _stage: temp };
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
// [html][/html]
|
|
||||||
return "[html]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/html]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( html, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Html", html );
|
|
||||||
})();
|
|
@ -1,173 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var image = function( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var input_url = Dand.wrap(
|
|
||||||
"input", null, "v_snippet_input_single", null, new IKey( "type", "text" )
|
|
||||||
)
|
|
||||||
, input_a = Dand.wrap(
|
|
||||||
"input", null, "v_snippet_input_single", null, new IKey( "type", "text" )
|
|
||||||
)
|
|
||||||
, input_preferred = Dand.wrapna( "input", new IKey( "type", "checkbox" ) )
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
input_url.value = this._url;
|
|
||||||
input_a.value = this._href;
|
|
||||||
input_preferred.checked = ( this._preferred == "on" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
( this._stage ? "Edit" : "Insert" ) + " image snippet",
|
|
||||||
Dand.wrape([
|
|
||||||
Dand.wrapc( "v_instruction flsf", "Link to the image:" )
|
|
||||||
, input_url
|
|
||||||
, Dand.wrapc( "v_instruction flsf", "Ancohr link(optional):" )
|
|
||||||
, input_a
|
|
||||||
, Dand.wrape( Dand.wrapne( "label", [ input_preferred, "Preferred" ] ) )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ url:input_url, href:input_a, stage: this._stage, preferred: input_preferred })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function ( submitted, override )
|
|
||||||
{
|
|
||||||
var src, href, preferred
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
src = unescapeStr( override.value );
|
|
||||||
href = unescapeStr( override.href );
|
|
||||||
preferred = override.preferred ? "on" : "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
src = this.url.value;
|
|
||||||
href = this.href.value;
|
|
||||||
preferred = this.preferred.checked ? "on" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( submitted && src )
|
|
||||||
{
|
|
||||||
|
|
||||||
// Shared clause
|
|
||||||
i = Dand.textNode(href ? ("link to: " + href): "No link");
|
|
||||||
|
|
||||||
if ( !stage )
|
|
||||||
{
|
|
||||||
if ( !src ) return;
|
|
||||||
|
|
||||||
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc(
|
|
||||||
"v_box"
|
|
||||||
, [
|
|
||||||
Dand.wrapna(
|
|
||||||
"img"
|
|
||||||
, [
|
|
||||||
new IKey( "src", src )
|
|
||||||
, new IKey( "style", "max-width: 100%" )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
// caption
|
|
||||||
, Dand.wrapc( "v_description", i )
|
|
||||||
]
|
|
||||||
, [
|
|
||||||
new DataKey( "value", src )
|
|
||||||
, new DataKey( "href", href )
|
|
||||||
, new DataKey( "preferred", preferred )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet( j = snippetWrap( "Image", temp ), Boolean( override ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute
|
|
||||||
([
|
|
||||||
new DataKey( "value", src )
|
|
||||||
, new DataKey( "href", href )
|
|
||||||
, new DataKey( "preferred", preferred )
|
|
||||||
]);
|
|
||||||
|
|
||||||
stage.firstChild.setAttribute("src", src);
|
|
||||||
|
|
||||||
temp = stage.lastChild;
|
|
||||||
temp.removeChild(temp.firstChild);
|
|
||||||
temp.appendChild(i);
|
|
||||||
|
|
||||||
// set temp back to stage
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {
|
|
||||||
_url: src
|
|
||||||
, _href: href
|
|
||||||
, _preferred: preferred || "off"
|
|
||||||
, _stage: temp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
// [img href=\"" + this.href.value + "\"]" + this.url.value + "[/img]
|
|
||||||
var element = IDOMElement( stage )
|
|
||||||
, props = [ "href", "preferred" ]
|
|
||||||
|
|
||||||
return "[img" + compileProp( element, props ) + "]"
|
|
||||||
+ escapeStr( element.getDAttribute( "value" ) )
|
|
||||||
+ "[/img]"
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Alias
|
|
||||||
var alias = "img";
|
|
||||||
|
|
||||||
__static_method( image, "compile", compile );
|
|
||||||
__const( image, "alias", alias );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Image", image );
|
|
||||||
})();
|
|
@ -1,3 +0,0 @@
|
|||||||
.v_boundary[data-type="Link"] {
|
|
||||||
color: #f15a24;
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
|
|
||||||
var link = function(insertSnippet, snippetWrap, createContext, override)
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var input_text = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
, input_a = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"));
|
|
||||||
|
|
||||||
if (this._stage)
|
|
||||||
{
|
|
||||||
input_text.value = this._text;
|
|
||||||
input_a.value = this._href;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
(this._stage ? "Edit" : "Insert") + " link",
|
|
||||||
Dand.wrape([
|
|
||||||
Dand.wrapc("v_instruction flsf", "Text")
|
|
||||||
, input_text
|
|
||||||
, Dand.wrapc("v_instruction flsf", "Link to:")
|
|
||||||
, input_a
|
|
||||||
])
|
|
||||||
, "OK", "Cancel", visualizer.bind({text:input_text, href:input_a, stage: this._stage})).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function (submitted, override)
|
|
||||||
{
|
|
||||||
var src, href
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
src = unescapeStr( override.value );
|
|
||||||
href = unescapeStr( override.href );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
src = this.text.value;
|
|
||||||
href = this.href.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submitted && src && href)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Shared clause
|
|
||||||
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
if (!src) return;
|
|
||||||
|
|
||||||
|
|
||||||
// Visualize component
|
|
||||||
temp =
|
|
||||||
Dand.wrapne("span", src
|
|
||||||
, [
|
|
||||||
new DataKey("value", src)
|
|
||||||
, new DataKey("href", href)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap("Link", temp, false, "span"), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement(stage).setAttribute
|
|
||||||
(
|
|
||||||
[
|
|
||||||
new DataKey("value", src)
|
|
||||||
, new DataKey("href", href)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
stage.removeChild(stage.firstChild);
|
|
||||||
stage.appendChild(Dand.textNode(src));
|
|
||||||
|
|
||||||
// set temp back to stage
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {_text: src, _href: href, _stage: temp};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext(i, j, handler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
// [link href=\"" + this.href.value + "\"]" + text + "[/link]
|
|
||||||
var element = IDOMElement(stage)
|
|
||||||
, href = escapeStr( element.getDAttribute("href") )
|
|
||||||
, val = escapeStr( element.getDAttribute("value") ) ;
|
|
||||||
|
|
||||||
return "[link" + (href ? (" href=\"" + href + "\"") : "") + "]" + val + "[/link]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( link, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Link", link );
|
|
||||||
})();
|
|
@ -1,5 +0,0 @@
|
|||||||
.v_boundary[data-type="Meta"] > span {
|
|
||||||
background-color: #444;
|
|
||||||
color: white;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
|
|
||||||
var meta = function( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Insert Meta Tags"
|
|
||||||
, v_snippetInput
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ code: v_snippetInput, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
var code, stage = this.stage;
|
|
||||||
|
|
||||||
code = override ? unescapeStr( override.value ) : this.code.value;
|
|
||||||
|
|
||||||
if (submitted && code)
|
|
||||||
{
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrap(
|
|
||||||
'span', null, "flsf"
|
|
||||||
, "Meta Tags"
|
|
||||||
, [ new DataKey( "value", code ) ]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap( "Meta", temp, false, "span" ), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute(new DataKey( "value", code ));
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _code: code, _stage: temp };
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
return "[meta]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/meta]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( meta, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Meta", meta );
|
|
||||||
})();
|
|
@ -1,5 +0,0 @@
|
|||||||
.v_boundary[data-type="RespH"] > span {
|
|
||||||
background-color: #444;
|
|
||||||
color: white;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
|
|
||||||
var resph = function( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" );
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Insert Response Headers"
|
|
||||||
, v_snippetInput
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({ code: v_snippetInput, stage: this._stage })
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
var code, stage = this.stage;
|
|
||||||
|
|
||||||
code = override ? unescapeStr( override.value ) : this.code.value;
|
|
||||||
|
|
||||||
if (submitted && code)
|
|
||||||
{
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrap(
|
|
||||||
'span', null, "flsf"
|
|
||||||
, "Response Headers"
|
|
||||||
, [
|
|
||||||
new DataKey( "value", code )
|
|
||||||
, new IKey(
|
|
||||||
"style", "background-color: #444; color: white; padding: 0.2em 0.5em;"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap( "RespH", temp, false, "span" ), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute(new DataKey( "value", code ));
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = { _code: code, _stage: temp };
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
visualizer( true, override );
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
return "[resph]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/resph]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( resph, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "RespH", resph );
|
|
||||||
})();
|
|
@ -1,3 +0,0 @@
|
|||||||
.v_box.sf-view {
|
|
||||||
max-height: 150px;
|
|
||||||
}
|
|
@ -1,289 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {System.Cycle.Trigger} */
|
|
||||||
var Trigger = __import( "System.Cycle.Trigger" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var getData = __import( "System.Net.getData" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.SiteFile} */
|
|
||||||
var config = null;
|
|
||||||
|
|
||||||
var sitefile = function ( insertSnippet, snippetWrap, createContext, override )
|
|
||||||
{
|
|
||||||
config = Config.get( "SiteFile" );
|
|
||||||
if( !config ) throw new Error( "config is not defined" );
|
|
||||||
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
, input_preferred = Dand.wrapna( "input", new IKey( "type", "checkbox" ) )
|
|
||||||
;
|
|
||||||
|
|
||||||
if ( this._stage )
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._content;
|
|
||||||
input_preferred.checked = ( this._preferred == "on" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox(
|
|
||||||
"Insert site file"
|
|
||||||
, Dand.wrape([
|
|
||||||
v_snippetInput
|
|
||||||
, Dand.wrape( Dand.wrapne( "label", [ input_preferred, "Preferred" ] ) )
|
|
||||||
])
|
|
||||||
, "OK", "Cancel"
|
|
||||||
, visualizer.bind({
|
|
||||||
code: v_snippetInput
|
|
||||||
, input_preferred: input_preferred
|
|
||||||
, stage: this._stage
|
|
||||||
})
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, __applyData = function (e)
|
|
||||||
{
|
|
||||||
if( typeof( e ) == "string" )
|
|
||||||
e = JSON.parse(e);
|
|
||||||
|
|
||||||
var _stage = IDOMElement( this.stage );
|
|
||||||
|
|
||||||
var isAlbum = false;
|
|
||||||
// Check if this is an album
|
|
||||||
if( isAlbum = ( "files" in e ) )
|
|
||||||
{
|
|
||||||
e.file = e.files[0];
|
|
||||||
_stage.setAttribute( new DataKey( "collection", 1 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
var s, m, l, o;
|
|
||||||
|
|
||||||
var finfo = e.file;
|
|
||||||
var content = this.stage.firstChild;
|
|
||||||
var desc = this.stage.lastChild;
|
|
||||||
var _hash = finfo.hash;
|
|
||||||
|
|
||||||
switch ( finfo.type )
|
|
||||||
{
|
|
||||||
case "image":
|
|
||||||
|
|
||||||
this.stage.removeChild(content);
|
|
||||||
// Default size is large
|
|
||||||
var _image = Dand.wrapna( "img", new IKey("src", config.path.image.large + _hash + ".jpg") );
|
|
||||||
var keys = [ new IKey( "type", "radio" ), new IKey( "name", "size_grp" + Perf.uuid ) ];
|
|
||||||
var sid;
|
|
||||||
|
|
||||||
var detectImageChange = function() { return _image.complete; };
|
|
||||||
var setImageSizeProp = function()
|
|
||||||
{
|
|
||||||
_stage.setAttribute( new DataKey( "dimensions", _image.naturalWidth + "x" + _image.naturalHeight ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
var selectionChanged = function ()
|
|
||||||
{
|
|
||||||
_stage.setAttribute( new DataKey( "size", this.size ) );
|
|
||||||
//// Handles the size selection
|
|
||||||
switch(this.size)
|
|
||||||
{
|
|
||||||
case "small":
|
|
||||||
_image.setAttribute( "src", config.path.image.small + _hash + ".jpg" );
|
|
||||||
break;
|
|
||||||
case "medium":
|
|
||||||
_image.setAttribute( "src", config.path.image.medium + _hash + ".jpg" );
|
|
||||||
break;
|
|
||||||
case "large":
|
|
||||||
_image.setAttribute( "src", config.path.image.large + _hash + ".jpg" );
|
|
||||||
break;
|
|
||||||
case "original":
|
|
||||||
_image.setAttribute( "src", config.path.image.original + _hash + ".jpg" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Trigger.register( detectImageChange, setImageSizeProp, 100 );
|
|
||||||
};
|
|
||||||
|
|
||||||
Trigger.register( detectImageChange, setImageSizeProp, 100 );
|
|
||||||
this.stage.insertBefore( _image, desc );
|
|
||||||
|
|
||||||
desc.removeChild( desc.firstChild );
|
|
||||||
desc.appendChild(
|
|
||||||
Dand.wrape([
|
|
||||||
Dand.textNode( ( isAlbum ? "[Album] " : "" ) + "Size: ")
|
|
||||||
, s = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) ))
|
|
||||||
, Dand.wrapne("label", "small", new IKey("for", sid))
|
|
||||||
, m = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) ))
|
|
||||||
, Dand.wrapne("label", "medium", new IKey("for", sid))
|
|
||||||
, l = Dand.wrapna("input", keys.concat( new IKey("checked", "1"), new IKey("id", sid = "size_" + Perf.uuid) ))
|
|
||||||
, Dand.wrapne("label", "large (default)", new IKey("for", sid))
|
|
||||||
, o = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) ))
|
|
||||||
, Dand.wrapne("label", "original", new IKey("for", sid))
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
// ad handlers to handles size change event
|
|
||||||
IDOMElement(s).addEventListener("Change", selectionChanged.bind({size: "small"}));
|
|
||||||
IDOMElement(m).addEventListener("Change", selectionChanged.bind({size: "medium"}));
|
|
||||||
IDOMElement(l).addEventListener("Change", selectionChanged.bind({size: "large"}));
|
|
||||||
IDOMElement(o).addEventListener("Change", selectionChanged.bind({size: "original"}));
|
|
||||||
|
|
||||||
var hasValue = _stage.getDAttribute( "size" );
|
|
||||||
if( hasValue )
|
|
||||||
{
|
|
||||||
switch( hasValue )
|
|
||||||
{
|
|
||||||
case "small": s.checked = 1; break;
|
|
||||||
case "medium": m.checked = 1; break;
|
|
||||||
case "large": l.checked = 1; break;
|
|
||||||
case "original": o.checked = 1; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
selectionChanged.bind({ size: hasValue })();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case "audio":
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
content.firstChild.nodeValue = "Regular file: " + finfo.name;
|
|
||||||
content.style.paddingBottom = "2em";
|
|
||||||
content.appendChild( Dand.wrap( "br" ) );
|
|
||||||
content.appendChild( Dand.textNode( "Date: " + XDate.pretty( new Date( finfo.date_created ), true ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, loadFailed = function (e) { }
|
|
||||||
|
|
||||||
, visualizer = function ( submitted, override )
|
|
||||||
{
|
|
||||||
var hash, _obj, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
hash = override.value;
|
|
||||||
preferred = override[ "preferred" ] ? "on" : "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hash = this.code.value;
|
|
||||||
preferred = this.input_preferred.checked ? "on" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
_obj = { file: hash };
|
|
||||||
|
|
||||||
if ( submitted && hash )
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
temp = Dand.wrapc("v_box sf-view"
|
|
||||||
, [
|
|
||||||
Dand.wrape("Getting information from Server ...")
|
|
||||||
, Dand.wrapc("v_description", "Site file (hash): " + hash)
|
|
||||||
]
|
|
||||||
, [
|
|
||||||
new DataKey( "value", hash )
|
|
||||||
, new DataKey( "size", ( override && override.size ) || "large" )
|
|
||||||
, new DataKey( "preferred", preferred )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get data from site library
|
|
||||||
getData( config.path.info + hash, __applyData.bind({stage: temp, hash: hash}), loadFailed );
|
|
||||||
|
|
||||||
insertSnippet(
|
|
||||||
j = snippetWrap( "SiteFile", temp )
|
|
||||||
, !!override
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement( stage ).setAttribute([
|
|
||||||
new DataKey( "value", hash )
|
|
||||||
, new DataKey( "preferred", preferred )
|
|
||||||
]);
|
|
||||||
getData( config.path.info + hash, __applyData.bind({stage: temp, hash: hash}), loadFailed );
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {
|
|
||||||
_content: hash
|
|
||||||
, _preferred: preferred || "off"
|
|
||||||
, _stage: temp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext( i, j, handler );
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
stage = IDOMElement( stage );
|
|
||||||
var options = "";
|
|
||||||
var opt;
|
|
||||||
if( opt = stage.getDAttribute( "collection" ) )
|
|
||||||
{
|
|
||||||
options += " collection=\"1\"";
|
|
||||||
}
|
|
||||||
if( opt = stage.getDAttribute( "size" ) )
|
|
||||||
{
|
|
||||||
options += " size=\"" + opt + "\"";
|
|
||||||
}
|
|
||||||
if( opt = stage.getDAttribute( "dimensions" ) )
|
|
||||||
{
|
|
||||||
options += " dimensions=\"" + opt + "\"";
|
|
||||||
}
|
|
||||||
if( opt = stage.getDAttribute( "preferred" ) )
|
|
||||||
{
|
|
||||||
options += " preferred=\"" + opt + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
return "[sitefile" + options + "]"
|
|
||||||
+ escapeStr( stage.getDAttribute( "value" ) )
|
|
||||||
+ "[/sitefile]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( sitefile, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "SiteFile", sitefile );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,146 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
|
|
||||||
var sound = function (insertSnippet, snippetWrap, createContext, override)
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
, defaultArt = "/assets/blog/layout-images/disc_s.png"
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var input_url = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
, input_albumArt = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
, input_lrc = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
;
|
|
||||||
|
|
||||||
if (this._stage)
|
|
||||||
{
|
|
||||||
input_url.value = this._url;
|
|
||||||
input_albumArt.value = this._albumArt;
|
|
||||||
input_lrc.value = this._lrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
new MessageBox(
|
|
||||||
(this._stage ? "Edit" : "Insert") + " sound snippet"
|
|
||||||
, Dand.wrape([
|
|
||||||
Dand.wrapc("v_instruction flsf", "Link to sound:")
|
|
||||||
, input_url
|
|
||||||
|
|
||||||
, Dand.wrapc("v_instruction flsf", "Link to album art(optional):")
|
|
||||||
, input_albumArt
|
|
||||||
|
|
||||||
, Dand.wrapc("v_instruction flsf", "Link to lrc(optional):")
|
|
||||||
, input_lrc
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, "OK", "Cancel", visualizer.bind({url:input_url, albumArt:input_albumArt, lrc:input_lrc, stage: this._stage})).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function (submitted)
|
|
||||||
{
|
|
||||||
|
|
||||||
var src, albumArt , lrc
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
src = override.url;
|
|
||||||
albumArt = override.albumArt;
|
|
||||||
lrc = override.lrc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
src = this.url.value;
|
|
||||||
albumArt = this.albumArt.value;
|
|
||||||
lrc = this.lrc.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submitted && src)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc('v_box'
|
|
||||||
, [
|
|
||||||
Dand.wrape(null, new IKey
|
|
||||||
(
|
|
||||||
"style", "height: 75px; background-size: auto 75px; background-repeat: no-repeat;"
|
|
||||||
+ "background-image: url(" + (albumArt ? albumArt : defaultArt) + ")"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
, Dand.wrapc('v_description', "Sound snippet")
|
|
||||||
]
|
|
||||||
, [
|
|
||||||
new DataKey("value", "")
|
|
||||||
, new DataKey("url", src)
|
|
||||||
, new DataKey("albumArt", albumArt)
|
|
||||||
, new DataKey("lrc", lrc)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap("Sound", temp), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Edit properties
|
|
||||||
stage.firstChild.style.backgroundImage = "url(" + (albumArt ? albumArt : defaultArt) + ")" ;
|
|
||||||
|
|
||||||
IDOMElement(stage).setAttribute
|
|
||||||
(
|
|
||||||
[
|
|
||||||
new DataKey("url", src)
|
|
||||||
, new DataKey("albumArt", albumArt)
|
|
||||||
, new DataKey("lrc", lrc)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {_url: src, _albumArt: albumArt, _lrc: lrc, _stage: temp};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext(i, j, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
// [sound url="" albumArt="" lrc="" ][/sound]");
|
|
||||||
var element = IDOMElement(stage)
|
|
||||||
, props = ["url", "albumArt", "lrc"];
|
|
||||||
|
|
||||||
return "[sound" + compileProp( element, props ) + "][/sound]";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
__static_method( sound, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Sound", sound );
|
|
||||||
})();
|
|
@ -1,155 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var compileProp = ns[ NS_INVOKE ]( "compileProp" );
|
|
||||||
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
|
|
||||||
var unescapeStr = ns[ NS_INVOKE ]( "unescapeStr" );
|
|
||||||
|
|
||||||
var spoiler = function(insertSnippet, snippetWrap, createContext, override)
|
|
||||||
{
|
|
||||||
var temp, i, j
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var v_snippetInput = Dand.wrap("textarea", null, "v_snippet_input")
|
|
||||||
, input_title = Dand.wrap("input", null, "v_snippet_input_single", null, new IKey("type", "text"))
|
|
||||||
, input_expanded = Dand.wrapna("input", new IKey("type", "checkbox"))
|
|
||||||
|
|
||||||
if (this._stage)
|
|
||||||
{
|
|
||||||
v_snippetInput.value = this._content;
|
|
||||||
input_title.value = this._title;
|
|
||||||
input_expanded.checked = (this._expanded == "on");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox("Insert spoiler content"
|
|
||||||
, Dand.wrape([
|
|
||||||
Dand.wrapc("v_instruction flsf", "Title")
|
|
||||||
, input_title
|
|
||||||
|
|
||||||
, Dand.wrapc("v_instruction flsf", "Content")
|
|
||||||
, v_snippetInput
|
|
||||||
|
|
||||||
, Dand.wrape( Dand.wrapne( "label", [ input_expanded, "Expanded" ] ) )
|
|
||||||
]
|
|
||||||
)
|
|
||||||
, "OK", "Cancel", visualizer.bind({title: input_title, content:v_snippetInput, expanded: input_expanded, stage: this._stage})).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* @type override {_AstXObject_.AstroEdit.Visualizer.Snippet.Spoiler.Override} */
|
|
||||||
, visualizer = function( submitted, override )
|
|
||||||
{
|
|
||||||
var content, title, expanded
|
|
||||||
, stage = this.stage;
|
|
||||||
|
|
||||||
if( override )
|
|
||||||
{
|
|
||||||
content = unescapeStr( override.value );
|
|
||||||
title = unescapeStr( override.title );
|
|
||||||
expanded = override.expanded ? "on" : "";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
content = this.content.value;
|
|
||||||
title = this.title.value;
|
|
||||||
expanded = this.expanded.checked ? "on" : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submitted && content)
|
|
||||||
{
|
|
||||||
// Shared Clause
|
|
||||||
i = Dand.textNode(title || "Spoiler");
|
|
||||||
if (!stage)
|
|
||||||
{
|
|
||||||
if (!content) return;
|
|
||||||
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc("v_box",
|
|
||||||
[
|
|
||||||
// caption
|
|
||||||
Dand.wrapc("v_caption", i)
|
|
||||||
, Dand.textNode(content)
|
|
||||||
],
|
|
||||||
[
|
|
||||||
new DataKey("value", content)
|
|
||||||
, new DataKey("title", title)
|
|
||||||
, new DataKey("expanded", expanded)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
insertSnippet(j = snippetWrap("Spoiler", temp), Boolean(override));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IDOMElement(stage).setAttribute
|
|
||||||
([
|
|
||||||
new DataKey("value", content)
|
|
||||||
, new DataKey("title", title)
|
|
||||||
, new DataKey("expanded", expanded)
|
|
||||||
]);
|
|
||||||
|
|
||||||
temp = stage.firstChild;
|
|
||||||
temp.removeChild(temp.firstChild);
|
|
||||||
temp.appendChild(i);
|
|
||||||
|
|
||||||
stage.removeChild(stage.lastChild);
|
|
||||||
stage.appendChild(Dand.textNode(content));
|
|
||||||
|
|
||||||
// set temp back to stage
|
|
||||||
temp = stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = {
|
|
||||||
_title: title
|
|
||||||
, _content: content
|
|
||||||
, _expanded: expanded || "off"
|
|
||||||
, _stage: temp
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext(i, j, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function ( stage )
|
|
||||||
{
|
|
||||||
var element = IDOMElement( stage )
|
|
||||||
, props = ["title", "expanded"];
|
|
||||||
|
|
||||||
return "[spoiler"
|
|
||||||
+ compileProp( element, props )
|
|
||||||
+ "]"
|
|
||||||
+ escapeStr( element.getDAttribute( "value" ) )
|
|
||||||
+ "[/spoiler]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( spoiler, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Spoiler", spoiler );
|
|
||||||
})();
|
|
@ -1,18 +0,0 @@
|
|||||||
.v_boundary[data-type="Video"] {
|
|
||||||
width: 640px; height: 390px;
|
|
||||||
background-color: black;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_boundary[data-type="Video"] .v_box {
|
|
||||||
width: 640px; height: 390px;
|
|
||||||
position: relative;
|
|
||||||
display: table-cell;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_boundary[data-type="Video"] .v_description {
|
|
||||||
text-align: left;
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
@ -1,141 +0,0 @@
|
|||||||
(function ()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
|
|
||||||
var getData = __import( "System.Net.getData" );
|
|
||||||
var BLANK_IMG = __import( "Dandelion.StaticRes.BLANK_IMG" );
|
|
||||||
|
|
||||||
var video = function (insertSnippet, snippetWrap, createContext, override)
|
|
||||||
{
|
|
||||||
var temp, i, j, imgSrc
|
|
||||||
|
|
||||||
, getVimeoThumbnail = function( v )
|
|
||||||
{
|
|
||||||
getData(
|
|
||||||
"//vimeo.com/api/oembed.json?url=https%3A//vimeo.com/" + v
|
|
||||||
, setThumbnail
|
|
||||||
, noThumb
|
|
||||||
);
|
|
||||||
}
|
|
||||||
, setImgSrc = function( url )
|
|
||||||
{
|
|
||||||
if( imgSrc ) imgSrc.src = url;
|
|
||||||
}
|
|
||||||
, noThumb = function () { }
|
|
||||||
, setThumbnail = function (str)
|
|
||||||
{
|
|
||||||
setImgSrc( JSON.parse(str)["thumbnail_url"] );
|
|
||||||
}
|
|
||||||
|
|
||||||
, handler = function ()
|
|
||||||
{
|
|
||||||
// Input fields
|
|
||||||
var input_url = Dand.wrap('input', null, "v_snippet_input_single", null, new IKey("type", "text"));
|
|
||||||
|
|
||||||
// Popup MessageBox
|
|
||||||
new MessageBox("Insert video snippet"
|
|
||||||
, Dand.wrape([ Dand.wrapc("v_instruction flsf", "Paste a vimeo/Youtube link below:"), input_url ])
|
|
||||||
, "OK", "Cancel", visualizer.bind(input_url)
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
, visualizer = function (submitted, override)
|
|
||||||
{
|
|
||||||
var t, v;
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
v = override.value;
|
|
||||||
i = override.type;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t = this.value;
|
|
||||||
// Match youtube links
|
|
||||||
v = t.match(/\/\/(www\.)?youtube\.com\/watch\?.*?v=([^\&\?\/\#]+)/) || t.match(/\/\/(www\.)?youtube\.com\/embed\/([^\&\?\/]+)/)
|
|
||||||
|| t.match(/\/\/(www\.)?youtube\.com\/v\/([^\&\?\/]+)/) || t.match(/\/\/(www\.)?youtu\.be\/([^\&\?\/]+)/);
|
|
||||||
if (v)
|
|
||||||
{
|
|
||||||
i = "youtube";
|
|
||||||
v = v[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// match vimeo links
|
|
||||||
v = t.match(/\/\/(www\.)?vimeo.com\/(\d+)($|\/)/);
|
|
||||||
if (v)
|
|
||||||
{
|
|
||||||
i = "vimeo";
|
|
||||||
v = v[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// None matched, do nothing
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submitted)
|
|
||||||
{
|
|
||||||
// Visualize component
|
|
||||||
temp = Dand.wrapc('v_box'
|
|
||||||
, [
|
|
||||||
Dand.wrapc( 'v_description', i[0].toUpperCase() + i.substr(1) + ": " + v )
|
|
||||||
, imgSrc = Dand.wrapna( "img", [ new IKey( "src", BLANK_IMG ) ] )
|
|
||||||
]
|
|
||||||
, [ new DataKey("value", v), new DataKey("type", i) ]
|
|
||||||
);
|
|
||||||
|
|
||||||
if( i[0] == "v" )
|
|
||||||
{
|
|
||||||
getVimeoThumbnail( v );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setImgSrc( "//img.youtube.com/vi/" + v + "/hqdefault.jpg" );
|
|
||||||
}
|
|
||||||
|
|
||||||
insertSnippet(j = snippetWrap("Video", temp), Boolean(override));
|
|
||||||
|
|
||||||
// Set context menu
|
|
||||||
createContext(null, j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (override)
|
|
||||||
{
|
|
||||||
visualizer(true, override);
|
|
||||||
override = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compile = function (stage)
|
|
||||||
{
|
|
||||||
// [video type=\"youtube\"]" + v[2] + "[/video]
|
|
||||||
var element = IDOMElement(stage)
|
|
||||||
, type = element.getDAttribute("type");
|
|
||||||
|
|
||||||
return "[video type=\"" + type + "\"]" + element.getDAttribute("value") + "[/video]";
|
|
||||||
};
|
|
||||||
|
|
||||||
__static_method( video, "compile", compile );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Video", video );
|
|
||||||
})();
|
|
@ -1,41 +0,0 @@
|
|||||||
(function()
|
|
||||||
{
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
|
|
||||||
|
|
||||||
var escapeStr = function ( str )
|
|
||||||
{
|
|
||||||
if( !str ) return str;
|
|
||||||
return str
|
|
||||||
.replace( /\[/g, "[" )
|
|
||||||
.replace( /\]/g, "]" )
|
|
||||||
.replace( /"/g, """ )
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
var unescapeStr = function( str )
|
|
||||||
{
|
|
||||||
if( !str ) return str;
|
|
||||||
return str
|
|
||||||
.replace( /[/g, "[" )
|
|
||||||
.replace( /]/g, "]" )
|
|
||||||
.replace( /"/g, "\"" )
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
var compileProp = function ( _iDOM, keys )
|
|
||||||
{
|
|
||||||
var i, j = "", k;
|
|
||||||
for (i in keys)
|
|
||||||
{
|
|
||||||
if( ( k = _iDOM.getDAttribute(keys[i]) ) )
|
|
||||||
{
|
|
||||||
j += " " + keys[i] + "=\"" + escapeStr( k ) + "\"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return j;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_FUNC, "escapeStr", escapeStr );
|
|
||||||
ns[ NS_EXPORT ]( EX_FUNC, "unescapeStr", unescapeStr );
|
|
||||||
ns[ NS_EXPORT ]( EX_FUNC, "compileProp", compileProp );
|
|
||||||
})();
|
|
@ -1,122 +0,0 @@
|
|||||||
.v_snippet_input {
|
|
||||||
width: 600px;
|
|
||||||
height: 350px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_boundary {
|
|
||||||
cursor: default;
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_box {
|
|
||||||
min-height: 3em;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_caption, .v_description {
|
|
||||||
background: rgba(0, 0, 0, 0.8);
|
|
||||||
padding: 0.2em;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
font-family: sans-serif;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_caption {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_description {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_caption_desc {
|
|
||||||
font-size: 60%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_boundary:hover {
|
|
||||||
background-color: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_snippet_input_single {
|
|
||||||
width: 600px;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea.v_snippet_input {
|
|
||||||
font-family: site-mono;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_instruction {
|
|
||||||
padding: 0.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_trimmer {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.v_select {
|
|
||||||
width: 100%;
|
|
||||||
background-color: #222;
|
|
||||||
font-size: 1em;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
background-image: none;
|
|
||||||
border: none;
|
|
||||||
box-shadow: none;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[data-type="token"] {
|
|
||||||
background-color: #111;
|
|
||||||
color: #EEE;
|
|
||||||
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
margin-right: 100%;
|
|
||||||
|
|
||||||
min-width: 8em;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[data-type="token"]:hover {
|
|
||||||
background-color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[data-type="token"]:after {
|
|
||||||
content: "Loading";
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
color: rgba( 255, 255, 255, 0.2 );
|
|
||||||
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[data-type="token"]:hover:after {
|
|
||||||
color: rgba( 255, 255, 255, 0.5 );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_visual_snippets > span[data-name="code"] { background: white; color: cornflowerblue; }
|
|
||||||
#ae_visual_snippets > span[data-name="image"] { background: #ff0084; }
|
|
||||||
#ae_visual_snippets > span[data-name="sound"] { background: YellowGreen; }
|
|
||||||
#ae_visual_snippets > span[data-name="video"] { background: Crimson; }
|
|
||||||
#ae_visual_snippets > span[data-name="spoiler"] { background: cornflowerblue; }
|
|
||||||
#ae_visual_snippets > span[data-name="link"] { background: blue; }
|
|
||||||
#ae_visual_snippets > span[data-name="acquirelib"] { background: black; }
|
|
||||||
#ae_visual_snippets > span[data-name="html"] { background: coral; }
|
|
||||||
#ae_visual_snippets > span[data-name="sitefile"] { background: royalblue; }
|
|
||||||
#ae_visual_snippets > span[data-name="heading"] { }
|
|
||||||
#ae_visual_snippets > span[data-name="footnote"] { }
|
|
||||||
#ae_visual_snippets > span[data-name="resph"] { }
|
|
||||||
#ae_visual_snippets > span[data-name="meta"] { }
|
|
||||||
#ae_visual_snippets > span[data-name="articlelink"] { }
|
|
||||||
#ae_visual_snippets > span[data-name="articlecontent"] { }
|
|
@ -1,503 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.utils} */
|
|
||||||
var utils = __import( "System.utils" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.Net.ClassLoader} */
|
|
||||||
var Loader = __import( "System.Net.ClassLoader" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Components.Mouse.ContextMenu} */
|
|
||||||
var ContextMenu = __import( "Components.Mouse.ContextMenu" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var snippetList = [
|
|
||||||
"Code"
|
|
||||||
, "Image"
|
|
||||||
, "Sound"
|
|
||||||
, "Video"
|
|
||||||
, "Spoiler"
|
|
||||||
, "Link"
|
|
||||||
, "AcquireLib"
|
|
||||||
, "Html"
|
|
||||||
, "SiteFile"
|
|
||||||
, "Heading"
|
|
||||||
, "Footnote"
|
|
||||||
, "RespH"
|
|
||||||
, "Meta"
|
|
||||||
, "ArticleLink"
|
|
||||||
, "ArticleContent"
|
|
||||||
];
|
|
||||||
|
|
||||||
var snippetNs = "Astro.Blog.AstroEdit.Visualizer.Snippet.";
|
|
||||||
//// Document Visualizer visualize snippets, used in AstroEdit and comments
|
|
||||||
var Visualizer = function ( e_document, snippetControls, service_uri )
|
|
||||||
{
|
|
||||||
var Article = ns[ NS_INVOKE ]( "Article" );
|
|
||||||
var loadedModule = {};
|
|
||||||
|
|
||||||
//// Constants
|
|
||||||
var article;
|
|
||||||
// "[^]" does not work in IE
|
|
||||||
var stackMatch = /\[([a-z][0-9a-z]*?)([\s\S]*?)\]([\s\S]*?)\[\/\1\]/ig;
|
|
||||||
var typeMatch = /([a-z][0-9a-z]*)\=\"([^"]+)\"/ig;
|
|
||||||
|
|
||||||
var snippetTokenQueue = {};
|
|
||||||
|
|
||||||
if ( e_document instanceof Article )
|
|
||||||
{
|
|
||||||
article = e_document;
|
|
||||||
// Allow Html snippet
|
|
||||||
}
|
|
||||||
else if ( e_document instanceof CeDocument )
|
|
||||||
{
|
|
||||||
article = e_document;
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
|
|
||||||
////// Variables
|
|
||||||
var contentDiv = Dand.wrap()
|
|
||||||
var selRange;
|
|
||||||
var snippetExists = false;
|
|
||||||
var lastOffset = 0;
|
|
||||||
var raw;
|
|
||||||
|
|
||||||
///// private methods
|
|
||||||
var snippetWrap = function( snippetType, element, editable, _with )
|
|
||||||
{
|
|
||||||
var snippet = Dand.wrap(
|
|
||||||
_with || "div"
|
|
||||||
, Perf.uuid
|
|
||||||
, "comp v_boundary"
|
|
||||||
, element
|
|
||||||
, [
|
|
||||||
new IKey( "contentEditable", editable ? "true" : "false" )
|
|
||||||
, new DataKey( "type", snippetType )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
return snippet;
|
|
||||||
};
|
|
||||||
|
|
||||||
var appendLinebreak = function ()
|
|
||||||
{
|
|
||||||
this.parentNode.insertBefore(Dand.wrap("br"), this.nextSibling);
|
|
||||||
}
|
|
||||||
|
|
||||||
var insertLinebreak = function ()
|
|
||||||
{
|
|
||||||
this.parentNode.insertBefore(Dand.wrap("br"), this);
|
|
||||||
};
|
|
||||||
|
|
||||||
var snippetDelete = function ()
|
|
||||||
{
|
|
||||||
this.parentNode.removeChild(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
var snippetBBCode = function()
|
|
||||||
{
|
|
||||||
var snippet = IDOMElement( this );
|
|
||||||
var type = snippet.getDAttribute( "type" ).toLowerCase();
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */
|
|
||||||
var module = loadedModule[ type ];
|
|
||||||
var title = "An error occurred";
|
|
||||||
var message = "No such module";
|
|
||||||
|
|
||||||
if( module )
|
|
||||||
{
|
|
||||||
title = "BBCode for Snippet: " + type;
|
|
||||||
message = module.compile( this.firstChild );
|
|
||||||
}
|
|
||||||
|
|
||||||
new MessageBox( title, Dand.wrapne( "pre", message ) ).show();
|
|
||||||
};
|
|
||||||
|
|
||||||
var createSnippetMenu = function ( snippetProp, snippet, editHandler, snippetActions )
|
|
||||||
{
|
|
||||||
var contextItems = [
|
|
||||||
editHandler && new EventKey( "Edit", editHandler.bind( snippetProp ) )
|
|
||||||
, new EventKey( "Insert a linebreak", insertLinebreak.bind( snippet ) )
|
|
||||||
, new EventKey( "Append a linebreak", appendLinebreak.bind( snippet ) )
|
|
||||||
, new EventKey( "Delete", snippetDelete.bind( snippet ) )
|
|
||||||
, new EventKey( "View BBCode", snippetBBCode.bind( snippet ) )
|
|
||||||
];
|
|
||||||
|
|
||||||
e_document.updateContent();
|
|
||||||
|
|
||||||
if ( snippetActions instanceof Array )
|
|
||||||
{
|
|
||||||
contextItems = snippetActions.concat( contextItems );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ContextMenu( snippet, contextItems, "RMB" );
|
|
||||||
};
|
|
||||||
|
|
||||||
var _savSelection = function ()
|
|
||||||
{
|
|
||||||
contentDiv.focus();
|
|
||||||
if ( window.getSelection )
|
|
||||||
{
|
|
||||||
var sel = window.getSelection();
|
|
||||||
if ( sel.getRangeAt && sel.rangeCount )
|
|
||||||
{
|
|
||||||
selRange = sel.getRangeAt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( document.selection && document.selection.createRange )
|
|
||||||
{
|
|
||||||
selRange = document.selection.createRange();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
selRange = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var _resSelection = function ()
|
|
||||||
{
|
|
||||||
contentDiv.focus();
|
|
||||||
if ( selRange )
|
|
||||||
{
|
|
||||||
if ( window.getSelection )
|
|
||||||
{
|
|
||||||
var sel = window.getSelection();
|
|
||||||
sel.removeAllRanges();
|
|
||||||
sel.addRange( selRange );
|
|
||||||
}
|
|
||||||
else if ( document.selection && selRange.select )
|
|
||||||
{
|
|
||||||
selRange.select();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var lastLine = Dand.wrap( "br", "v_linebreak" );
|
|
||||||
|
|
||||||
var ensureLastLinebreak = function ()
|
|
||||||
{
|
|
||||||
if( !Dand.id( "v_linebreak" ) )
|
|
||||||
{
|
|
||||||
insertElement( lastLine, true );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
insertElement( contentDiv.removeChild( lastLine ), true );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var insertAtCaret = function( element, newLine )
|
|
||||||
{
|
|
||||||
var sel, range;
|
|
||||||
if( newLine == undefined ) newLine = true;
|
|
||||||
|
|
||||||
sel = window.getSelection();
|
|
||||||
if ( sel.getRangeAt && sel.rangeCount )
|
|
||||||
{
|
|
||||||
range = sel.getRangeAt(0);
|
|
||||||
range.deleteContents();
|
|
||||||
range.insertNode( element );
|
|
||||||
range.setStartAfter( element );
|
|
||||||
range.setEndAfter( element );
|
|
||||||
range.collapse( false );
|
|
||||||
sel.removeAllRanges();
|
|
||||||
sel.addRange( range );
|
|
||||||
}
|
|
||||||
|
|
||||||
e_document.updateContent();
|
|
||||||
|
|
||||||
if( newLine ) ensureLastLinebreak();
|
|
||||||
};
|
|
||||||
|
|
||||||
var insertElement = function( element, override )
|
|
||||||
{
|
|
||||||
if ( override )
|
|
||||||
{
|
|
||||||
contentDiv.appendChild( element );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_resSelection();
|
|
||||||
insertAtCaret( element );
|
|
||||||
};
|
|
||||||
|
|
||||||
var replaceToken = function( element )
|
|
||||||
{
|
|
||||||
contentDiv.insertBefore( element, this.token );
|
|
||||||
contentDiv.removeChild( this.token );
|
|
||||||
};
|
|
||||||
|
|
||||||
var parseKeys = function ( match, name, value )
|
|
||||||
{
|
|
||||||
this[ name ] = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
var snippetQueue = function( type, alias )
|
|
||||||
{
|
|
||||||
var q = snippetTokenQueue[ type ] || [];
|
|
||||||
|
|
||||||
if( alias )
|
|
||||||
{
|
|
||||||
if( !( alias instanceof Array ) ) alias = [ alias ];
|
|
||||||
|
|
||||||
for( var i in alias )
|
|
||||||
{
|
|
||||||
q = snippetTokenQueue[ alias[i] ] || [];
|
|
||||||
if( q.length ) return q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( snippetTokenQueue[ type ] = q );
|
|
||||||
};
|
|
||||||
|
|
||||||
var parseSnippet = function( match, type, properties, _value, offset )
|
|
||||||
{
|
|
||||||
var temp, i, j;
|
|
||||||
// Texts goes first
|
|
||||||
if ( lastOffset != offset )
|
|
||||||
{
|
|
||||||
// innerText does not work in firefox:(
|
|
||||||
temp = Dand.wrape( raw.substr( lastOffset, offset - lastOffset ) );
|
|
||||||
// innerHTML will escape html entities, now replace linebreaks to br
|
|
||||||
temp.innerHTML = temp.innerHTML.replace( /[\r\n]/g, "<br>" );
|
|
||||||
IDOMElement( contentDiv ).loot( temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
lastOffset = offset + match.length;
|
|
||||||
|
|
||||||
// Snippet Args
|
|
||||||
temp = { value: _value };
|
|
||||||
// to ekeys
|
|
||||||
properties.replace( typeMatch, parseKeys.bind( temp ) );
|
|
||||||
|
|
||||||
// Now deal with snippet
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */
|
|
||||||
var _module = loadedModule[ type ];
|
|
||||||
if ( _module )
|
|
||||||
{
|
|
||||||
// Visualize snippet
|
|
||||||
new ( _module )( insertElement, snippetWrap, createSnippetMenu, temp );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no such module, or module is not loaded yet
|
|
||||||
debug.Info( "[Visualizer] Queueing: " + type );
|
|
||||||
var token = snippetWrap( "token", type, false );
|
|
||||||
token.setAttribute( "class", token.getAttribute( "class" ) + " flsf" );
|
|
||||||
snippetQueue( type ).push([ token, temp ]);
|
|
||||||
|
|
||||||
insertElement( token, true );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var linebreakNodes = ["P", "DIV"];
|
|
||||||
var linebreakNode = function( name )
|
|
||||||
{
|
|
||||||
if( -1 < linebreakNodes.indexOf( name.toUpperCase() ) ) return "\n";
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
var ensureGoodness = function ()
|
|
||||||
{
|
|
||||||
_savSelection();
|
|
||||||
ensureLastLinebreak();
|
|
||||||
};
|
|
||||||
|
|
||||||
var stepContent = function ( element, level )
|
|
||||||
{
|
|
||||||
var j , snippetType
|
|
||||||
, elements = element.childNodes
|
|
||||||
, output = "";
|
|
||||||
|
|
||||||
for (var i = 0, l = elements.length; i < l; i ++)
|
|
||||||
{
|
|
||||||
j = elements[i];
|
|
||||||
|
|
||||||
// do nothing on lastline
|
|
||||||
if (j == lastLine) continue;
|
|
||||||
|
|
||||||
if (j.nodeType == 1)
|
|
||||||
{
|
|
||||||
snippetType = IDOMElement( j ).getDAttribute( "type" );
|
|
||||||
if( snippetType && loadedModule[ snippetType = snippetType.toLowerCase() ] )
|
|
||||||
{
|
|
||||||
output += loadedModule[ snippetType ].compile( j.firstChild );
|
|
||||||
}
|
|
||||||
else if ( j.firstChild )
|
|
||||||
{
|
|
||||||
// Text
|
|
||||||
output += linebreakNode( j.nodeName ) + stepContent(j, ++level);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Handle special <div><br></div> => one line break
|
|
||||||
if(l == 1 && j.nodeName.toUpperCase() == "BR") continue;
|
|
||||||
|
|
||||||
// Line breaks
|
|
||||||
output += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Text
|
|
||||||
else if (j.nodeType == 3)
|
|
||||||
{
|
|
||||||
output += j.nodeValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
};
|
|
||||||
|
|
||||||
///// Initializations
|
|
||||||
var snippetReady = function ( e )
|
|
||||||
{
|
|
||||||
// Initialize modules
|
|
||||||
var mod_name = e.substr( e.lastIndexOf(".") + 1, e.length ).toLowerCase()
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Visualizer.Snippet.Model} */
|
|
||||||
var _module = __import( e );
|
|
||||||
var alias = _module.alias;
|
|
||||||
|
|
||||||
// Implement module if valid and available
|
|
||||||
if ( _module && _module.compile )
|
|
||||||
{
|
|
||||||
loadedModule[ mod_name ] = _module;
|
|
||||||
debug.Info( "[Visualizer] Module loaded: " + mod_name );
|
|
||||||
// Set alias
|
|
||||||
if ( alias )
|
|
||||||
{
|
|
||||||
alias = ( alias instanceof Array ) ? alias : [ alias ];
|
|
||||||
|
|
||||||
for ( var k in alias )
|
|
||||||
{
|
|
||||||
loadedModule[ alias[k] ] = _module;
|
|
||||||
debug.Info( "[Visualizer] Alias: " + mod_name + " => " + alias );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append module"s control
|
|
||||||
temp = Dand.wrapne( "span", mod_name, new IKey( "data-name", mod_name ) );
|
|
||||||
|
|
||||||
snippetControls.appendChild( temp );
|
|
||||||
snippetControls.appendChild( Dand.textNode( "\t" ) );
|
|
||||||
temp.onclick = new ( _module )( insertElement, snippetWrap, createSnippetMenu );
|
|
||||||
|
|
||||||
var queue = snippetQueue( mod_name, _module.alias );
|
|
||||||
for( var i in queue )
|
|
||||||
{
|
|
||||||
var token = queue[i];
|
|
||||||
new ( _module )( replaceToken.bind({ token: token[0] }), snippetWrap, createSnippetMenu, token[1] );
|
|
||||||
delete queue[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( _module )
|
|
||||||
{
|
|
||||||
delete loadedModule[ mod_name ];
|
|
||||||
debug.Info( "[Visualizer] Module discarded: invalid module \"" + mod_name + "\"" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug.Info( "[Visualizer] Module \"" + mod_name + "\" does not exists" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.setContentDiv = function( element )
|
|
||||||
{
|
|
||||||
contentDiv = element;
|
|
||||||
// listeners that return values cannot use addEventListener
|
|
||||||
contentDiv.onkeypress = function(e)
|
|
||||||
{
|
|
||||||
if (e.which == 13)
|
|
||||||
{
|
|
||||||
insertAtCaret( Dand.wrap( "br" ) );
|
|
||||||
_savSelection();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
temp = IDOMElement( contentDiv );
|
|
||||||
temp.addEventListener( "Input", ensureGoodness );
|
|
||||||
temp.addEventListener( "KeyUp", ensureGoodness );
|
|
||||||
temp.addEventListener( "Click", ensureGoodness );
|
|
||||||
|
|
||||||
contentDiv.focus();
|
|
||||||
ensureGoodness();
|
|
||||||
|
|
||||||
try {
|
|
||||||
document.execCommand( "insertBrOnReturn", false, "true" );
|
|
||||||
} catch(e) {
|
|
||||||
debug.Info( "Not firefox" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveRaw = function ()
|
|
||||||
{
|
|
||||||
return stepContent( contentDiv, 0 );
|
|
||||||
};
|
|
||||||
|
|
||||||
this.visualizeData = function ( data )
|
|
||||||
{
|
|
||||||
if ( !data ) return;
|
|
||||||
|
|
||||||
lastOffset = 0;
|
|
||||||
// clear content
|
|
||||||
contentDiv.innerHTML = "";
|
|
||||||
|
|
||||||
( raw = data ).replace( stackMatch, parseSnippet );
|
|
||||||
if ( lastOffset != raw.length )
|
|
||||||
{
|
|
||||||
// innerText does not work in firefox:(
|
|
||||||
temp = Dand.wrape( raw.substr( lastOffset, raw.length - lastOffset ) );
|
|
||||||
// innerHTML will escape html entities, now replace linebreaks to br
|
|
||||||
temp.innerHTML = temp.innerHTML.replace( /[\r\n]/g, "<br>" );
|
|
||||||
IDOMElement( contentDiv ).loot( temp );
|
|
||||||
}
|
|
||||||
temp = null;
|
|
||||||
raw = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.saveSelection = _savSelection;
|
|
||||||
this.restoreSelection = _resSelection;
|
|
||||||
this.insertAtCaret = insertAtCaret;
|
|
||||||
|
|
||||||
this.insertSnippet = function( type, options )
|
|
||||||
{
|
|
||||||
var _module = loadedModule[ type ];
|
|
||||||
|
|
||||||
new ( _module )(
|
|
||||||
// Disables the override
|
|
||||||
function( e ) { insertElement( e ); }
|
|
||||||
, snippetWrap, createSnippetMenu, options
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
article.invoke(this);
|
|
||||||
|
|
||||||
var modules = [];
|
|
||||||
for( var i = 0; i < snippetList.length; i ++ )
|
|
||||||
{
|
|
||||||
modules[ modules.length ] = snippetNs + snippetList[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
var ldr = new Loader( service_uri, "o" );
|
|
||||||
ldr.load( modules, snippetReady );
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Visualizer", Visualizer );
|
|
||||||
})();
|
|
@ -1,256 +0,0 @@
|
|||||||
.ae_panel_section {
|
|
||||||
padding: 0 1em;
|
|
||||||
color: white;
|
|
||||||
height: 0;
|
|
||||||
overflow: hidden;;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_section_prop {
|
|
||||||
margin: 0.5em 0;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_prop_name {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_prop_value {
|
|
||||||
font-size: 1.2em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Interactive value */
|
|
||||||
.ae_iValue {
|
|
||||||
text-align: center;
|
|
||||||
padding: 0.5em;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_background {
|
|
||||||
background-color: #fff;
|
|
||||||
background-image:
|
|
||||||
linear-gradient(90deg, transparent 1em, #666 1em, #666 1.2em, transparent 1.2em),
|
|
||||||
linear-gradient(#EEE .1em, transparent .1em);
|
|
||||||
background-size: 100% 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Buttons */
|
|
||||||
.ae_purple { background: purple; }
|
|
||||||
.ae_purple:hover { background: darkmagenta; }
|
|
||||||
.ae_coral { background: orangered; }
|
|
||||||
.ae_coral:hover { background: darkorange; }
|
|
||||||
.ae_dodgerblue { background: dodgerblue; }
|
|
||||||
.ae_caution { color: red; }
|
|
||||||
.ae_caution:hover { background: #333; }
|
|
||||||
.ae_dodgerblue:hover { background: cornflowerblue; }
|
|
||||||
/* End buttons */
|
|
||||||
|
|
||||||
|
|
||||||
.ae_disabled {
|
|
||||||
color: grey;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_blockswitch {
|
|
||||||
line-height: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_blockswitch > span {
|
|
||||||
white-space: nowrap;
|
|
||||||
/* text-transform:uppercase; */
|
|
||||||
font-family: custom-sans;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
cursor: default;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_blockswitch > span:hover {
|
|
||||||
background-color: black;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_body {
|
|
||||||
max-height: 100%;
|
|
||||||
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_content {
|
|
||||||
width: auto;
|
|
||||||
background: SkyBlue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_panel {
|
|
||||||
width: 300px;
|
|
||||||
height: auto;
|
|
||||||
min-height: 100%;
|
|
||||||
background: #222;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
/* will handel mouse scroll later*/
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
-moz-box-shadow: -2px 0 5px black;
|
|
||||||
-webkit-box-shadow: -2px 0 5px black;
|
|
||||||
box-shadow: -2px 0 5px black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_topbar {
|
|
||||||
width: 100%;
|
|
||||||
color: #222;
|
|
||||||
padding: 0.35em 0;
|
|
||||||
overflow: hidden;
|
|
||||||
border-bottom: 7px solid #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.ae_title, .ae_stitle {
|
|
||||||
padding: 0.35em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_title {
|
|
||||||
position: relative;
|
|
||||||
top: 0.25em;
|
|
||||||
font-size: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_stitle:hover {
|
|
||||||
background-color: rgba( 0, 0, 0, 0.2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_stitle {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_title {
|
|
||||||
font-size: 2.5em;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_content {
|
|
||||||
font-size: 100%;
|
|
||||||
margin-bottom: 100%;
|
|
||||||
border-bottom: 1px black dashed;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_title, #ae_content {
|
|
||||||
background: none;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_title:focus {
|
|
||||||
background: rgba(255, 255, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_content:focus {
|
|
||||||
background: rgba(255, 255, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_bgdimmer {
|
|
||||||
background: rgba(255, 255, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_content, #ae_bgdimmer {
|
|
||||||
color: #555;
|
|
||||||
padding: 1em 1em 0.01em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_preview {
|
|
||||||
display: block;
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
padding: 0.4em;
|
|
||||||
font-size: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_user_info {
|
|
||||||
background: #111;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_draft_section {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_draft_logo {
|
|
||||||
font-size: 3em;
|
|
||||||
position: absolute;
|
|
||||||
opacity: 0.2;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_name {
|
|
||||||
text-align: right;
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_user_content {
|
|
||||||
padding: 0.2em
|
|
||||||
}
|
|
||||||
|
|
||||||
#ae_user_drafts {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_dEntry {
|
|
||||||
cursor: default;
|
|
||||||
padding: 0.2em;
|
|
||||||
background: rgba(255, 255, 255, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_dEntry:hover {
|
|
||||||
background: rgba(255, 255, 255, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_dEntry_date {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_expand_btn, .ae_callapse_btn {
|
|
||||||
background: url(/assets/blog/layout-images/collapse.png) center 2.5px no-repeat;
|
|
||||||
width: 100%;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_expand_btn {
|
|
||||||
-webkit-transform: rotate(180deg);
|
|
||||||
-moz-transform: rotate(180deg);
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_callapse_btn {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
-moz-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ae_affected_count {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Active draft notation*/
|
|
||||||
.ae_dActive_bubble {
|
|
||||||
float: right;
|
|
||||||
color: yellowgreen;
|
|
||||||
text-shadow: 0 0 5px yellowgreen;
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0 auto;
|
|
||||||
min-width: 1200px;
|
|
||||||
}
|
|
@ -1,143 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
|
||||||
|
|
||||||
/** @type {System.utils} */
|
|
||||||
var utils = __import( "System.utils" );
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Article} */
|
|
||||||
var Article = __import( "Astro.Blog.AstroEdit.Article" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Draft} */
|
|
||||||
var Draft = __import( "Astro.Blog.AstroEdit.Draft" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Flag} */
|
|
||||||
var Flag = __import( "Astro.Blog.AstroEdit.Flag" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Visualizer} */
|
|
||||||
var Visualizer = __import( "Astro.Blog.AstroEdit.Visualizer" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.Uploader} */
|
|
||||||
var Uploader = __import( "Astro.Blog.AstroEdit.Uploader" );
|
|
||||||
/** @type {Astro.Blog.AstroEdit.SiteLibrary} */
|
|
||||||
var SiteLibrary = __import( "Astro.Blog.AstroEdit.SiteLibrary" );
|
|
||||||
/** @type {Components.Vim.VimArea} */
|
|
||||||
var VimArea = __import( "Components.Vim.VimArea" );
|
|
||||||
|
|
||||||
// calls the smart bar
|
|
||||||
var SmartInput = __import( "Astro.Blog.AstroEdit.SmartInput" );
|
|
||||||
|
|
||||||
// __import( "Astro.Blog.SharedStyle" ); CSS_RESERVATION
|
|
||||||
|
|
||||||
var wh, ww, cw, html, article;
|
|
||||||
|
|
||||||
var init = function ()
|
|
||||||
{
|
|
||||||
//// Component initializations
|
|
||||||
/** @type {_AstConf_.AstroEdit} */
|
|
||||||
var a_conf = Config.get( "AstroEdit" );
|
|
||||||
var base_path = utils.siteProto( Config.get( "BasePath" ) );
|
|
||||||
|
|
||||||
Cycle.next(
|
|
||||||
function()
|
|
||||||
{
|
|
||||||
article.load(
|
|
||||||
a_conf.article_id
|
|
||||||
, function( obj, id )
|
|
||||||
{
|
|
||||||
window.history.replaceState( obj, "", base_path + "astroedit/" + id + "/" );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
article = new Article(
|
|
||||||
a_conf.paths.set_article
|
|
||||||
, [
|
|
||||||
new Flag( "tags", "ae_tags", a_conf.paths.tags )
|
|
||||||
, new Flag( "section", "ae_secs", a_conf.paths.sections )
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Article modules
|
|
||||||
new Draft( article, a_conf.paths.get_drafts );
|
|
||||||
|
|
||||||
var Vis = new Visualizer(
|
|
||||||
article
|
|
||||||
, Dand.id( "ae_visual_snippets" )
|
|
||||||
, Config.get( "ServiceUri" )
|
|
||||||
);
|
|
||||||
|
|
||||||
new SmartInput( Vis );
|
|
||||||
|
|
||||||
// Independent modules
|
|
||||||
new Uploader( a_conf.paths.set_file );
|
|
||||||
new SiteLibrary(
|
|
||||||
base_path
|
|
||||||
, a_conf.paths.get_files
|
|
||||||
, a_conf.paths.set_file
|
|
||||||
);
|
|
||||||
|
|
||||||
var title = Dand.id("ae_title");
|
|
||||||
var content = Dand.id("ae_content");
|
|
||||||
|
|
||||||
// content height
|
|
||||||
content.style.minHeight = String(screen.availHeight) + "px";
|
|
||||||
|
|
||||||
html = document.body.parentNode;
|
|
||||||
|
|
||||||
window.onresize = adjustLayout;
|
|
||||||
|
|
||||||
// Setting event handlers
|
|
||||||
title.onblur = content.onblur = function () { Dand.id("ae_bgdimmer").style.background = ""; };
|
|
||||||
content.onfocus = content.onfocus = function ()
|
|
||||||
{
|
|
||||||
Dand.id("ae_bgdimmer").style.background = "rgba(255, 255, 255, 0.2)";
|
|
||||||
};
|
|
||||||
|
|
||||||
Dand.id( "ae_publish_btn" ).onclick = function () { article.saveAndPublish(); };
|
|
||||||
Dand.id( "ae_preview_btn" ).onclick = function () { article.preview(); };
|
|
||||||
Dand.id( "ae_drop_btn" ).onclick = function () { article.drop(); };;
|
|
||||||
|
|
||||||
adjustLayout();
|
|
||||||
|
|
||||||
VimTrigger();
|
|
||||||
};
|
|
||||||
|
|
||||||
var VimTrigger = function()
|
|
||||||
{
|
|
||||||
var f10Binding = function ( e )
|
|
||||||
{
|
|
||||||
e = e || window.event;
|
|
||||||
if ( e.keyCode ) code = e.keyCode;
|
|
||||||
else if ( e.which ) code = e.which;
|
|
||||||
|
|
||||||
if ( code == 121 )
|
|
||||||
{
|
|
||||||
e.preventDefault();
|
|
||||||
var node = document.activeElement;
|
|
||||||
if( node.nodeName == "TEXTAREA" )
|
|
||||||
{
|
|
||||||
new VimArea( node, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Attach the var with the event = function
|
|
||||||
if(document.addEventListener) document.addEventListener('keydown', f10Binding, false);
|
|
||||||
else if(document.attachEvent) document.attachEvent('onkeydown', f10Binding);
|
|
||||||
else document.onkeydown = f10Binding;
|
|
||||||
};
|
|
||||||
|
|
||||||
var adjustLayout = function ()
|
|
||||||
{
|
|
||||||
ww = html.clientWidth;
|
|
||||||
wh = html.clientHeight;
|
|
||||||
cw = ww - 300;
|
|
||||||
Dand.id("ae_body").style.width = String(cw) + "px";
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
})();
|
|
@ -1,14 +0,0 @@
|
|||||||
.site-file[data-type="album"] {
|
|
||||||
column-width: 225px;
|
|
||||||
column-gap: 0.75em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-file[data-type="album"] > div {
|
|
||||||
display: inline-block;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-file[data-type="album"] > div img {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {System.utils.Perf} **/
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.SiteFile} */
|
|
||||||
var config = null;
|
|
||||||
|
|
||||||
var SiteFile = ns[ NS_INVOKE ]( "SiteFile" );
|
|
||||||
var BLANK_IMG = __import( "Dandelion.StaticRes.BLANK_IMG" );
|
|
||||||
|
|
||||||
var Album = function ( id, hash )
|
|
||||||
{
|
|
||||||
if( !config ) throw new Error( "config is not defined" );
|
|
||||||
var stage = Dand.id( id, true );
|
|
||||||
|
|
||||||
var sf = new SiteFile( id, hash );
|
|
||||||
if( sf.type != "album" ) return;
|
|
||||||
|
|
||||||
var ostage = stage.element;
|
|
||||||
|
|
||||||
var applyStructure = function( obj )
|
|
||||||
{
|
|
||||||
/** @type {_AstJson_.SiteFile} */
|
|
||||||
var finfo = JSON.parse( obj );
|
|
||||||
|
|
||||||
var files = finfo.files;
|
|
||||||
var l = files.length;
|
|
||||||
|
|
||||||
// XXX: Not traditional!
|
|
||||||
// Maximum of 4 for listing
|
|
||||||
if( ostage.parentNode.className == "h_img" && 4 < l )
|
|
||||||
{
|
|
||||||
l = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for( var i = 0; i < l; i ++ )
|
|
||||||
{
|
|
||||||
/** @type {_AstJson_.SiteFile} */
|
|
||||||
var file = files[i];
|
|
||||||
var uuid = Perf.uuid;
|
|
||||||
|
|
||||||
ostage.appendChild( Dand.wrapne(
|
|
||||||
"div"
|
|
||||||
, Dand.wrapna( "img", [ new IKey( "src", BLANK_IMG ) ] )
|
|
||||||
, [ new IKey( "id", uuid ), new DataKey( "size", "medium" ) ]
|
|
||||||
) );
|
|
||||||
|
|
||||||
Cycle.next( function()
|
|
||||||
{
|
|
||||||
new SiteFile( this.id, this.info.hash, this.info );
|
|
||||||
}.bind({ id: uuid, info: file }) );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var loadFailed = function( obj )
|
|
||||||
{
|
|
||||||
console.log( obj );
|
|
||||||
};
|
|
||||||
|
|
||||||
sf.loadInfo( applyStructure, loadFailed );
|
|
||||||
};
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
config = Conf.get( "SiteFile" );
|
|
||||||
if( config )
|
|
||||||
{
|
|
||||||
var SFOs = Conf.get( "SFObjects" );
|
|
||||||
for( var i in SFOs )
|
|
||||||
{
|
|
||||||
var f = SFOs[i];
|
|
||||||
new Album( f[0], f[1] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Album", Album );
|
|
||||||
})();
|
|
@ -1 +0,0 @@
|
|||||||
.ref-content { display: inline-block; }
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.ArticleContent" );
|
|
@ -1,35 +0,0 @@
|
|||||||
.bubble {
|
|
||||||
position: fixed;
|
|
||||||
background: white;
|
|
||||||
border-radius: 300px;
|
|
||||||
|
|
||||||
-moz-box-shadow: 7px 7px 10px;
|
|
||||||
-webkit-box-shadow: 7px 7px 10px;
|
|
||||||
box-shadow: 7px 7px 10px;
|
|
||||||
|
|
||||||
z-index: 98;
|
|
||||||
}
|
|
||||||
|
|
||||||
.innerBubble {
|
|
||||||
border-radius: 300px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.innerBubble:before {
|
|
||||||
content: '';
|
|
||||||
display: inline-block;
|
|
||||||
height: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bInner{
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
vertical-align: middle;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
font-size: 1.35em;
|
|
||||||
color: white;
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
|
|
||||||
var Bubble = function () {
|
|
||||||
this.stage = null;
|
|
||||||
this.bubble = null;
|
|
||||||
|
|
||||||
//// default is somewhat purple
|
|
||||||
this.bgColor = "#662D91";
|
|
||||||
|
|
||||||
this.blowInner = function ()
|
|
||||||
{
|
|
||||||
var b_style = this.bubble.style
|
|
||||||
, s_style = this.stage.style;
|
|
||||||
|
|
||||||
b_style.margin = "10px 10px";
|
|
||||||
b_style.width = "150px";
|
|
||||||
b_style.height = "150px";
|
|
||||||
|
|
||||||
s_style.width = "170px";
|
|
||||||
s_style.height = "170px";
|
|
||||||
s_style.bottom = "20px";
|
|
||||||
s_style.right = "20px";
|
|
||||||
};
|
|
||||||
|
|
||||||
this.blowOuter = function ()
|
|
||||||
{
|
|
||||||
var b_style = this.bubble.style
|
|
||||||
, s_style = this.stage.style;
|
|
||||||
|
|
||||||
b_style.margin = "100px 100px";
|
|
||||||
|
|
||||||
s_style.width = "200px";
|
|
||||||
s_style.height = "200px";
|
|
||||||
s_style.bottom = "10px";
|
|
||||||
s_style.right = "10px";
|
|
||||||
|
|
||||||
Cycle.delay( this.blowInner.bind(this), 250 );
|
|
||||||
};
|
|
||||||
|
|
||||||
this.Void = function ()
|
|
||||||
{
|
|
||||||
this.stage.style.display = "none";
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set Bindings
|
|
||||||
this.init = this.init.bind(this);
|
|
||||||
this.blurp = this.blurp.bind(this);
|
|
||||||
this.pop = this.pop.bind(this);
|
|
||||||
this.setColor = this.setColor.bind(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
var wrapc = function( aClass, elem )
|
|
||||||
{
|
|
||||||
return Dand.wrapc( "comp " + aClass, elem );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bubble.prototype.init = function ()
|
|
||||||
{
|
|
||||||
this.stage = wrapc( "bubble" );
|
|
||||||
this.bubble = wrapc( "innerBubble" );
|
|
||||||
|
|
||||||
var b_style = this.bubble.style
|
|
||||||
, s_style = this.stage.style;
|
|
||||||
|
|
||||||
|
|
||||||
b_style.margin = "85px 85px";
|
|
||||||
b_style.width = "0px";
|
|
||||||
b_style.height = "0px";
|
|
||||||
b_style.background = this.bgColor;
|
|
||||||
b_style.overflow = "hidden";
|
|
||||||
|
|
||||||
this.bubble.appendChild(
|
|
||||||
this.message = wrapc( "bInner flsf" )
|
|
||||||
);
|
|
||||||
|
|
||||||
this.stage.appendChild(this.bubble);
|
|
||||||
|
|
||||||
s_style.display = "none";
|
|
||||||
s_style.width = "10px";
|
|
||||||
s_style.height = "10px";
|
|
||||||
s_style.bottom = "85px";
|
|
||||||
s_style.right = "85px";
|
|
||||||
|
|
||||||
|
|
||||||
// onClick handle to prevent persistent bubble
|
|
||||||
IDOMElement( this.stage ).addEventListener( new EventKey( "Click", this.blurp ) );
|
|
||||||
return this.stage;
|
|
||||||
};
|
|
||||||
|
|
||||||
Bubble.prototype.setColor = function (color)
|
|
||||||
{
|
|
||||||
this.bubble.style.background = color;
|
|
||||||
};
|
|
||||||
|
|
||||||
Bubble.prototype.blurp = function ()
|
|
||||||
{
|
|
||||||
var b_style = this.bubble.style
|
|
||||||
, s_style = this.stage.style;
|
|
||||||
|
|
||||||
b_style.margin = "0 0";
|
|
||||||
b_style.width = "0px";
|
|
||||||
b_style.height = "0px";
|
|
||||||
b_style.overflow = "hidden";
|
|
||||||
|
|
||||||
|
|
||||||
s_style.position = "fixed";
|
|
||||||
s_style.width = "10px";
|
|
||||||
s_style.height = "10px";
|
|
||||||
s_style.bottom = "85px";
|
|
||||||
s_style.right = "85px";
|
|
||||||
|
|
||||||
Cycle.delay( this.Void.bind(this), 250 );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bubble.prototype.pop = function (message)
|
|
||||||
{
|
|
||||||
this.message.innerHTML = message;
|
|
||||||
this.stage.style.display = "block";
|
|
||||||
Cycle.delay( this.blowOuter.bind(this), 100 );
|
|
||||||
};
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Bubble", Bubble );
|
|
||||||
})();
|
|
@ -1,67 +0,0 @@
|
|||||||
.calendar, #timeline {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calendar{
|
|
||||||
position: absolute;
|
|
||||||
display: none;
|
|
||||||
background: white;
|
|
||||||
margin: 20px auto;
|
|
||||||
font-size: 17px;
|
|
||||||
padding: 3px;
|
|
||||||
width: 241px;
|
|
||||||
box-shadow: 3px 3px 4px black;
|
|
||||||
border: 10px solid dodgerblue;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Inline_Blocks*/
|
|
||||||
.calDate, #calDays > div > span {
|
|
||||||
display:-moz-inline-block;
|
|
||||||
display:-moz-inline-box;
|
|
||||||
display:inline-block;
|
|
||||||
}
|
|
||||||
/*End_Inline_Blocks*/
|
|
||||||
|
|
||||||
#calDays > div > span {
|
|
||||||
background: white;
|
|
||||||
border: 0px solid;
|
|
||||||
margin: 1.71428%;
|
|
||||||
padding: 3px 0px 3px 0px;
|
|
||||||
#:100/7 - (0.24% margin);
|
|
||||||
width: 10.857%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
#calDays>div {
|
|
||||||
height: 27px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.calDate {
|
|
||||||
width: 155px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.navbtn {
|
|
||||||
opacity: .5;
|
|
||||||
width: 17px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
.navbtn:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.onhover {
|
|
||||||
border: 3px solid !important;
|
|
||||||
margin-left: -2px !important;
|
|
||||||
margin-top: -4px !important;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0px 1px 2px 0px;
|
|
||||||
box-shadow: 3px 3px 3px black;
|
|
||||||
}
|
|
||||||
.toNorm {
|
|
||||||
}
|
|
||||||
|
|
||||||
#norec{color: #FF7BAC;}
|
|
||||||
#notfin{color: #3FA9F5;}
|
|
||||||
#notyet{color: #BDCCD4;}
|
|
||||||
#today{color: #7AC943;}
|
|
@ -1,244 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
var Calendar = function ()
|
|
||||||
{
|
|
||||||
this.stage = null;
|
|
||||||
this.calDate = null;
|
|
||||||
this.show = false;
|
|
||||||
this.caption = null;
|
|
||||||
this.calDays = false;
|
|
||||||
this.currentHandler = function( v ) {
|
|
||||||
debug.Info( "[Astro.Blog.Components.Calendar] " + v );
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var bodyClick = function ( e )
|
|
||||||
{
|
|
||||||
var s = e.target.getAttribute("calObj")
|
|
||||||
if(s)
|
|
||||||
{
|
|
||||||
this.stage.style.display = "none";
|
|
||||||
this.stage.style.position = "";
|
|
||||||
this.show = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( this.show && !this.istg.contains( e.target ) )
|
|
||||||
{
|
|
||||||
this.stage.style.display = "none";
|
|
||||||
this.stage.style.position = "";
|
|
||||||
this.show = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var addZero = function ( num )
|
|
||||||
{
|
|
||||||
return num < 10
|
|
||||||
? "0" + String(num)
|
|
||||||
: String(num)
|
|
||||||
;
|
|
||||||
};
|
|
||||||
|
|
||||||
Calendar.prototype.init = function()
|
|
||||||
{
|
|
||||||
this.stage = Dand.wrapc( "compx calendar" );
|
|
||||||
this.istg = IDOMElement( this.stage );
|
|
||||||
this.calDate = new Date;
|
|
||||||
|
|
||||||
IDOMElement( document.body ).addEventListener( "Click", bodyClick.bind( this ) );
|
|
||||||
|
|
||||||
var tr = Dand.wrap(null, "navbar")
|
|
||||||
, td = Dand.wrap("span")
|
|
||||||
, btn = Dand.wrap("a", null, "navbtn")
|
|
||||||
;
|
|
||||||
tr.setAttribute("style", "position: relative");
|
|
||||||
|
|
||||||
btn.onclick = function (e) { this.nextMon(); }.bind(this);
|
|
||||||
|
|
||||||
td.style.textAlign = "right";
|
|
||||||
td.style.width = "100%";
|
|
||||||
td.style.position = "absolute";
|
|
||||||
td.style.left = "0";
|
|
||||||
|
|
||||||
btn.appendChild(Dand.textNode("\u25ba"));
|
|
||||||
|
|
||||||
td.appendChild(btn);
|
|
||||||
tr.appendChild(td);
|
|
||||||
|
|
||||||
td = Dand.wrap("span");
|
|
||||||
btn = Dand.wrap("a", null, "navbtn");
|
|
||||||
|
|
||||||
btn.appendChild(Dand.textNode("\u25c4"));
|
|
||||||
|
|
||||||
btn.onclick = function (e) { this.prevMon(); }.bind(this);
|
|
||||||
|
|
||||||
td.style["float"] = "left";
|
|
||||||
td.style.position = "absolute";
|
|
||||||
|
|
||||||
td.appendChild(btn);
|
|
||||||
tr.appendChild(td);
|
|
||||||
|
|
||||||
caption = Dand.wrap("span", null, "calDate");
|
|
||||||
caption.style.width = "100%";
|
|
||||||
caption.appendChild(
|
|
||||||
Dand.textNode(
|
|
||||||
XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
tr.appendChild(caption);
|
|
||||||
|
|
||||||
this.stage.appendChild(tr);
|
|
||||||
|
|
||||||
this.stage.onselectstart = function() { return false;};
|
|
||||||
|
|
||||||
return this.stage;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Calendar.prototype.pop = function ( dateObj, handler )
|
|
||||||
{
|
|
||||||
if( typeof( dateObj ) == "string" )
|
|
||||||
{
|
|
||||||
var p = dateObj.split(",");
|
|
||||||
if ( p.length == 3 )
|
|
||||||
dateObj = new Date( p[2], p[1] - 1, p[0] );
|
|
||||||
}
|
|
||||||
|
|
||||||
this.draw( dateObj, handler );
|
|
||||||
|
|
||||||
this.show = false;
|
|
||||||
|
|
||||||
this.stage.style.display = "block";
|
|
||||||
Cycle.next( function (){ this.show = true; }.bind(this) );
|
|
||||||
};
|
|
||||||
|
|
||||||
Calendar.prototype.draw = function (dateObj, handler)
|
|
||||||
{
|
|
||||||
if(!dateObj)
|
|
||||||
dateObj = new Date;
|
|
||||||
|
|
||||||
this.calDate = dateObj;
|
|
||||||
|
|
||||||
var mon = dateObj.getMonth()
|
|
||||||
, yr = dateObj.getFullYear()
|
|
||||||
, j = dateObj.getDay()
|
|
||||||
, dt = dateObj.getDate()
|
|
||||||
, thisDate = new Date
|
|
||||||
, thisYear = thisDate.getFullYear()
|
|
||||||
, thisMonth = thisDate.getMonth()
|
|
||||||
, thisDate = thisDate.getDate()
|
|
||||||
, thisDate = Number(String(thisYear) + addZero(thisMonth) + addZero(thisDate))
|
|
||||||
, currHead = String(yr) + addZero(mon)
|
|
||||||
, currDate;
|
|
||||||
|
|
||||||
( typeof handler == "function" ) && ( this.currentHandler = handler );
|
|
||||||
|
|
||||||
caption.innerHTML = XDate.MONTH[this.calDate.getMonth()] + ", " + this.calDate.getFullYear();
|
|
||||||
|
|
||||||
if(this.calDays)
|
|
||||||
this.calDays.parentElement.removeChild(this.calDays);
|
|
||||||
this.calDays = Dand.wrap(null, "calDays");
|
|
||||||
|
|
||||||
var days = (mon == 1) ? (yr % 4 == 0 ? 29: 28) : XDate.CAP_MONTHS[mon] ? 30 : 31;
|
|
||||||
for (var i = 0; i < days; i ++)
|
|
||||||
{
|
|
||||||
if(j < 0)
|
|
||||||
j = 6;
|
|
||||||
if(dt - i == 1)
|
|
||||||
break;
|
|
||||||
j --;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tr = Dand.wrap(), td;
|
|
||||||
for(i = 0; i < 7; i ++)
|
|
||||||
{
|
|
||||||
td = Dand.wrap("span");
|
|
||||||
td.appendChild( Dand.textNode( XDate.DAY_ABBR[i] ) );
|
|
||||||
tr.appendChild(td);
|
|
||||||
}
|
|
||||||
this.calDays.appendChild(tr);
|
|
||||||
|
|
||||||
tr = Dand.wrap();
|
|
||||||
for(i = 0; i < j; i ++)
|
|
||||||
{
|
|
||||||
td = Dand.wrap("span");
|
|
||||||
td.style.background = "none";
|
|
||||||
tr.appendChild(td);
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while( i ++ < days )
|
|
||||||
{
|
|
||||||
currDate = Number(currHead + addZero(i));
|
|
||||||
if(j > 6)
|
|
||||||
{
|
|
||||||
j = 0;
|
|
||||||
this.calDays.appendChild(tr);
|
|
||||||
tr = Dand.wrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
td = Dand.wrap( "span" );
|
|
||||||
td.setAttribute( "value", i + "," + (mon + 1) + "," + yr );
|
|
||||||
td.setAttribute( "onmouseover", "className=\"onhover\";" );
|
|
||||||
td.setAttribute( "onmouseout", "className=\"toNorm\";" );
|
|
||||||
// Unique identifier for body click
|
|
||||||
// to test whether choice is chosen
|
|
||||||
td.setAttribute("calObj", "1");
|
|
||||||
|
|
||||||
td.onclick = function ( e )
|
|
||||||
{
|
|
||||||
this.currentHandler( e.target.getAttribute("value") );
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
if(thisDate < currDate)
|
|
||||||
{
|
|
||||||
td.setAttribute("id", "notyet");
|
|
||||||
}
|
|
||||||
else if(thisDate > currDate)
|
|
||||||
{
|
|
||||||
td.setAttribute("id", "norec");
|
|
||||||
/*
|
|
||||||
if(!( book[yr] && book[yr][mon + 1] && book[yr][mon + 1][i] )) {
|
|
||||||
td.setAttribute("id", "norec");
|
|
||||||
} else if(book[yr][mon + 1][i][1]) {
|
|
||||||
td.setAttribute("id", "notfin");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else if(currDate == thisDate)
|
|
||||||
{
|
|
||||||
td.setAttribute("id", "today");
|
|
||||||
currlabel = td;
|
|
||||||
}
|
|
||||||
td.appendChild(Dand.textNode(i));
|
|
||||||
tr.appendChild(td);
|
|
||||||
j ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(j) this.calDays.appendChild(tr);
|
|
||||||
|
|
||||||
this.stage.appendChild(this.calDays);
|
|
||||||
};
|
|
||||||
|
|
||||||
Calendar.prototype.prevMon = function () {
|
|
||||||
this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() - 1 ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
Calendar.prototype.nextMon = function () {
|
|
||||||
this.draw( this.calDate = new Date( this.calDate.getFullYear(), this.calDate.getMonth() + 1 ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "Calendar", Calendar );
|
|
||||||
})();
|
|
@ -1,288 +0,0 @@
|
|||||||
.comment-stage {
|
|
||||||
width: 80%;
|
|
||||||
float: right;
|
|
||||||
padding-bottom: 1em;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_body {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_title {
|
|
||||||
padding: 1em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_bsign {
|
|
||||||
margin-left: -0.47em;
|
|
||||||
padding: 0.1em 0.5em 0.1em 1em;
|
|
||||||
font-size: 2em;
|
|
||||||
color: white;
|
|
||||||
background: cornflowerblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.uc_ntoggle {
|
|
||||||
font-family: custom-sans;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0.2em 0em;
|
|
||||||
}
|
|
||||||
.uc_ntoggle:before { content: '..'; }
|
|
||||||
.uc_ntoggle:after { content: '!'; }
|
|
||||||
|
|
||||||
.cr_ntoggle {
|
|
||||||
font-family: custom-sans;
|
|
||||||
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
|
|
||||||
bottom: 0;
|
|
||||||
right: -3em;
|
|
||||||
|
|
||||||
border-radius: 2em 2em 2em 0em;
|
|
||||||
border: 0.5em solid white;
|
|
||||||
|
|
||||||
line-height: 1.5em !important;
|
|
||||||
|
|
||||||
background-color: white;
|
|
||||||
/* box-shadow: 2px 2px 10px -5px black; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:before, .cr_ntoggle:after {
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:before {
|
|
||||||
content: '..';
|
|
||||||
background-color: slategrey;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:after { content: '!'; }
|
|
||||||
|
|
||||||
.c_comm {
|
|
||||||
position: relative;
|
|
||||||
left: 1.6em;
|
|
||||||
padding-right: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_comm > .c_cont:after {
|
|
||||||
content: "";
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-top: 1em solid transparent;
|
|
||||||
border-bottom: 1em solid transparent;
|
|
||||||
border-right: 1em solid white;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 1em;
|
|
||||||
left: -0.9em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_comm > .c_cont:before {
|
|
||||||
content: "";
|
|
||||||
top: 0;
|
|
||||||
left: -2.15em;
|
|
||||||
position: absolute;
|
|
||||||
background: cornflowerblue;
|
|
||||||
width: 8px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.c_cont {
|
|
||||||
position: relative;
|
|
||||||
background-color: white;
|
|
||||||
padding: 1em;
|
|
||||||
margin-top: 1em;
|
|
||||||
border: 1px solid #D7D4C9
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_text {
|
|
||||||
padding-bottom: 0.5em;
|
|
||||||
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_info > div:first-child, .c_info > div > a {
|
|
||||||
text-align: right;
|
|
||||||
color: #D4145A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_info > div:last-child {
|
|
||||||
text-align: right;
|
|
||||||
color: #AAA;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cu_stack {
|
|
||||||
/* padding 0.5 - 0.2 border width */
|
|
||||||
margin: 0 0 -0.3em 0.3em;
|
|
||||||
position: relative;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cu_stack > div {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cu_avatar {
|
|
||||||
/* Equal to the border width */
|
|
||||||
margin: 0 0 -0.2em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cu_avatar > img {
|
|
||||||
border: 0.2em white solid;
|
|
||||||
box-shadow: 0px 0px 5px 0 black;
|
|
||||||
width: 64px;
|
|
||||||
height: 64px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reply {
|
|
||||||
margin-left: 20%;
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reply > .c_cont:after, .r_indicator {
|
|
||||||
content: "";
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 1em solid transparent;
|
|
||||||
border-right: 1em solid transparent;
|
|
||||||
border-bottom: 1em solid white;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ri_switch[data-pointy="1"] { top: -1em; }
|
|
||||||
|
|
||||||
.c_relative_wrap {
|
|
||||||
position: relative;
|
|
||||||
padding: 1em;
|
|
||||||
|
|
||||||
background: radial-gradient(circle, rgba(0, 0, 0, 0) 10px, #EEE 10px) 0px 10px, #FFF;
|
|
||||||
background-size: 20px 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commentblock {
|
|
||||||
margin-top: 1em;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
#background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
#c_submit {
|
|
||||||
background: cornflowerblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#c_submit:hover {
|
|
||||||
background: cadetblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_reply {
|
|
||||||
background: Coral;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_reply:hover {
|
|
||||||
background: LightCoral;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_tag {
|
|
||||||
cursor: pointer;
|
|
||||||
position: absolute;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100%;
|
|
||||||
width: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.c_tag > span {
|
|
||||||
-moz-transform: rotate(90deg);
|
|
||||||
-moz-transform-origin: 50% 50%;
|
|
||||||
-webkit-transform: rotate(90deg);
|
|
||||||
-webkit-transform-origin: 50% 50%;
|
|
||||||
transform: rotate(90deg);
|
|
||||||
transform-origin: 50% 50%;
|
|
||||||
font-size: 1.5em;
|
|
||||||
display: block;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commentInput {
|
|
||||||
width: 100%;
|
|
||||||
height: 80px;
|
|
||||||
font-size: 1.2em;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_caption {
|
|
||||||
font-size: 1.2em;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_false_input {
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-size: custom-serif;
|
|
||||||
font-style: italic;
|
|
||||||
color: red;
|
|
||||||
text-align: right;
|
|
||||||
height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nocomment {
|
|
||||||
font-size: 1.2em;
|
|
||||||
padding: 1em;
|
|
||||||
background: white;
|
|
||||||
font-family: custom-serif !important;
|
|
||||||
margin: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info_field > div{
|
|
||||||
margin: 0.2em 0;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info_field .website span { width: 20%; }
|
|
||||||
.info_field .website input { width: 80%; }
|
|
||||||
|
|
||||||
iframe[src="about:blank"] {
|
|
||||||
/* recaptcha about:blank page */
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commentblock, #capcha_wrapper, #c_input_panel, .c_comm {
|
|
||||||
-webkit-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-moz-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-ms-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-o-transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
transition: all 500ms cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
|
|
||||||
|
|
||||||
-webkit-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-moz-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-ms-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
-o-transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
|
||||||
transition-timing-function: cubic-bezier(0.770, 0.000, 0.175, 1.000); /* easeInOutQuart */
|
|
||||||
}
|
|
||||||
|
|
||||||
#c_input_panel.reply {
|
|
||||||
max-width: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c_so_sorry {
|
|
||||||
padding: 0.2em;
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: orangered;
|
|
||||||
display: none;
|
|
||||||
}
|
|
@ -1,625 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.Comment" );
|
|
||||||
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.Cycle.Trigger} */
|
|
||||||
var Trigger = __import( "System.Cycle.Trigger" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {System.utils.Perf} */
|
|
||||||
var Perf = __import( "System.utils.Perf" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {Astro.Blog.Components.Bubble} */
|
|
||||||
var Bubble = __import( "Astro.Blog.Components.Bubble" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
/** @type {_3rdParty_.Recaptcha} */
|
|
||||||
var Recaptcha;
|
|
||||||
var RECAPTCHA_SITE_KEY = null;
|
|
||||||
|
|
||||||
/** @type {_AstConf_.UserInfo} */
|
|
||||||
var currentUser = Conf.get( "UserInfo" );
|
|
||||||
/** @type {_AstConf_.Comment} */
|
|
||||||
var Config = Conf.get( "Comment" );
|
|
||||||
/** @type {_AstConf_.Article} */
|
|
||||||
var article = Conf.get( "Article" );
|
|
||||||
|
|
||||||
/*{{{ Validation Methods */
|
|
||||||
var v_match = function( str, regEx )
|
|
||||||
{
|
|
||||||
// Optional string is empty
|
|
||||||
if( !str ) return true;
|
|
||||||
// Not empty, validate
|
|
||||||
if( str.match( regEx ) != null ) return str;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
var validateMail = function ( str )
|
|
||||||
{
|
|
||||||
return v_match( str, /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i );
|
|
||||||
};
|
|
||||||
|
|
||||||
var validateURL = function ( str )
|
|
||||||
{
|
|
||||||
return v_match( str, /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/ );
|
|
||||||
};
|
|
||||||
/* End Validation Methods}}}*/
|
|
||||||
|
|
||||||
var wrapc = Dand.wrapc;
|
|
||||||
|
|
||||||
var init = function ()
|
|
||||||
{
|
|
||||||
// TODO: should add controls to be able to remove comments
|
|
||||||
var contentHaveText = false
|
|
||||||
, nameHaveText = false
|
|
||||||
, fieldReady = false
|
|
||||||
, releaseReplyLock
|
|
||||||
, submit_button
|
|
||||||
, cBubble
|
|
||||||
, button
|
|
||||||
, cHeight = 0
|
|
||||||
, elmH = "1.2em"
|
|
||||||
|
|
||||||
, cp = Dand.id( "c_input_panel" )
|
|
||||||
, contentField = Dand.id( "content_field" )
|
|
||||||
, nameField = Dand.id( "name_field" )
|
|
||||||
, c_body = Dand.id( "comment_body" )
|
|
||||||
|
|
||||||
// If nameField exists, we assume logged in
|
|
||||||
, loggedIn = !nameField
|
|
||||||
|
|
||||||
, contentHadHaveText = false
|
|
||||||
, commentInput = function ()
|
|
||||||
{
|
|
||||||
// trim whitespaces
|
|
||||||
contentHaveText = contentField.value.trim();
|
|
||||||
if( contentHaveText != contentHadHaveText ) {
|
|
||||||
fieldReadyTrigger();
|
|
||||||
contentHadHaveText = contentHaveText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, nameHadHaveText = false
|
|
||||||
, nameInput = function ()
|
|
||||||
{
|
|
||||||
if( !nameField )
|
|
||||||
return;
|
|
||||||
// trim whitespaces
|
|
||||||
nameHaveText = nameField.value.trim();
|
|
||||||
if( nameHadHaveText != nameHaveText ) {
|
|
||||||
fieldReadyTrigger();
|
|
||||||
nameHadHaveText = nameHaveText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, doReply = function ()
|
|
||||||
{
|
|
||||||
var c_reply = this;
|
|
||||||
// This will ensure capcha_wrapper is set
|
|
||||||
fieldReadyTrigger();
|
|
||||||
// Set comment id
|
|
||||||
submit_button.setAttribute( new DataKey( "cid", c_reply.getAttribute( "value" ) ) );
|
|
||||||
|
|
||||||
// close the triangle in the top rigth corner
|
|
||||||
Dand.id( "ri_switch", true ).removeAttribute( "data-pointy" );
|
|
||||||
|
|
||||||
// If this button is not that button
|
|
||||||
button && ( c_reply != button ) && releaseReplyButton();
|
|
||||||
|
|
||||||
// Lock reply button
|
|
||||||
c_reply.setAttribute("locked", "1");
|
|
||||||
c_reply.onclick = null;
|
|
||||||
|
|
||||||
c_reply.style.cursor = "default";
|
|
||||||
c_reply.style.background = "Crimson";
|
|
||||||
c_reply.style.width = "1.2em";
|
|
||||||
c_reply.style.right = "-1.2em";
|
|
||||||
|
|
||||||
// Configure release lock
|
|
||||||
button = c_reply;
|
|
||||||
|
|
||||||
hideSubmit();
|
|
||||||
Cycle.delay( function() {
|
|
||||||
closeInputPanel( function() {
|
|
||||||
cp.classList.add( "reply" );
|
|
||||||
reviveInputpanel.bind( c_reply.parentNode.parentNode )();
|
|
||||||
} );
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
, releaseReplyButton = function ()
|
|
||||||
{
|
|
||||||
button.removeAttribute("locked");
|
|
||||||
button.onclick = doReply.bind(button);
|
|
||||||
button.style.cursor
|
|
||||||
= button.style.background
|
|
||||||
= button.style.width
|
|
||||||
= button.style.right
|
|
||||||
= "";
|
|
||||||
}
|
|
||||||
|
|
||||||
, fieldReadyTrigger = loggedIn
|
|
||||||
? /* Overload */ function ()
|
|
||||||
{
|
|
||||||
submit_button || ( submit_button = Dand.id( "c_submit", true ) );
|
|
||||||
if(contentHaveText)
|
|
||||||
{
|
|
||||||
// show submit button
|
|
||||||
showSubmit();
|
|
||||||
fieldReady = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// hide submit button
|
|
||||||
hideSubmit();
|
|
||||||
fieldReady = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: /* Overload */ function ()
|
|
||||||
{
|
|
||||||
submit_button || ( submit_button = Dand.id( "c_submit", true ) );
|
|
||||||
if(!fieldReady && contentHaveText && nameHaveText)
|
|
||||||
{
|
|
||||||
// show submit button
|
|
||||||
showSubmit();
|
|
||||||
fieldReady = true;
|
|
||||||
}
|
|
||||||
else if(!(contentHaveText || nameHaveText))
|
|
||||||
{
|
|
||||||
// hide submit button
|
|
||||||
hideSubmit();
|
|
||||||
fieldReady = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
, submitComment = loggedIn
|
|
||||||
? /* Overload */ function ()
|
|
||||||
{
|
|
||||||
// Postdata
|
|
||||||
var p = {
|
|
||||||
"article_id": article.id
|
|
||||||
, "name": currentUser.name
|
|
||||||
, "website": currentUser.website
|
|
||||||
, "avatar": currentUser.avatar
|
|
||||||
}
|
|
||||||
// pass-through obj
|
|
||||||
, comment_id = submit_button.getDAttribute( "cid" );
|
|
||||||
|
|
||||||
p.article_id = article.id;
|
|
||||||
// Set comment id if available
|
|
||||||
comment_id && ( p["comment_id"] = comment_id );
|
|
||||||
hideSubmit();
|
|
||||||
|
|
||||||
if( getFieldsValidated(p) )
|
|
||||||
{
|
|
||||||
popBubble();
|
|
||||||
// Post the data, bind obj to Handler
|
|
||||||
postData( Config.processor, p, commentSuccess.bind(p), commentFailed );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cycle.delay( showSubmit, 1500 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: /* Overload */ function ()
|
|
||||||
{
|
|
||||||
var p = { "article_id": article.id }
|
|
||||||
, comment_id = submit_button.getDAttribute( "cid" );
|
|
||||||
|
|
||||||
// Set comment id if available
|
|
||||||
comment_id && ( p["comment_id"] = comment_id );
|
|
||||||
hideSubmit();
|
|
||||||
|
|
||||||
if( getFieldsValidated( p ) )
|
|
||||||
{
|
|
||||||
popBubble();
|
|
||||||
Recaptcha.execute( RECAPTCHA_SITE_KEY, { "action": "submit" } )
|
|
||||||
.then(function( token )
|
|
||||||
{
|
|
||||||
p[ "token" ] = token;
|
|
||||||
// Post the data, bind obj to Handler
|
|
||||||
postData( Config.processor, p, commentSuccess.bind(p), commentFailed );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cycle.delay( showSubmit, 1500 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, commentSuccess = function ( obj )
|
|
||||||
{
|
|
||||||
// Pass Color = Green
|
|
||||||
cBubble.setColor("YellowGreen");
|
|
||||||
|
|
||||||
// Popup Success message
|
|
||||||
cBubble.pop("Success");
|
|
||||||
|
|
||||||
// blurp after 1 sec
|
|
||||||
Cycle.delay( function (){ cBubble.blurp(); }, 1500 );
|
|
||||||
|
|
||||||
generateCommentStack( this, obj );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input panel control
|
|
||||||
, closeInputPanel = function (handler) {
|
|
||||||
cHeight = cp.clientHeight;
|
|
||||||
|
|
||||||
cp.style.transition = "all 0s";
|
|
||||||
|
|
||||||
cp.style.height = cHeight + "px";
|
|
||||||
cp.style.overflow = "hidden";
|
|
||||||
|
|
||||||
// Delay for 10 millisec for establishing transition properties
|
|
||||||
Cycle.next(function() {
|
|
||||||
this.style.transition = "";
|
|
||||||
}.bind(cp));
|
|
||||||
|
|
||||||
Trigger.transition(cp.style, "", function()
|
|
||||||
{
|
|
||||||
cp.style.padding = "0";
|
|
||||||
cp.style.height = "0";
|
|
||||||
});
|
|
||||||
|
|
||||||
// After transition finished, remove input panel
|
|
||||||
Cycle.delay(function()
|
|
||||||
{
|
|
||||||
cp.parentNode.removeChild(cp);
|
|
||||||
// Pass panel to handler
|
|
||||||
if(handler) handler();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
, openInputPanel = function ()
|
|
||||||
{
|
|
||||||
cp.style.padding = "";
|
|
||||||
cp.style.height = cHeight + "px";
|
|
||||||
|
|
||||||
// Delay for 500 millisec waiting for transition finished
|
|
||||||
Cycle.delay(function()
|
|
||||||
{
|
|
||||||
cp.style.transition = "all 0s";
|
|
||||||
cp.style.height = "";
|
|
||||||
cp.style.overflow = "";
|
|
||||||
|
|
||||||
// Pop back up the pointy triangle
|
|
||||||
Dand.id( "ri_switch", true ).setAttribute( new DataKey( "pointy", "1" ) );
|
|
||||||
|
|
||||||
fieldReady = false;
|
|
||||||
fieldReadyTrigger();
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
, reviveInputpanel = function ()
|
|
||||||
{
|
|
||||||
this.appendChild(cp);
|
|
||||||
Cycle.next(openInputPanel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comments submission and handling
|
|
||||||
, commentFailed = function (obj)
|
|
||||||
{
|
|
||||||
// Handle error here to prevent accidental catch by caller
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if(obj != null)
|
|
||||||
{
|
|
||||||
if(obj.reload)
|
|
||||||
{
|
|
||||||
Cycle.delay(showSubmit, 1500);
|
|
||||||
|
|
||||||
Cycle.delay( function()
|
|
||||||
{
|
|
||||||
this.innerHTML = "Recaptcha failure";
|
|
||||||
this.style.height = "1.2em";
|
|
||||||
}.bind(f), 500 );
|
|
||||||
|
|
||||||
Cycle.delay(function (){cBubble.blurp();}, 500);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Reload not needed, serious error had occurred
|
|
||||||
Cycle.delay(function (){cBubble.blurp();}, 500);
|
|
||||||
Cycle.delay(function ()
|
|
||||||
{
|
|
||||||
cBubble.setColor("red");
|
|
||||||
cBubble.pop("Server error");
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Cycle.delay(showSubmit, 1500);
|
|
||||||
Cycle.delay(function (){cBubble.blurp();}, 500);
|
|
||||||
Cycle.delay(function ()
|
|
||||||
{
|
|
||||||
cBubble.setColor("red");
|
|
||||||
cBubble.pop("Cannot connect");
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
debug.Error(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
, submitKey = new EventKey("Click", submitComment)
|
|
||||||
|
|
||||||
, showSubmit = function ()
|
|
||||||
{
|
|
||||||
// prevent multiple prop assign
|
|
||||||
if( !submit_button.hasListener( submitKey ) )
|
|
||||||
{
|
|
||||||
submit_button.style.width = "1.2em";
|
|
||||||
submit_button.style.right = "-1.2em";
|
|
||||||
submit_button.style.cursor = "pointer";
|
|
||||||
}
|
|
||||||
submit_button.addEventListener( submitKey );
|
|
||||||
}
|
|
||||||
|
|
||||||
, hideSubmit = function ()
|
|
||||||
{
|
|
||||||
// prevent multiple prop assign
|
|
||||||
if( submit_button.hasListener( submitKey ) )
|
|
||||||
{
|
|
||||||
submit_button.style.cursor = "default";
|
|
||||||
submit_button.style.width = "";
|
|
||||||
submit_button.style.right = "";
|
|
||||||
}
|
|
||||||
submit_button.removeEventListener( submitKey );
|
|
||||||
}
|
|
||||||
|
|
||||||
, __createContentText = function( text )
|
|
||||||
{
|
|
||||||
var e = wrapc( "c_text", text );
|
|
||||||
e.innerHTML = e.innerHTML.replace( /\n/g, "<br />" );
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
, generateCommentStack = function ( rObj, obj )
|
|
||||||
{
|
|
||||||
|
|
||||||
var
|
|
||||||
// Hold for transitions
|
|
||||||
c_ind, c_cont, cpole
|
|
||||||
// The info stack
|
|
||||||
, _c_info = wrapc("c_info",
|
|
||||||
[
|
|
||||||
wrapc("fls", rObj.website ? Dand.wrapne( "a", rObj.name, IKey.quickDef( "target", "_blank", "href", rObj.website ) ) : rObj.name )
|
|
||||||
, wrapc( "flsf", obj.time )
|
|
||||||
])
|
|
||||||
// loggedIn Overload
|
|
||||||
, c_info = loggedIn
|
|
||||||
? wrapc("cu_stack", [ _c_info
|
|
||||||
, Dand.textNode(" ")
|
|
||||||
, wrapc("cu_avatar"
|
|
||||||
, Dand.wrapna( "img", IKey.quickDef( "src", rObj.avatar, "alt", "avatar" ) )
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
: _c_info
|
|
||||||
// Generate comment stack
|
|
||||||
, c_stack = rObj["comment_id"]
|
|
||||||
// Reply Structure
|
|
||||||
? wrapc("reply", wrapc("c_cont", [ c_ind = wrapc("r_indicator") , __createContentText( rObj.content ) , c_info ]))
|
|
||||||
: wrapc("c_comm",
|
|
||||||
[
|
|
||||||
c_ind = wrapc("c_indicator")
|
|
||||||
, c_cont = wrapc("c_cont", [ cpole = wrapc("cpole") , __createContentText( rObj.content ) , c_info ])
|
|
||||||
]
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
// Remove transition properties
|
|
||||||
c_stack.style.transition = "all 0s";
|
|
||||||
// Close Input panel
|
|
||||||
closeInputPanel( null );
|
|
||||||
|
|
||||||
// Remove false_fields
|
|
||||||
for(var i in fields) {
|
|
||||||
i = Dand.id("false_" + fields[i]);
|
|
||||||
i.parentNode.removeChild(i);
|
|
||||||
}
|
|
||||||
c_stack.style.opacity = 0;
|
|
||||||
cp.parentNode.insertBefore( c_stack, cp );
|
|
||||||
|
|
||||||
c_stack.style.marginTop = ( -c_stack.clientHeight ) + "px";
|
|
||||||
|
|
||||||
// if nocomment notice exist, remove it
|
|
||||||
if( i = Dand.id("nocomment") )
|
|
||||||
{
|
|
||||||
i.style.transition = "all 0s";
|
|
||||||
i.style.width = "658px";
|
|
||||||
i.style.height = "22px";
|
|
||||||
i.style.overflow = "hidden";
|
|
||||||
// transition
|
|
||||||
Cycle.next(function()
|
|
||||||
{
|
|
||||||
this.style.transition = "";
|
|
||||||
this.style.margin = "0";
|
|
||||||
this.style.width = "0";
|
|
||||||
this.style.padding = "0";
|
|
||||||
this.style.height = "0";
|
|
||||||
}.bind(i));
|
|
||||||
// Pending remove
|
|
||||||
Trigger.height(i, 0, function(){ this.parentNode.removeChild(this); }.bind(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay for 10 millisec for establishing transition properties
|
|
||||||
Cycle.next( function() { this.style.transition = ""; }.bind( c_stack ) );
|
|
||||||
|
|
||||||
Cycle.delay(function()
|
|
||||||
{
|
|
||||||
this.style.marginTop = "";
|
|
||||||
this.style.opacity = 1;
|
|
||||||
}.bind(c_stack), 600);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validation
|
|
||||||
, fields = loggedIn ? ["content"] : [ "content", "name", "email", "website", "email_notify" ]
|
|
||||||
, getFieldsValidated = function (obj)
|
|
||||||
{
|
|
||||||
var name, field, falsefield, f;
|
|
||||||
|
|
||||||
for(var i in fields)
|
|
||||||
{
|
|
||||||
name = fields[i];
|
|
||||||
field = name + "_field";
|
|
||||||
falsefield = "false_" + name;
|
|
||||||
|
|
||||||
f = Dand.id( falsefield );
|
|
||||||
if( f ) f.style.height = 0;
|
|
||||||
|
|
||||||
switch(name)
|
|
||||||
{
|
|
||||||
case "name":
|
|
||||||
if(!( obj[name] = Dand.id(field).value.trim() ))
|
|
||||||
Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 );
|
|
||||||
break;
|
|
||||||
case "content":
|
|
||||||
if(!( obj[name] = Dand.id(field).value.trim() ))
|
|
||||||
Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 );
|
|
||||||
break;
|
|
||||||
case "website":
|
|
||||||
if(!( obj[name] = validateURL( Dand.id(field).value.trim() )))
|
|
||||||
{
|
|
||||||
obj[name] = false;
|
|
||||||
Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(obj[name] == true)
|
|
||||||
delete obj[ name ];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "email":
|
|
||||||
if(!( obj[name] = validateMail( Dand.id(field).value.trim() ) ))
|
|
||||||
{
|
|
||||||
obj[name] = false;
|
|
||||||
Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( obj[ name ] == true )
|
|
||||||
delete obj[ name ];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "email_notify":
|
|
||||||
if( obj[ name ] = Dand.id( field ).checked )
|
|
||||||
{
|
|
||||||
if( obj[ "email" ] == undefined )
|
|
||||||
{
|
|
||||||
obj[ name ] = false;
|
|
||||||
Cycle.delay( function() { this.style.height = elmH; }.bind(f), 500 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete obj[ name ];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( var i in obj )
|
|
||||||
if( !obj[i] ) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
, showReplyButton = function ()
|
|
||||||
{
|
|
||||||
this.style.width = "1.2em";
|
|
||||||
this.style.right = "-1.2em";
|
|
||||||
}
|
|
||||||
|
|
||||||
, hideReplyButton = function ()
|
|
||||||
{
|
|
||||||
if(!this.getAttribute("locked"))
|
|
||||||
this.style.width = this.style.right = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
, popBubble = function ()
|
|
||||||
{
|
|
||||||
if(cBubble == null)
|
|
||||||
{
|
|
||||||
// create a new bubble
|
|
||||||
cBubble = new Bubble();
|
|
||||||
document.body.appendChild( cBubble.init() );
|
|
||||||
// pop message
|
|
||||||
cBubble.setColor( "cornflowerblue" );
|
|
||||||
Cycle.next( function () { cBubble.pop("Submitting"); } );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
if( !loggedIn )
|
|
||||||
{
|
|
||||||
IDOMElement( nameField ).addEventListener( "Input", nameInput );
|
|
||||||
}
|
|
||||||
|
|
||||||
IDOMElement( contentField ).addEventListener( "Input", commentInput );
|
|
||||||
|
|
||||||
var l = c_body.childNodes, c_id;
|
|
||||||
|
|
||||||
for( var i in l )
|
|
||||||
{
|
|
||||||
if( l[i].nodeType == 1
|
|
||||||
&& ( c_id = IDOMElement( l[i] ).getDAttribute("value") )
|
|
||||||
)
|
|
||||||
{
|
|
||||||
var reply_button = Dand.id("c_reply_" + c_id);
|
|
||||||
reply_button.onclick = doReply.bind(reply_button);
|
|
||||||
|
|
||||||
l[i].onmouseover = showReplyButton.bind(reply_button);
|
|
||||||
l[i].onmouseout = hideReplyButton.bind(reply_button);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !loggedIn )
|
|
||||||
{
|
|
||||||
var limit = 5;
|
|
||||||
var i = 0;
|
|
||||||
var reUUID = Perf.uuid;
|
|
||||||
RECAPTCHA_SITE_KEY = Dand.id( "recaptcha-js" ).src.split( "?render=" )[1];
|
|
||||||
Cycle.perma(
|
|
||||||
reUUID, function()
|
|
||||||
{
|
|
||||||
if( limit < i ++ )
|
|
||||||
{
|
|
||||||
var mesg = Dand.glass( "c_so_sorry" );
|
|
||||||
if( mesg.length ) mesg[0].style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(( Recaptcha = window["grecaptcha"] ))
|
|
||||||
{
|
|
||||||
Cycle.permaRemove( reUUID );
|
|
||||||
debug.Info( "Recaptcha instance is up" );
|
|
||||||
}
|
|
||||||
} , 500
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cycle.next( nameInput );
|
|
||||||
Cycle.next( commentInput );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
})();
|
|
@ -1,50 +0,0 @@
|
|||||||
.control_panel {
|
|
||||||
height: 100%;
|
|
||||||
margin-top: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control_panel > a {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control_panel > a:after {
|
|
||||||
content: attr(data-desc);
|
|
||||||
|
|
||||||
font-family: custom-sans;
|
|
||||||
|
|
||||||
background-color: rgba(0, 0, 0, 0.6);
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
padding: 0 0.2em;
|
|
||||||
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control_panel > a > span {
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
background-color: orange;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control_panel > div {
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control_panel > div > a {
|
|
||||||
color: #222;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.ControlPanel" );
|
|
@ -1,6 +0,0 @@
|
|||||||
.tags > a {
|
|
||||||
color: saddlebrown;
|
|
||||||
font-family: custom-sans;
|
|
||||||
padding: 0.2em;
|
|
||||||
float: left;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.CrowdTag" );
|
|
@ -1,123 +0,0 @@
|
|||||||
.b_entry img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-code {
|
|
||||||
font-family: site-mono;
|
|
||||||
font-size: 1.12em;
|
|
||||||
|
|
||||||
color: black;
|
|
||||||
background-color: #EEE;
|
|
||||||
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_entry {
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
/* box-shadow: 0 0 8px -2px black; */
|
|
||||||
border: 1px solid #D7D4C9;
|
|
||||||
|
|
||||||
word-wrap: break-word;
|
|
||||||
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
margin-top: 0;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_entry.archived::after {
|
|
||||||
display: block;
|
|
||||||
content: "Archived";
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
background:
|
|
||||||
linear-gradient(-45deg, transparent 36%, black 36%, black 82%, transparent 82%)
|
|
||||||
, linear-gradient(45deg, transparent 36%, black 36%, black 82%, transparent 82%);
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
width: 4.4em;
|
|
||||||
right: -2.25em;
|
|
||||||
top: 1.45em;
|
|
||||||
|
|
||||||
font-size: 1.5em;
|
|
||||||
padding: 0.15em 2.25em;
|
|
||||||
|
|
||||||
transform: rotate(45deg);
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_title {
|
|
||||||
font-family: custom-serif;
|
|
||||||
font-size: 2.5em;
|
|
||||||
margin-bottom: 0.25em;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_avartar {
|
|
||||||
margin: 0 0 0.5em 0.5em;
|
|
||||||
line-height: 0;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
-moz-box-shadow: 2px 2px 5px 0 black;
|
|
||||||
-webkit-box-shadow: 2px 2px 5px 0 black;
|
|
||||||
box-shadow: 2px 2px 5px 0 black;
|
|
||||||
border: 0.4em solid white;
|
|
||||||
|
|
||||||
background-color: white;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_bodyWrapper {
|
|
||||||
color: #555;
|
|
||||||
text-align: justify;
|
|
||||||
min-height: 155px;
|
|
||||||
margin-bottom: 3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_bodyWrapper a { color: #f15a24; }
|
|
||||||
|
|
||||||
.b_edit {
|
|
||||||
background-color: yellowgreen;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_preview {
|
|
||||||
background-color: orangered;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_author {
|
|
||||||
color: purple;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_entry .top-date {
|
|
||||||
float: right;
|
|
||||||
opacity: 0.35;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_entry .top-date:hover {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_date, .b_mdate {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_date {
|
|
||||||
font-family: custom-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_mdate {
|
|
||||||
font-style: italic;
|
|
||||||
font-family: custom-sans;
|
|
||||||
font-size: 0.8em;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_tags > a {
|
|
||||||
font-size: 1em;
|
|
||||||
color: #76400C;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.Entry.Blog" );
|
|
||||||
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
var entry = Dand.id( "b_entry", true );
|
|
||||||
|
|
||||||
var time = new Date( entry.getDAttribute( "time" ) );
|
|
||||||
entry.element.insertBefore(
|
|
||||||
Dand.wrapc(
|
|
||||||
"top-date"
|
|
||||||
, Dand.textNode( XDate.chinese( time ) )
|
|
||||||
)
|
|
||||||
, entry.first( 1 )
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
})();
|
|
@ -1,124 +0,0 @@
|
|||||||
.home_entry {
|
|
||||||
position: relative;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_info {
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 7em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_body {
|
|
||||||
margin-left: 7em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_bodyWrapper {
|
|
||||||
border: 1px solid #D4D7C9;
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
color: #777;
|
|
||||||
|
|
||||||
padding: 1em 1em 2em 1em;
|
|
||||||
|
|
||||||
min-height: 155px;
|
|
||||||
/* Same as image size */
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_datetime {
|
|
||||||
right: 0;
|
|
||||||
bottom: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_auth_com {
|
|
||||||
padding-top: 0.5em;
|
|
||||||
|
|
||||||
font-family: Calibri;
|
|
||||||
color: #D4145A;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.h_avatarWrapper {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_avatar, .a_avatarWrapper {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_avatar {
|
|
||||||
|
|
||||||
border-radius: 80px;
|
|
||||||
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
background-size: 50px 50px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
|
|
||||||
-moz-box-shadow: 2px 2px 5px 0 black;
|
|
||||||
-webkit-box-shadow: 2px 2px 5px 0 black;
|
|
||||||
box-shadow: 2px 2px 5px 0 black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_avatar:hover {
|
|
||||||
width: 70px;
|
|
||||||
height: 70px;
|
|
||||||
border-radius: 70px;
|
|
||||||
|
|
||||||
margin-top: 5px;
|
|
||||||
|
|
||||||
background-size: 60px 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_infoWrapper {
|
|
||||||
padding: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_cCount {
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: cornflowerblue;
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_title {
|
|
||||||
font-size: 2em;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_title, .h_desc {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_read_full {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0.5em;
|
|
||||||
right: 1.5em;
|
|
||||||
|
|
||||||
font-size: 0.8em;
|
|
||||||
text-align: right;
|
|
||||||
padding: 0.5em 0 0.5em 0;
|
|
||||||
color: #F15A24;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_read_full_a {
|
|
||||||
color: #F15A24;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_img {
|
|
||||||
width: 100%;
|
|
||||||
max-height: 350px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h_img img {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.Entry.Home" );
|
|
@ -1,67 +0,0 @@
|
|||||||
.list_entry {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
margin: 1em 0;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
background-color: #FAFAFA;
|
|
||||||
border: 1px solid #D4D7C9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.caption {
|
|
||||||
font-size: 2.5em;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
color: #777;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tags {
|
|
||||||
padding: 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag {
|
|
||||||
font-family: custom-sans;
|
|
||||||
font-size: 0.8em;
|
|
||||||
|
|
||||||
padding: 0 0.5em;
|
|
||||||
margin: 0 0 0 0.2em;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flag.archived { color: white; background: #888; }
|
|
||||||
.flag.archived:hover { background: #666; }
|
|
||||||
|
|
||||||
.flag.featured { color: white; background: coral; }
|
|
||||||
.flag.featured:hover { background: orangered; }
|
|
||||||
|
|
||||||
.tag {
|
|
||||||
color: #76400C;
|
|
||||||
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdate, .author {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.author {
|
|
||||||
color: crimson;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mdate {
|
|
||||||
color: #AAA;
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.Entry.List" );
|
|
@ -1,68 +0,0 @@
|
|||||||
.t_title {
|
|
||||||
font-size: 2.5em;
|
|
||||||
color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ts_title {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive > li {
|
|
||||||
position: relative;
|
|
||||||
padding: 0.5em 0.5em 0.1em;
|
|
||||||
margin: 0.5em;
|
|
||||||
border-right: 1px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive > li:hover {
|
|
||||||
border-right: 1px solid #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive h4 {
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive a {
|
|
||||||
color: #666;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive a:before {
|
|
||||||
content: attr(data-value);
|
|
||||||
|
|
||||||
margin-right: 0.5em;
|
|
||||||
padding: 0.5em;
|
|
||||||
|
|
||||||
float: left;
|
|
||||||
width: 1.4em;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
font-family: custom-sans;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive a:hover:before {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive a:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.n-archive a.Sun:before { color: rgba(255, 29, 37, 1); }
|
|
||||||
ul.n-archive a.Mon:before { color: rgba(102, 45, 145, 1); }
|
|
||||||
ul.n-archive a.Tue:before { color: rgba(63, 169, 245, 1); }
|
|
||||||
ul.n-archive a.Wed:before { color: rgba(122, 201, 67, 1); }
|
|
||||||
ul.n-archive a.Thu:before { color: rgba(255, 123, 172, 1); }
|
|
||||||
ul.n-archive a.Fri:before { color: rgba(96, 56, 19, 1); }
|
|
||||||
ul.n-archive a.Sat:before { color: rgba(255, 147, 30, 1); }
|
|
||||||
ul.n-archive a.Sun:hover:before { color: white; background: rgba(255, 29, 37, 1); }
|
|
||||||
ul.n-archive a.Mon:hover:before { color: white; background: rgba(102, 45, 145, 1); }
|
|
||||||
ul.n-archive a.Tue:hover:before { color: white; background: rgba(63, 169, 245, 1); }
|
|
||||||
ul.n-archive a.Wed:hover:before { color: white; background: rgba(122, 201, 67, 1); }
|
|
||||||
ul.n-archive a.Thu:hover:before { color: white; background: rgba(255, 123, 172, 1); }
|
|
||||||
ul.n-archive a.Fri:hover:before { color: white; background: rgba(96, 56, 19, 1); }
|
|
||||||
ul.n-archive a.Sat:hover:before { color: white; background: rgba(255, 147, 30, 1); }
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.Entry.Tag" );
|
|
@ -1,90 +0,0 @@
|
|||||||
.tile-block {
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
background-image: linear-gradient(
|
|
||||||
135deg, transparent 40%, rgba(0,0,0,.2) 40%, rgba(0,0,0,.2) 60%, transparent 60%
|
|
||||||
)
|
|
||||||
, linear-gradient(
|
|
||||||
225deg, transparent 40%, rgba(0,0,0,.2) 40%, rgba(0,0,0,.2) 60%, transparent 60%
|
|
||||||
)
|
|
||||||
, linear-gradient( 45deg, rgba(0,0,0,.2) 0%, rgba(0,0,0,.2) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 135deg, rgba(0,0,0,.2) 0%, rgba(0,0,0,.2) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 225deg, rgba(0,0,0,.2) 0%, rgba(0,0,0,.2) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 315deg, rgba(0,0,0,.2) 0%, rgba(0,0,0,.2) 10%, transparent 10% )
|
|
||||||
;
|
|
||||||
background-size: 100px 100px;
|
|
||||||
background-color: white;
|
|
||||||
|
|
||||||
border: 1px solid #d4d7c9;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.tile-block .banner {
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
opacity: 0.9;
|
|
||||||
background-color:white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tile-block .banner, .tile-block .link {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tile-block .link {
|
|
||||||
background-color: black;
|
|
||||||
color: white;
|
|
||||||
opacity: 0;
|
|
||||||
text-align: center;
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
padding-top: 55%;
|
|
||||||
|
|
||||||
background-image: linear-gradient(
|
|
||||||
135deg, transparent 40%, rgba(255,255,255,.1) 40%, rgba(255,255,255,.1) 60%, transparent 60%
|
|
||||||
)
|
|
||||||
, linear-gradient(
|
|
||||||
225deg, transparent 40%, rgba(255,255,255,.1) 40%, rgba(255,255,255,.1) 60%, transparent 60%
|
|
||||||
)
|
|
||||||
, linear-gradient( 45deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.1) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 135deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.1) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 225deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.1) 10%, transparent 10% )
|
|
||||||
, linear-gradient( 315deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.1) 10%, transparent 10% )
|
|
||||||
;
|
|
||||||
|
|
||||||
background-size: 100px 100px;
|
|
||||||
background-position: 100% 0;
|
|
||||||
|
|
||||||
-webkit-transition: all 200ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition: all 200ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition: all 200ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition: all 200ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition: all 200ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
|
|
||||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
}
|
|
||||||
|
|
||||||
.tile-block .link:hover {
|
|
||||||
padding-top: 50%;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tile-block .title {
|
|
||||||
margin-top: -0.5em;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.Entry.Tile" );
|
|
@ -1,35 +0,0 @@
|
|||||||
.footnote {
|
|
||||||
padding-top: 0.25em;
|
|
||||||
position: relative;
|
|
||||||
margin-bottom: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote a {
|
|
||||||
color: #f15a24;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote {
|
|
||||||
color: #555;
|
|
||||||
list-style-type: decimal;
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote > li {
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote > li[focused] {
|
|
||||||
background-color: #EE5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footnote:before {
|
|
||||||
content: "";
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
|
|
||||||
width: 40%;
|
|
||||||
|
|
||||||
border-top: 1px black solid;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.Footnote" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
/** @param {Dandelion.IDOMElement} elem */
|
|
||||||
var Footnote = function( elem )
|
|
||||||
{
|
|
||||||
var jumpers = Dand.glass( "ft", true );
|
|
||||||
if( !jumpers.length ) return;
|
|
||||||
|
|
||||||
var notes = Dand.glass( "footnote", true )[0];
|
|
||||||
|
|
||||||
jumpers.forEach( function( e ) {
|
|
||||||
|
|
||||||
var a = e.first( 1 );
|
|
||||||
IDOMElement( a ).addEventListener( "Click", function()
|
|
||||||
{
|
|
||||||
var clicked = a.hash.substr( 1 );
|
|
||||||
notes.foreach( 1, function( e ) {
|
|
||||||
if( e.id == clicked )
|
|
||||||
{
|
|
||||||
e.setAttribute( "focused", 1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e.removeAttribute( "focused" );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit(function() {
|
|
||||||
new Footnote();
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
@ -1,172 +0,0 @@
|
|||||||
.notifications {
|
|
||||||
float: right;
|
|
||||||
cursor: default;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_body {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
left: -300px;
|
|
||||||
|
|
||||||
max-width: 300px;
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
display: none;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_body > div { float: right; }
|
|
||||||
|
|
||||||
.nt_button {
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
text-align: left;
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
padding: 0 0.5em 0 0;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
background-color: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_button:before {
|
|
||||||
content: attr(data-count);
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
padding: 0 0.5em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
line-height: 2em;
|
|
||||||
|
|
||||||
background-color: royalblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_button:before, .nt_switch:before, .nt_icon_settings {
|
|
||||||
-webkit-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
|
|
||||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_button:hover:before {
|
|
||||||
background: dodgerblue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_arrow {
|
|
||||||
margin-top: 0.2em;
|
|
||||||
border-top: 0.8em solid transparent;
|
|
||||||
border-left: 1em solid #444;
|
|
||||||
border-bottom: 0.8em solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_container {
|
|
||||||
min-width: 300px;
|
|
||||||
|
|
||||||
padding: 0.5em;
|
|
||||||
background: #444;
|
|
||||||
|
|
||||||
margin-right: 0.5em;
|
|
||||||
margin-top: -2em;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_date {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_container > ul {
|
|
||||||
max-height: 400px;
|
|
||||||
width: 120%;
|
|
||||||
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow-y: scroll;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_container > ul > li {
|
|
||||||
width: 80%;
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_container > ul > li:hover {
|
|
||||||
background-color: orangered;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_icon_settings {
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
padding: 0em 0.2em;
|
|
||||||
width: 2em; height: 2em;
|
|
||||||
|
|
||||||
background: #333 url(/assets/blog/layout-images/settings.png) no-repeat center center;
|
|
||||||
background-size: 1.5em 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_icon_settings:hover {
|
|
||||||
background-color: #555;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.nt_smenu {
|
|
||||||
font-family: custom-sans;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.nt_smenu > li {
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.nt_smenu > li:hover {
|
|
||||||
background-color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.nt_smenu > li[active] > span.nt_switch:before {
|
|
||||||
margin-top: -1.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.nt_smenu > li > span {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_switch {
|
|
||||||
width: 2.5em;
|
|
||||||
height: 1.2em;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_switch:before {
|
|
||||||
float: left;
|
|
||||||
color: red;
|
|
||||||
content: 'OFF';
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_switch:after {
|
|
||||||
float: left;
|
|
||||||
color: yellowgreen;
|
|
||||||
content: 'ON';
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_tname {
|
|
||||||
padding-left: 0.5em;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.nt_tcount {
|
|
||||||
float: right;
|
|
||||||
}
|
|
@ -1,240 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.Notification" );
|
|
||||||
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.Cycle} */
|
|
||||||
var Cycle = __import( "System.Cycle" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
/** @type {System.utils.EventKey} */
|
|
||||||
var EventKey = __import( "System.utils.EventKey" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Components.Mouse.ContextMenu} */
|
|
||||||
var ContextMenu = __import( "Components.Mouse.ContextMenu" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {Astro.utils.Date} */
|
|
||||||
var XDate = __import( "Astro.utils.Date" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
var smstamp = __import( "Astro.utils.Date.smstamp" );
|
|
||||||
|
|
||||||
var init = function ()
|
|
||||||
{
|
|
||||||
var stage = Dand.id( "notifications" );
|
|
||||||
var bodyStyle = Dand.id( "nt_body" ).style;
|
|
||||||
|
|
||||||
/** @type {_AstConf_.Notification} */
|
|
||||||
var conf = Config.get( "Notification" );
|
|
||||||
|
|
||||||
var processor = conf.processor;
|
|
||||||
var contextMenu;
|
|
||||||
|
|
||||||
var itemsMenu;
|
|
||||||
|
|
||||||
var nError = function( e ) {
|
|
||||||
// TODO: Do something on error
|
|
||||||
debug.Info( e );
|
|
||||||
};
|
|
||||||
|
|
||||||
var followLink = function(e)
|
|
||||||
{
|
|
||||||
window.location = this.link;
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleFollow = function(e)
|
|
||||||
{
|
|
||||||
var _action = "enable";
|
|
||||||
if( this.item.getAttribute( "active" ) )
|
|
||||||
{
|
|
||||||
_action = "disable";
|
|
||||||
if(
|
|
||||||
0 < IDOMElement( this.count ).getDAttribute( "count" )
|
|
||||||
&& !confirm( "All followed notifications of this type will be unfollowed. Continue?" )
|
|
||||||
) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
postData(
|
|
||||||
processor
|
|
||||||
, {
|
|
||||||
"action": _action
|
|
||||||
, "tid": IDOMElement( this.item ).getDAttribute( "tid" )
|
|
||||||
, "cid": 0
|
|
||||||
}
|
|
||||||
, toggleSuccess.bind(this)
|
|
||||||
, nError
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
var toggleSuccess = function(e)
|
|
||||||
{
|
|
||||||
if( this.item.getAttribute( "active" ) )
|
|
||||||
{
|
|
||||||
this.item.removeAttribute( "active" );
|
|
||||||
this.count.innerHTML = "N/A";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.item.setAttribute( "active", 1 );
|
|
||||||
this.count.innerHTML = "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var showSettings = function( e )
|
|
||||||
{
|
|
||||||
// Create list <ul> <li> ... </ul>
|
|
||||||
var ul = Dand.wrap("ul", "nt_imenu", "nt_smenu");
|
|
||||||
|
|
||||||
for( var i in e.data )
|
|
||||||
{
|
|
||||||
var data = e.data[i];
|
|
||||||
var li
|
|
||||||
, li_s = [
|
|
||||||
// On/off toggle
|
|
||||||
Dand.wrap( "span", null, "nt_switch" )
|
|
||||||
, Dand.wrap( "span", null, "nt_tname", data.name )
|
|
||||||
]
|
|
||||||
, keys = [ new DataKey( "tid", data.type ) ]
|
|
||||||
;
|
|
||||||
|
|
||||||
if( data.hasOwnProperty("count") )
|
|
||||||
{
|
|
||||||
// type count
|
|
||||||
li_s[2] = Dand.wrap(
|
|
||||||
"span"
|
|
||||||
, null
|
|
||||||
, "nt_tcount"
|
|
||||||
, e.data[i].count + ""
|
|
||||||
, new DataKey( "count", data.count )
|
|
||||||
);
|
|
||||||
// Active
|
|
||||||
keys[ keys.length ] = new IKey( "active", 1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
li_s[2] = Dand.wrap( "span", null, "nt_tcount", "N/A" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create li element
|
|
||||||
li = Dand.wrapne( "li", li_s, keys );
|
|
||||||
ul.appendChild( li );
|
|
||||||
|
|
||||||
IDOMElement( li ).addEventListener(
|
|
||||||
"Click"
|
|
||||||
, toggleFollow.bind({ item: li, count: li_s[2] })
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
var msgBox = new MessageBox( "Notification Settings", ul, "Close" ).show();
|
|
||||||
};
|
|
||||||
|
|
||||||
var popupSettings = function()
|
|
||||||
{
|
|
||||||
postData( processor, { action: "getSettings" }, showSettings, nError );
|
|
||||||
};
|
|
||||||
|
|
||||||
var readNotification = function(e)
|
|
||||||
{
|
|
||||||
postData( processor, { action: "read", id: this.id }, followLink.bind( this ), nError );
|
|
||||||
};
|
|
||||||
// functions
|
|
||||||
var createContextMenu = function(e)
|
|
||||||
{
|
|
||||||
var items = [], menuShow = false;
|
|
||||||
var hasNotis = 0 < e.data.length;
|
|
||||||
|
|
||||||
for( var n in e.data )
|
|
||||||
{
|
|
||||||
/** @type {_AstJson_.AJaxGetNotis} */
|
|
||||||
var data = e.data[n];
|
|
||||||
// Create items
|
|
||||||
items[ items.length ] = new IKey(
|
|
||||||
data.mesg
|
|
||||||
, new EventKey(
|
|
||||||
"m_" + data.id
|
|
||||||
, readNotification.bind( data )
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Dand.glass( "nt_icon_settings", true )[0].addEventListener( "Click", popupSettings );
|
|
||||||
|
|
||||||
contextMenu = new ContextMenu(
|
|
||||||
Dand.id( "nt_open_menu" )
|
|
||||||
, items
|
|
||||||
, "LMB"
|
|
||||||
, nt_body
|
|
||||||
// showMenu/hideMenu overrides style settings
|
|
||||||
, {
|
|
||||||
"class": "nt_container"
|
|
||||||
, "showMenu": function( stage, event )
|
|
||||||
{
|
|
||||||
if( stage.className == "nt_date" ) return;
|
|
||||||
if( !hasNotis || menuShow ) return;
|
|
||||||
bodyStyle.marginLeft = "1em";
|
|
||||||
bodyStyle.marginRight = "-1em";
|
|
||||||
bodyStyle.opacity = 0;
|
|
||||||
bodyStyle.display = "block";
|
|
||||||
Cycle.next(function()
|
|
||||||
{
|
|
||||||
bodyStyle.marginLeft
|
|
||||||
= bodyStyle.marginRight = 0;
|
|
||||||
|
|
||||||
bodyStyle.opacity = 1;
|
|
||||||
menuShow = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
, "hideMenu": function( stage )
|
|
||||||
{
|
|
||||||
if( stage.className == "nt_date" ) return;
|
|
||||||
if( !menuShow ) return;
|
|
||||||
bodyStyle.marginLeft = "1em";
|
|
||||||
bodyStyle.marginRight = "-1em";
|
|
||||||
bodyStyle.opacity = 0;
|
|
||||||
|
|
||||||
Cycle.delay(function()
|
|
||||||
{
|
|
||||||
bodyStyle.display = "none";
|
|
||||||
// cubic 200, we set delay to 200
|
|
||||||
menuShow = false;
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
// Prevent default subnode chaining
|
|
||||||
, "chainHide": function( stage ) { }
|
|
||||||
, "chainShow": function( stage ) { }
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
for( n in e.data )
|
|
||||||
{
|
|
||||||
/** @type {_AstJson_.AJaxGetNotis} */
|
|
||||||
var data = e.data[n];
|
|
||||||
|
|
||||||
var li = contextMenu.getItemByKey( "m_" + data.id ).stage;
|
|
||||||
li.appendChild(
|
|
||||||
Dand.wrapc(
|
|
||||||
"nt_date"
|
|
||||||
, smstamp( new Date( data.date ) )
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
postData( processor, { "action": "get" }, createContextMenu );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,58 +0,0 @@
|
|||||||
.section-buttons > a {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
color: white;
|
|
||||||
background-color: darkslategray;
|
|
||||||
|
|
||||||
margin: 0.5em 0.2em;
|
|
||||||
padding: 0.75em 0;
|
|
||||||
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-buttons > a:hover, .section-buttons > a[data-active="1"]:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-buttons > a[data-name="blog"] {
|
|
||||||
background-color: purple;
|
|
||||||
}
|
|
||||||
.section-buttons > a[data-name="works"] {
|
|
||||||
background-color: royalblue;
|
|
||||||
}
|
|
||||||
.section-buttons > a[data-name="album"] {
|
|
||||||
background-color: crimson;
|
|
||||||
background-image:
|
|
||||||
repeating-linear-gradient(
|
|
||||||
45deg, transparent
|
|
||||||
, transparent 2px, rgba(0,0,0,.2) 2px
|
|
||||||
, rgba(0,0,0,.2) 3px, transparent 3px
|
|
||||||
, transparent 5px, rgba(0,0,0,.2) 5px
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-buttons > a[data-name="lifestyle"] {
|
|
||||||
text-shadow: 1px 1px 1px black;
|
|
||||||
background-image:
|
|
||||||
repeating-linear-gradient(
|
|
||||||
-15deg
|
|
||||||
, orangered 0%, orangered 16.6%
|
|
||||||
, lawngreen 16.6%, lawngreen 33.2%
|
|
||||||
, turquoise 33.2%, turquoise 49.8%
|
|
||||||
, darkorchid 49.8%, darkorchid 66.6%
|
|
||||||
, violetred 66.6%, violetred 83.3%
|
|
||||||
, royalblue 83.3%, royalblue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-buttons > a > span {
|
|
||||||
padding: 0.75em 0.5em;
|
|
||||||
}
|
|
||||||
.section-buttons > a[data-active="1"] {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.section-buttons > a > .count {
|
|
||||||
background-color: rgba( 0, 0, 0, 0.3 );
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.Section" );
|
|
@ -1,17 +0,0 @@
|
|||||||
.site-file {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
.sf_regular sup { vertical-align: baseline; }
|
|
||||||
|
|
||||||
.sf_regular {
|
|
||||||
padding: 1em;
|
|
||||||
background-color: #F0F0F0;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sf_failed {
|
|
||||||
color: orangered;
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
.sf_failed:hover { opacity: 1; }
|
|
@ -1,174 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components" );
|
|
||||||
|
|
||||||
/** @type {System.Debug} */
|
|
||||||
var debug = __import( "System.Debug" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var getData = __import( "System.Net.getData" );
|
|
||||||
var getSMStamp = __import( "Astro.utils.Date.smstamp" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.SiteFile} */
|
|
||||||
var config = null;
|
|
||||||
|
|
||||||
var SiteFile = function ( id, hash, nObj )
|
|
||||||
{
|
|
||||||
if( !config ) throw new Error( "config is not defined" );
|
|
||||||
// TODO: Make a trigger for downloading from server
|
|
||||||
var stage = Dand.id( id );
|
|
||||||
if( !stage )
|
|
||||||
{
|
|
||||||
debug.Info( "[SiteFile] id not found: " + id );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.id = id;
|
|
||||||
this.hash = hash;
|
|
||||||
this.type = IDOMElement( stage ).getDAttribute( "type" );
|
|
||||||
|
|
||||||
if(!( this.type == "default" || this.type == null )) return this;
|
|
||||||
if( stage.getAttribute( "noauto" ) != null ) return this;
|
|
||||||
|
|
||||||
var applyStructure = function( obj )
|
|
||||||
{
|
|
||||||
return _applyStructure( JSON.parse( obj ).file );
|
|
||||||
};
|
|
||||||
|
|
||||||
var _applyStructure = function( obj )
|
|
||||||
{
|
|
||||||
/** @type {_AstJson_.SiteFile} */
|
|
||||||
var finfo = obj;
|
|
||||||
|
|
||||||
switch( finfo.type )
|
|
||||||
{
|
|
||||||
case "image":
|
|
||||||
var node = Dand.tag( "img", false, stage )[0];
|
|
||||||
|
|
||||||
switch( IDOMElement(stage).getDAttribute('size') )
|
|
||||||
{
|
|
||||||
case "small":
|
|
||||||
node.src = finfo.thumbs.small || ( config.path.image.small + hash + '.jpg' );
|
|
||||||
break;
|
|
||||||
case "medium":
|
|
||||||
node.src = finfo.thumbs.medium || ( config.path.image.medium + hash + '.jpg' );
|
|
||||||
break;
|
|
||||||
case "original":
|
|
||||||
node.src = config.path.image.original + hash + '.jpg';
|
|
||||||
break;
|
|
||||||
default: // large
|
|
||||||
node.src = finfo.thumbs.large || ( config.path.image.large + hash + '.jpg' );
|
|
||||||
}
|
|
||||||
|
|
||||||
stage.appendChild(Dand.wrapne(
|
|
||||||
'a', node
|
|
||||||
, [
|
|
||||||
new IKey( 'href', config.f_host + finfo.src_location )
|
|
||||||
, new IKey( 'title', finfo.name )
|
|
||||||
, new IKey( 'target', '_blank' )
|
|
||||||
]
|
|
||||||
));
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "audio":
|
|
||||||
// TODO
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// create a form to post hash string to php
|
|
||||||
var hash_field = Dand.wrapna(
|
|
||||||
'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'hash' ) ]
|
|
||||||
)
|
|
||||||
, name_field = Dand.wrapna(
|
|
||||||
'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'name' ) ]
|
|
||||||
)
|
|
||||||
, link = Dand.wrapne(
|
|
||||||
'a', 'download', new IKey( 'href', config.path.download + finfo.name )
|
|
||||||
)
|
|
||||||
|
|
||||||
, form = Dand.wrap(
|
|
||||||
'form', null, 'sf_regular'
|
|
||||||
, [ name_field, hash_field ]
|
|
||||||
, [
|
|
||||||
new IKey('target', '_blank')
|
|
||||||
, new IKey('action', config.path.download + finfo.name)
|
|
||||||
, new IKey('method', 'POST')
|
|
||||||
]
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
hash_field.value = hash;
|
|
||||||
name_field.value = finfo.name;
|
|
||||||
|
|
||||||
IDOMElement(link).addEventListener(
|
|
||||||
'Click'
|
|
||||||
, function(e) {
|
|
||||||
form.submit();
|
|
||||||
e.preventDefault();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// file name
|
|
||||||
form.appendChild( Dand.wrapne( 'span', 'File: ' + finfo.name) );
|
|
||||||
|
|
||||||
// download, submit button
|
|
||||||
form.appendChild( Dand.wrapne( 'sup', [ Dand.textNode(" ["), link, Dand.textNode("]") ] ) );
|
|
||||||
|
|
||||||
// hash
|
|
||||||
form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'MD5: ' + hash ) ) );
|
|
||||||
// date
|
|
||||||
form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'Date: ' + getSMStamp( new Date( finfo.date_created ) ) ) ) );
|
|
||||||
|
|
||||||
stage.appendChild(form);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
var loadFailed = function( obj )
|
|
||||||
{
|
|
||||||
while( stage.hasChildNodes() ) stage.removeChild( stage.firstChild );
|
|
||||||
stage.appendChild( Dand.wrapc( "sf_failed", Dand.textNode( "Error: Failed to get resources info" ) ) );
|
|
||||||
};
|
|
||||||
|
|
||||||
if( nObj )
|
|
||||||
{
|
|
||||||
_applyStructure( nObj );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.loadInfo( applyStructure, loadFailed );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SiteFile.prototype.loadInfo = function( success, failed )
|
|
||||||
{
|
|
||||||
getData( config.path.info + this.hash, success, failed );
|
|
||||||
};
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
config = Conf.get( "SiteFile" );
|
|
||||||
if( config )
|
|
||||||
{
|
|
||||||
var SFOs = Conf.get( "SFObjects" );
|
|
||||||
for( var i in SFOs )
|
|
||||||
{
|
|
||||||
var f = SFOs[i];
|
|
||||||
new SiteFile( f[0], f[1] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "SiteFile", SiteFile );
|
|
||||||
})();
|
|
@ -1,8 +0,0 @@
|
|||||||
.social_panel {
|
|
||||||
margin: 0.5em 0;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social_panel > div {
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.SocialButtons" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {System.utils.IKey} */
|
|
||||||
var IKey = __import( "System.utils.IKey" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
|
|
||||||
var init = function( id )
|
|
||||||
{
|
|
||||||
var s = Dand.tag( "script" )[0];
|
|
||||||
|
|
||||||
// Facebook
|
|
||||||
var fb = Dand.wrapna(
|
|
||||||
"script"
|
|
||||||
, IKey.quickDef(
|
|
||||||
"type" , 'text/javascript'
|
|
||||||
, "id" , 'facebook-jssdk'
|
|
||||||
, "src" , "//connect.facebook.net/en_US/all.js#xfbml=1"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Google+
|
|
||||||
var gplus = Dand.wrapna(
|
|
||||||
"script"
|
|
||||||
, IKey.quickDef(
|
|
||||||
"type" , 'text/javascript'
|
|
||||||
, "async" , true
|
|
||||||
, "src" , "https://apis.google.com/js/plusone.js"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
s.parentNode.insertBefore( fb, s );
|
|
||||||
s.parentNode.insertBefore( gplus, s );
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
|
|
||||||
})();
|
|
@ -1,35 +0,0 @@
|
|||||||
.spoiler {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.spoiler .title {
|
|
||||||
background: cornflowerblue;
|
|
||||||
color: white;
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spoiler .title:hover {
|
|
||||||
background: royalblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spoiler .title[clicked] {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spoiler .title:before {
|
|
||||||
padding-right: 0.5em;
|
|
||||||
content: "\25BC";
|
|
||||||
font-size: 0.75em;
|
|
||||||
}
|
|
||||||
.spoiler .title[clicked]:before {
|
|
||||||
content: "\25B2";
|
|
||||||
}
|
|
||||||
|
|
||||||
.spoiler .content {
|
|
||||||
padding: 0.5em;
|
|
||||||
font-size: 0.9em;
|
|
||||||
line-height: 1.2em;
|
|
||||||
background-color: rgba( 0, 0, 0, 0.02 );
|
|
||||||
display: none;
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.Spoiler" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Config = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
var Spoiler = function( id )
|
|
||||||
{
|
|
||||||
var sp_stage = Dand.id( "spoiler_" + id );
|
|
||||||
var sp_display = ( sp_stage.nodeName == "span" ) ? "inline-block" : "block";
|
|
||||||
|
|
||||||
var ostage = IDOMElement( sp_stage );
|
|
||||||
var sp_title = ostage.first( "DIV" );
|
|
||||||
var sp_content = ostage.last( "DIV" );
|
|
||||||
|
|
||||||
sp_title.onclick = function ()
|
|
||||||
{
|
|
||||||
var s_style = sp_content.style;
|
|
||||||
|
|
||||||
if( s_style.display == sp_display )
|
|
||||||
{
|
|
||||||
s_style.display = "none";
|
|
||||||
sp_title.removeAttribute( "clicked" );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s_style.display = sp_display;
|
|
||||||
sp_title.setAttribute( "clicked", "" );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
sp_stage.hasAttribute( "expanded" ) && sp_title.onclick();
|
|
||||||
};
|
|
||||||
|
|
||||||
var sps = Config.get( "Spoiler" );
|
|
||||||
|
|
||||||
Bootstrap.regInit(function() {
|
|
||||||
for( var i in sps )
|
|
||||||
{
|
|
||||||
new Spoiler( sps[i] );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
})();
|
|
@ -1,24 +0,0 @@
|
|||||||
.tag-ctrl .title {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #444;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-ctrl {
|
|
||||||
white-space-collapse: discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-ctrl > div > div {
|
|
||||||
padding: 0.2em 0;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-ctrl > div > div > a {
|
|
||||||
padding: 0 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tag-ctrl > div > div > a:first-child:hover {
|
|
||||||
color: white;
|
|
||||||
background: purple;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
// __namespace( "Astro.Blog.Components.TagControl" );
|
|
@ -1,46 +0,0 @@
|
|||||||
.b_notify { background-color: #222 !important; }
|
|
||||||
.b_notify:before { content: 'Mute'; }
|
|
||||||
.b_notify:after { content: 'Notify'; }
|
|
||||||
|
|
||||||
.uc_ntoggle {
|
|
||||||
font-family: custom-sans;
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 0.2em 0em;
|
|
||||||
}
|
|
||||||
.uc_ntoggle:before { content: '..'; }
|
|
||||||
.uc_ntoggle:after { content: '!'; }
|
|
||||||
|
|
||||||
.cr_ntoggle {
|
|
||||||
font-family: custom-sans;
|
|
||||||
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
width: 1.5em;
|
|
||||||
height: 1.5em;
|
|
||||||
|
|
||||||
bottom: 0;
|
|
||||||
right: -3em;
|
|
||||||
|
|
||||||
border-radius: 2em 2em 2em 0em;
|
|
||||||
border: 0.5em solid white;
|
|
||||||
|
|
||||||
line-height: 1.5em !important;
|
|
||||||
|
|
||||||
background-color: white;
|
|
||||||
/* box-shadow: 2px 2px 10px -5px black; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:before, .cr_ntoggle:after {
|
|
||||||
padding: 0;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:before {
|
|
||||||
content: '..';
|
|
||||||
background-color: orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cr_ntoggle:after { content: '!'; }
|
|
@ -1,35 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.ToggleButton.CommentToggle" );
|
|
||||||
|
|
||||||
var ToggleButton = __import( "Astro.Blog.Components.ToggleButton" );
|
|
||||||
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog.Config} */
|
|
||||||
var Conf = __import( "Astro.Blog.Config" );
|
|
||||||
|
|
||||||
/** @type {_AstConf_.CommentToggle} */
|
|
||||||
var settings = Conf.get( "CommentToggle" );
|
|
||||||
|
|
||||||
var CommentToggle = function( id, processor, object )
|
|
||||||
{
|
|
||||||
ToggleButton.call( this, id, processor, object );
|
|
||||||
};
|
|
||||||
|
|
||||||
__extends( CommentToggle, ToggleButton );
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
for( var i in settings )
|
|
||||||
{
|
|
||||||
var button = settings[i];
|
|
||||||
new CommentToggle( button[0], button[1], button[2] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
})();
|
|
@ -1,42 +0,0 @@
|
|||||||
.b_button {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
font-family: custom-sans;
|
|
||||||
font-size: 1em;
|
|
||||||
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
margin: 0.5em 0.2em;
|
|
||||||
|
|
||||||
background-color: grey;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_delete {
|
|
||||||
color: crimson;
|
|
||||||
background-color: crimson;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_delete:after {
|
|
||||||
content: "\2715";
|
|
||||||
color: white;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 0.15em;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.b_delete:hover:after {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.b_scope { background-color: slategrey; }
|
|
||||||
.b_scope:before { content: 'Private'; background-color: purple; }
|
|
||||||
.b_scope:after { content: 'Public'; background-color: orangered; }
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components.ToggleButton.DeleteArticle" );
|
|
||||||
|
|
||||||
/** @type {Components.MessageBox} */
|
|
||||||
var MessageBox = __import( "Components.MessageBox" );
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
var aid = Dand.id( "b_entry", true ).getDAttribute( "aid" );
|
|
||||||
var stage = Dand.glass( "b_delete", true, Dand.id( "b_entry" ) );
|
|
||||||
if( !stage.length ) return;
|
|
||||||
|
|
||||||
stage = stage[0];
|
|
||||||
|
|
||||||
var doDelete = function( confirmed )
|
|
||||||
{
|
|
||||||
var a_deleteSuccess = function( args ) { window.location.reload( true ); };
|
|
||||||
var a_deleteFailed = function( args ) { };
|
|
||||||
|
|
||||||
if( confirmed ) postData(
|
|
||||||
"/ajax/del-article"
|
|
||||||
, { "article_id": aid }
|
|
||||||
, a_deleteSuccess
|
|
||||||
, a_deleteFailed
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
stage.addEventListener(
|
|
||||||
'Click'
|
|
||||||
, function (e) {
|
|
||||||
new MessageBox(
|
|
||||||
"Confirm"
|
|
||||||
, "Are you sure you want to delete this article?. Comments will also be deleted!"
|
|
||||||
, "Yes", "No"
|
|
||||||
, doDelete
|
|
||||||
).show();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
})();
|
|
@ -1,85 +0,0 @@
|
|||||||
.btn_toggle {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
font-family: serif;
|
|
||||||
font-size: 1em;
|
|
||||||
|
|
||||||
padding: 0.2em 0.5em;
|
|
||||||
margin: 0.5em 0.2em;
|
|
||||||
|
|
||||||
background-color: #222;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
cursor: default;
|
|
||||||
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle > .btn_space {
|
|
||||||
visibility: hidden;
|
|
||||||
padding: 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle:hover {
|
|
||||||
opacity: 1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle:hover:before, .btn_toggle:hover:after {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle:before, .btn_toggle:after {
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
padding-top: 0.15em;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
-webkit-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle:before {
|
|
||||||
content: '';
|
|
||||||
top: 0%;
|
|
||||||
|
|
||||||
-webkit-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle:after {
|
|
||||||
content: '';
|
|
||||||
background-color: #4169E1;
|
|
||||||
top: 100%;
|
|
||||||
|
|
||||||
-webkit-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-moz-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-ms-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
-o-transition: all 750ms cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
|
||||||
transition: all 500ms cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn_toggle[data-active="1"]:after {
|
|
||||||
top: 0%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.btn_toggle[data-active="1"]:before {
|
|
||||||
top: -100%;
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
(function(){
|
|
||||||
var ns = __namespace( "Astro.Blog.Components" );
|
|
||||||
|
|
||||||
/** @type {Dandelion} */
|
|
||||||
var Dand = __import( "Dandelion" );
|
|
||||||
/** @type {Dandelion.IDOMElement} */
|
|
||||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
|
||||||
/** @type {Astro.Bootstrap} */
|
|
||||||
var Bootstrap = __import( "Astro.Bootstrap" );
|
|
||||||
/** @type {Astro.Blog} */
|
|
||||||
var config = __import( "Astro.Blog.Config" );
|
|
||||||
/** @type {System.utils.DataKey} */
|
|
||||||
var DataKey = __import( "System.utils.DataKey" );
|
|
||||||
|
|
||||||
var postData = __import( "System.Net.postData" );
|
|
||||||
|
|
||||||
var ToggleButton = function ( elem, processor, obj )
|
|
||||||
{
|
|
||||||
var stage = Dand.id( elem, true );
|
|
||||||
if( !stage ) return;
|
|
||||||
|
|
||||||
|
|
||||||
var n_toggle = function (args)
|
|
||||||
{
|
|
||||||
if( stage.getDAttribute("active") == 1 )
|
|
||||||
{
|
|
||||||
stage.setAttribute( new DataKey( "active", 0 ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
stage.setAttribute( new DataKey( "active", 1 ) );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var nError = function (args)
|
|
||||||
{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
stage.addEventListener(
|
|
||||||
"Click"
|
|
||||||
, function (e) {
|
|
||||||
var _action = stage.getDAttribute( "active" ) == 1
|
|
||||||
? obj[ "disable" ]
|
|
||||||
: obj[ "enable" ]
|
|
||||||
;
|
|
||||||
postData( processor, _action, n_toggle, nError );
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
var init = function()
|
|
||||||
{
|
|
||||||
var toggles = config.get( "ToggleButtons" );
|
|
||||||
for( var i in toggles )
|
|
||||||
{
|
|
||||||
new ToggleButton( toggles[ i ][0], toggles[ i ][1], toggles[ i ][2] );
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Bootstrap.regInit( init );
|
|
||||||
|
|
||||||
ns[ NS_EXPORT ]( EX_CLASS, "ToggleButton", ToggleButton );
|
|
||||||
})();
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user