hunk ./Main.hs 1
-{-# LANGUAGE CPP #-}
-import Control.Monad
-import Data.List
-import Data.Maybe
-import Network
-import Network.HTTP.Lucu
-import OpenSSL
-import Rakka.Environment
-import Rakka.Resource.CheckAuth
-import Rakka.Resource.DumpRepos
-import Rakka.Resource.Index
-import Rakka.Resource.JavaScript
-import Rakka.Resource.PageEntity
-import Rakka.Resource.Object
-import Rakka.Resource.Render
-import Rakka.Resource.Search
-import Rakka.Resource.SystemConfig
--- import Rakka.Resource.TrackBack
-import Rakka.Resource.Users
-import Rakka.Storage
-import Subversion
-import System.Console.GetOpt
-import System.Directory
-import System.Environment
-import System.Exit
-import System.IO
-import System.Log.Handler.Simple
-import System.Log.Logger
-import System.Posix.Files
-import System.Posix.Types
-import System.Posix.User
-
-
-logger :: String
-logger = "Main"
-
-
-data CmdOpt
- = OptPortNum PortNumber
- | OptLSDir FilePath
- | OptUserName String
- | OptGroupName String
- | OptLogLevel Priority
- | OptDisableStderrLog
- | OptRebuildIndex
- | OptHelp
- deriving (Eq, Show)
-
-
-defaultPort :: PortNumber
-defaultPort = toEnum 8080
-
-defaultLocalStateDir :: FilePath
-defaultLocalStateDir = LOCALSTATEDIR -- replaced by CPP
-
-defaultUserName :: String
-defaultUserName = "daemon"
-
-defaultGroupName :: String
-defaultGroupName = "daemon"
-
-
-defaultLogLevel :: Priority
-defaultLogLevel = NOTICE
-
-
-options :: [OptDescr CmdOpt]
-options = [ Option ['p'] ["port"]
- (ReqArg (OptPortNum . toEnum . read) "NUM")
- ("Port number to listen. (default: " ++ show defaultPort ++ ")")
-
- , Option ['d'] ["localstatedir"]
- (ReqArg OptLSDir "DIR")
- ("Path to the database directory. (default: " ++ defaultLocalStateDir ++ ")")
-
- , Option ['u'] ["user"]
- (ReqArg OptUserName "USER")
- ("Which user to setuid. (default: " ++ defaultUserName ++ ")")
-
- , Option ['g'] ["group"]
- (ReqArg OptGroupName "GROUP")
- ("Which user to setgid. (default: " ++ defaultGroupName ++ ")")
-
- , Option ['l'] ["log-level"]
- (ReqArg (OptLogLevel . read) "LEVEL")
- ("The lowest log level to show. (default: " ++ show defaultLogLevel ++ ")")
-
- , Option [] ["disable-stderr-log"]
- (NoArg OptDisableStderrLog)
- "Disable logging to stderr."
-
- , Option [] ["rebuild-index"]
- (NoArg OptRebuildIndex)
- "Rebuild the index database."
-
- , Option ['h'] ["help"]
- (NoArg OptHelp)
- "Print this message."
- ]
-
-
-printUsage :: IO ()
-printUsage = do putStrLn "Usage:"
- putStrLn " rakka [OPTIONS...]"
- putStrLn ""
- putStr $ usageInfo "Options:" options
-
-
-main :: IO ()
-main = withOpenSSL $
- withSubversion $
- do (opts, nonOpts, errors) <- return . getOpt Permute options =<< getArgs
-
- unless (null errors)
- $ do mapM_ putStr errors
- exitWith $ ExitFailure 1
-
- when (any (\ x -> x == OptHelp) opts)
- $ do printUsage
- exitWith ExitSuccess
-
- unless (null nonOpts)
- $ do printUsage
- exitWith $ ExitFailure 1
-
- portNum <- getPortNum opts
- uid <- getUserID opts
- gid <- getGroupID opts
- lsdir <- getLocalStateDir opts
-
- createLocalStateDir lsdir uid gid
-
- setGroupID gid
- setUserID uid
-
- setupLogger opts
- env <- setupEnv lsdir portNum
-
- rebuildIndexIfRequested env opts
-
- infoM logger ("Listening to " ++ show portNum ++ "/tcp...")
- runHttpd (envLucuConf env) (resTree env) [fallbackPageEntity env]
-
-
-resTree :: Environment -> ResTree
-resTree env
- = mkResTree [ ([] , resIndex env)
- , (["checkAuth" ], resCheckAuth env)
- , (["dumpRepos" ], resDumpRepos env)
- , (["js" ], javaScript )
- , (["object" ], resObject env)
- , (["render" ], resRender env)
- , (["search" ], resSearch env)
- , (["search.html" ], resSearch env)
- , (["search.xml" ], resSearch env)
- , (["systemConfig"], resSystemConfig env)
- -- , (["trackback" ], resTrackBack env)
- , (["users" ], resUsers env)
- ]
-
-
-getPortNum :: [CmdOpt] -> IO PortNumber
-getPortNum opts
- = do let xs = mapMaybe (\ x -> case x of
- OptPortNum n -> Just n
- _ -> Nothing) opts
- case xs of
- [] -> return defaultPort
- (x:[]) -> return x
- _ -> error "too many --port options."
-
-
-getUserID :: [CmdOpt] -> IO UserID
-getUserID opts
- = do let xs = mapMaybe (\ x -> case x of
- OptUserName n -> Just n
- _ -> Nothing) opts
- name = case xs of
- [] -> defaultUserName
- (x:[]) -> x
- _ -> error "too many --user options."
-
- userEnt <- getUserEntryForName name
- return $ userID userEnt
-
-
-getGroupID :: [CmdOpt] -> IO GroupID
-getGroupID opts
- = do let xs = mapMaybe (\ x -> case x of
- OptGroupName n -> Just n
- _ -> Nothing) opts
- name = case xs of
- [] -> defaultGroupName
- (x:[]) -> x
- _ -> error "too many --group options."
-
- groupEnt <- getGroupEntryForName name
- return $ groupID groupEnt
-
-
-getLocalStateDir :: [CmdOpt] -> IO FilePath
-getLocalStateDir opts
- = do let xs = mapMaybe (\ x -> case x of
- OptLSDir n -> Just n
- _ -> Nothing) opts
- path = case xs of
- [] -> defaultLocalStateDir
- (x:[]) -> x
- _ -> error "too many --localstatedir options."
-
- return path
-
-
-setupLogger :: [CmdOpt] -> IO ()
-setupLogger opts
- = do let disableStderrLog = find (== OptDisableStderrLog) opts /= Nothing
- logHandlers = if disableStderrLog then
- []
- else
- [verboseStreamHandler stderr DEBUG]
- logLevel = fromMaybe defaultLogLevel
- $ do OptLogLevel l <- find (\ x -> case x of
- OptLogLevel _ -> True
- _ -> False) opts
- return l
-
- logHandlers' <- sequence logHandlers
- updateGlobalLogger rootLoggerName (setHandlers logHandlers' . setLevel logLevel)
-
-
-createLocalStateDir :: FilePath -> UserID -> GroupID -> IO ()
-createLocalStateDir path uid gid
- = do createDirectoryIfMissing True path
- setOwnerAndGroup path uid gid
-
-
-rebuildIndexIfRequested :: Environment -> [CmdOpt] -> IO ()
-rebuildIndexIfRequested env opts
- = do let rebuild = isJust $ find (\ x -> case x of
- OptRebuildIndex -> True
- _ -> False) opts
- when rebuild
- $ rebuildIndex (envStorage env)
rmfile ./Main.hs
hunk ./Makefile 1
-CABAL_FILE = Rakka.cabal
-GHC = ghc
-EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG
-#EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG +RTS -S -A60M -RTS
-#EXECUTABLE = sudo ./dist/build/rakka/rakka -p 8989 -l DEBUG +RTS -p -RTS
-
-build: dist/setup-config Setup
- $(MAKE) -C js $@
- ./Setup build
-
-run: build
- $(EXECUTABLE)
-
-rebuild-index: build
- $(EXECUTABLE) --rebuild-index
-
-dist/setup-config: $(CABAL_FILE) configure Setup Rakka.buildinfo.in
- ./Setup configure --disable-optimization -fbuild-test-suite
-# ./Setup configure -fhardest-optimization
-# ./Setup configure -fenable-profiling
-
-configure: configure.ac
- autoconf
-
-Setup: Setup.hs
- $(GHC) --make Setup
-
-clean:
- $(MAKE) -C js $@
- rm -rf dist Setup Setup.o Setup.hi
- find . -name '*~' -exec rm -f {} \;
-
-install: build
- sudo ./Setup install
-
-test: build
- ./Setup test
-
-sdist: Setup
- ./Setup sdist
-
-.PHONY: build run clean install doc sdist test
rmfile ./Makefile
hunk ./Rakka/Attachment.hs 1
-module Rakka.Attachment
- ( Attachment(..)
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowList
-import System.IO.Unsafe
-import Text.XML.HXT.Arrow.ReadDocument
-import Text.XML.HXT.Arrow.WriteDocument
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.TypeDefs
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-class Attachment t where
- serializeToXmlTree :: (ArrowChoice a, ArrowXml a) => a t XmlTree
- deserializeFromXmlTree :: (ArrowChoice a, ArrowXml a) => a XmlTree t
-
- serializeToString :: t -> String
- serializeToString attachment
- = unsafePerformIO $
- do [xmlStr] <- runX ( setErrorMsgHandler False fail
- >>>
- constA attachment
- >>>
- serializeToXmlTree
- >>>
- writeDocumentToString [ (a_indent, v_1) ]
- )
- return xmlStr
-
- deserializeFromString :: String -> t
- deserializeFromString source
- = unsafePerformIO $
- do [ret] <- runX ( setErrorMsgHandler False fail
- >>>
- readString [ (a_validate , v_0)
- , (a_check_namespaces , v_1)
- , (a_remove_whitespace, v_0)
- ] source
- >>>
- deserializeFromXmlTree
- )
- return ret
rmfile ./Rakka/Attachment.hs
hunk ./Rakka/Authorization.hs 1
-module Rakka.Authorization
- ( AuthDB
- , mkAuthDB
- , isValidPair
- , getUserList
- , addUser
- , delUser
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import Control.Concurrent.STM
-import Control.Monad
-import Control.Monad.Trans
-import qualified Data.ByteString as B
-import Data.Map (Map)
-import qualified Data.Map as M hiding (Map)
-import Data.Maybe
-import OpenSSL.EVP.Base64
-import OpenSSL.EVP.Digest
-import Rakka.SystemConfig
-import System.Directory
-import System.FilePath
-
-
-data AuthDB
- = AuthDB {
- adbFilePath :: !FilePath
- , adbUserMap :: !(TVar UserMap)
- }
-
-
-type UserMap = Map String String
-
-
-mkAuthDB :: FilePath -> IO AuthDB
-mkAuthDB lsdir
- = do let path = lsdir > "authDB"
- m <- newTVarIO =<< loadUserMap path
- return AuthDB {
- adbFilePath = path
- , adbUserMap = m
- }
-
-
-isValidPair :: MonadIO m => AuthDB -> String -> String -> m Bool
-isValidPair adb name pass
- = liftIO $ do sha1 <- return . fromJust =<< getDigestByName "SHA1"
- let hash = digestBS sha1 $ B.pack $ UTF8.encode pass
- atomically $ do m <- readTVar (adbUserMap adb)
- return (M.lookup name m == Just hash)
-
-
-getUserList :: MonadIO m => AuthDB -> m [String]
-getUserList adb
- = liftIO $
- atomically $
- do m <- readTVar (adbUserMap adb)
- return (M.keys m)
-
-
-addUser :: MonadIO m => AuthDB -> String -> String -> m ()
-addUser adb name pass
- = liftIO $
- do sha1 <- return . fromJust =<< getDigestByName "SHA1"
- let hash = digestBS sha1 $ B.pack $ UTF8.encode pass
- m <- atomically $ do m <- readTVar (adbUserMap adb)
- let m' = M.insert name hash m
- writeTVar (adbUserMap adb) m'
- return m'
- saveUserMap (adbFilePath adb) m
-
-
-delUser :: MonadIO m => AuthDB -> String -> m ()
-delUser adb name
- = liftIO $
- do m <- atomically $ do m <- readTVar (adbUserMap adb)
- let m' = M.delete name m
- writeTVar (adbUserMap adb) m'
- return m'
- saveUserMap (adbFilePath adb) m
-
-
-loadUserMap :: FilePath -> IO UserMap
-loadUserMap path
- = do exist <- doesFileExist path
- m <- if exist then
- liftM (M.fromList . map decodePair . fromJust . deserializeStringPairs)
- (readFile path)
- else
- return M.empty
- sha1 <- return . fromJust =<< getDigestByName "SHA1"
- return (initMap sha1 m)
- where
- decodePair :: (String, String) -> (String, String)
- decodePair (name, b64Hash)
- = (UTF8.decodeString name, decodeBase64 b64Hash)
-
- initMap :: Digest -> UserMap -> UserMap
- initMap sha1 m
- | M.null m = let name = "root"
- hash = digest sha1 ""
- in
- M.singleton name hash
- | otherwise = m
-
-
-saveUserMap :: FilePath -> UserMap -> IO ()
-saveUserMap path m
- = writeFile path $ serializeStringPairs $ map encodePair $ M.toList m
- where
- encodePair :: (String, String) -> (String, String)
- encodePair (name, hash)
- = (UTF8.encodeString name, encodeBase64 hash)
rmfile ./Rakka/Authorization.hs
hunk ./Rakka/Environment.hs 1
-module Rakka.Environment
- ( Environment(..)
- , InterpTable
- , setupEnv
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowList
-import qualified Data.Map as M
-import Network
-import qualified Network.HTTP.Lucu.Config as LC
-import Rakka.Authorization
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Wiki.Engine
-import Rakka.Wiki.Interpreter
-import qualified Rakka.Wiki.Interpreter.Base as Base
-import qualified Rakka.Wiki.Interpreter.Image as Image
-import qualified Rakka.Wiki.Interpreter.PageList as PageList
---import qualified Rakka.Wiki.Interpreter.Trackback as Trackback
-import qualified Rakka.Wiki.Interpreter.Outline as Outline
-import Subversion.Repository
-import System.Directory
-import System.FilePath
-import System.Log.Logger
-import Text.HyperEstraier
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-
-
-logger :: String
-logger = "Rakka.Environment"
-
-
-data Environment = Environment {
- envLocalStateDir :: !FilePath
- , envLucuConf :: !LC.Config
- , envRepository :: !Repository
- , envSysConf :: !SystemConfig
- , envStorage :: !Storage
- , envInterpTable :: !InterpTable
- , envAuthDB :: !AuthDB
- }
-
-
-setupEnv :: FilePath -> PortNumber -> IO Environment
-setupEnv lsdir portNum
- = do let lucuConf = LC.defaultConfig {
- LC.cnfServerPort = PortNumber portNum
- }
- reposPath = lsdir > "repos"
- interpTable = mkInterpTable
-
- reposExist <- doesDirectoryExist reposPath
- repos <- if reposExist then
- do debugM logger ("Found a subversion repository on " ++ reposPath)
- openRepository reposPath
- else
- do noticeM logger ("Creating a subversion repository on " ++ reposPath)
- createRepository reposPath [] []
- sysConf <- mkSystemConfig lucuConf repos
- storage <- mkStorage lsdir repos (makeDraft' interpTable)
- authDB <- mkAuthDB lsdir
-
- return Environment {
- envLocalStateDir = lsdir
- , envLucuConf = lucuConf
- , envRepository = repos
- , envSysConf = sysConf
- , envStorage = storage
- , envInterpTable = interpTable
- , envAuthDB = authDB
- }
- where
- makeDraft' :: InterpTable -> Page -> IO Document
- makeDraft' interpTable page
- = do [doc] <- runX ( setErrorMsgHandler False fail
- >>>
- constA page
- >>>
- xmlizePage
- >>>
- makeDraft interpTable
- )
- return doc
-
-
-mkInterpTable :: InterpTable
-mkInterpTable = listToTable $
- foldl (++) [] [ Base.interpreters
- , Image.interpreters
- , PageList.interpreters
- --, Trackback.interpreters
- , Outline.interpreters
- ]
- where
- listToTable :: [Interpreter] -> InterpTable
- listToTable xs
- = M.fromList [ (commandName x, x) | x <- xs ]
rmfile ./Rakka/Environment.hs
hunk ./Rakka/Page.hs 1
-module Rakka.Page
- ( PageName
- , Page(..)
- , UpdateInfo(..)
- , LanguageTag
- , LanguageName
-
- , isRedirect
- , isEntity
-
- , pageName
- , pageUpdateInfo
- , pageRevision
-
- , encodePageName
- , decodePageName
-
- , mkPageURI
- , mkPageFragmentURI
- , mkObjectURI
- , mkFragmentURI
- , mkAuxiliaryURI
- , mkFeedURI
- , mkRakkaURI
-
- , xmlizePage
- , parseXmlizedPage
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import qualified Data.ByteString.Lazy as Lazy (ByteString)
-import qualified Data.ByteString.Lazy as L hiding (ByteString)
-import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
-import Data.Char
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.Time
-import Network.HTTP.Lucu hiding (redirect)
-import Network.URI hiding (fragment)
-import OpenSSL.EVP.Base64
-import Rakka.Utils
-import Rakka.W3CDateTime
-import Subversion.Types
-import System.FilePath.Posix
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.XPath
-
-
-type PageName = String
-
-type LanguageTag = String -- See RFC 3066: http://www.ietf.org/rfc/rfc3066.txt
-type LanguageName = String -- i.e. "日本語"
-
-
-data Page
- = Redirection {
- redirName :: !PageName
- , redirDest :: !PageName
- , redirIsLocked :: !Bool
- , redirRevision :: RevNum
- , redirLastMod :: UTCTime
- , redirUpdateInfo :: Maybe UpdateInfo
- }
- | Entity {
- entityName :: !PageName
- , entityType :: !MIMEType
- , entityLanguage :: !(Maybe LanguageTag)
- , entityIsTheme :: !Bool -- text/css 以外では無意味
- , entityIsFeed :: !Bool -- text/x-rakka 以外では無意味
- , entityIsLocked :: !Bool
- , entityIsBinary :: !Bool
- , entityRevision :: RevNum
- , entityLastMod :: UTCTime
- , entitySummary :: !(Maybe String)
- , entityOtherLang :: !(Map LanguageTag PageName)
- , entityContent :: !Lazy.ByteString
- , entityUpdateInfo :: Maybe UpdateInfo
- }
- deriving (Show, Eq)
-
-
-data UpdateInfo
- = UpdateInfo {
- uiOldRevision :: !RevNum
- , uiOldName :: !(Maybe PageName)
- }
- deriving (Show, Eq)
-
-
-isRedirect :: Page -> Bool
-isRedirect (Redirection _ _ _ _ _ _) = True
-isRedirect _ = False
-
-
-isEntity :: Page -> Bool
-isEntity (Entity _ _ _ _ _ _ _ _ _ _ _ _ _) = True
-isEntity _ = False
-
-
-pageName :: Page -> PageName
-pageName p
- | isRedirect p = redirName p
- | isEntity p = entityName p
- | otherwise = error "neither redirection nor entity"
-
-
-pageUpdateInfo :: Page -> Maybe UpdateInfo
-pageUpdateInfo p
- | isRedirect p = redirUpdateInfo p
- | isEntity p = entityUpdateInfo p
- | otherwise = error "neither redirection nor entity"
-
-
-pageRevision :: Page -> RevNum
-pageRevision p
- | isRedirect p = redirRevision p
- | isEntity p = entityRevision p
- | otherwise = error "neither redirection nor entity"
-
-
--- UTF-8 に encode してから 0x20 - 0x7E の範圍を除いて URI escape する。
-encodePageName :: PageName -> FilePath
-encodePageName = escapeURIString isSafeChar . UTF8.encodeString . fixPageName
- where
- fixPageName :: PageName -> PageName
- fixPageName = (\ (x:xs) -> toUpper x : xs) . map (\ c -> if c == ' ' then '_' else c)
-
-
-decodePageName :: FilePath -> PageName
-decodePageName = UTF8.decodeString . unEscapeString
-
-
-encodeFragment :: String -> String
-encodeFragment = escapeURIString isSafeChar . UTF8.encodeString
-
-
-mkPageURI :: URI -> PageName -> URI
-mkPageURI baseURI name
- = baseURI {
- uriPath = uriPath baseURI > encodePageName name <.> "html"
- }
-
-
-mkPageFragmentURI :: URI -> PageName -> String -> URI
-mkPageFragmentURI baseURI name fragment
- = baseURI {
- uriPath = uriPath baseURI > encodePageName name <.> "html"
- , uriFragment = ('#' : encodeFragment fragment)
- }
-
-
-mkFragmentURI :: String -> URI
-mkFragmentURI fragment
- = nullURI {
- uriFragment = ('#' : encodeFragment fragment)
- }
-
-
-mkObjectURI :: URI -> PageName -> URI
-mkObjectURI baseURI name
- = mkAuxiliaryURI baseURI ["object"] name
-
-
-mkAuxiliaryURI :: URI -> [String] -> PageName -> URI
-mkAuxiliaryURI baseURI basePath name
- = baseURI {
- uriPath = foldl (>) "/" ([uriPath baseURI] ++ basePath ++ [encodePageName name])
- }
-
-
-mkFeedURI :: URI -> PageName -> URI
-mkFeedURI baseURI name
- = baseURI {
- uriPath = uriPath baseURI > encodePageName name <.> "rdf"
- }
-
-
-mkRakkaURI :: PageName -> URI
-mkRakkaURI name = URI {
- uriScheme = "rakka:"
- , uriAuthority = Nothing
- , uriPath = encodePageName name
- , uriQuery = ""
- , uriFragment = ""
- }
-
-
-{-
-
-
-
- blah blah...
- -- 存在しない場合もある
-
- -- 存在しない場合もある
-
-
-
-
-
- blah blah...
-
-
- SKJaHKS8JK/DH8KS43JDK2aKKaSFLLS...
-
-
-
-
--}
-xmlizePage :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree
-xmlizePage
- = proc page
- -> if isRedirect page then
- xmlizeRedirection -< page
- else
- xmlizeEntity -< page
- where
- xmlizeRedirection :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree
- xmlizeRedirection
- = proc page
- -> do lastMod <- arrIO (utcToLocalZonedTime . redirLastMod) -< page
- ( eelem "/"
- += ( eelem "page"
- += sattr "name" (redirName page)
- += sattr "redirect" (redirDest page)
- += sattr "isLocked" (yesOrNo $ redirIsLocked page)
- += sattr "revision" (show $ redirRevision page)
- += sattr "lastModified" (formatW3CDateTime lastMod)
- )) -<< ()
-
- xmlizeEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a Page XmlTree
- xmlizeEntity
- = proc page
- -> do lastMod <- arrIO (utcToLocalZonedTime . entityLastMod) -< page
- ( eelem "/"
- += ( eelem "page"
- += sattr "name" (pageName page)
- += sattr "type" (show $ entityType page)
- += ( case entityLanguage page of
- Just x -> sattr "lang" x
- Nothing -> none
- )
- += ( case entityType page of
- MIMEType "text" "css" _
- -> sattr "isTheme" (yesOrNo $ entityIsTheme page)
- MIMEType "text" "x-rakka" _
- -> sattr "isFeed" (yesOrNo $ entityIsFeed page)
- _
- -> none
- )
- += sattr "isLocked" (yesOrNo $ entityIsLocked page)
- += sattr "isBinary" (yesOrNo $ entityIsBinary page)
- += sattr "revision" (show $ entityRevision page)
- += sattr "lastModified" (formatW3CDateTime lastMod)
- += ( case entitySummary page of
- Just s -> eelem "summary" += txt s
- Nothing -> none
- )
- += ( if M.null (entityOtherLang page) then
- none
- else
- selem "otherLang"
- [ eelem "link"
- += sattr "lang" lang
- += sattr "page" name
- | (lang, name) <- M.toList (entityOtherLang page) ]
- )
- += ( if entityIsBinary page then
- ( eelem "binaryData"
- += txt (L8.unpack $ encodeBase64LBS $ entityContent page)
- )
- else
- ( eelem "textData"
- += txt (UTF8.decode $ L.unpack $ entityContent page)
- )
- )
- )) -<< ()
-
-
-parseXmlizedPage :: (ArrowXml a, ArrowChoice a) => a (PageName, XmlTree) Page
-parseXmlizedPage
- = proc (name, tree)
- -> do updateInfo <- maybeA parseUpdateInfo -< tree
- redirect <- maybeA (getXPathTreesInDoc "/page/@redirect/text()" >>> getText) -< tree
- isLocked <- (withDefault (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText) "no"
- >>> parseYesOrNo) -< tree
- case redirect of
- Nothing -> parseEntity -< (name, tree)
- Just dest -> returnA -< (Redirection {
- redirName = name
- , redirDest = dest
- , redirIsLocked = isLocked
- , redirRevision = undefined
- , redirLastMod = undefined
- , redirUpdateInfo = updateInfo
- })
-
-
-parseEntity :: (ArrowXml a, ArrowChoice a) => a (PageName, XmlTree) Page
-parseEntity
- = proc (name, tree)
- -> do updateInfo <- maybeA parseUpdateInfo -< tree
-
- mimeTypeStr <- withDefault (getXPathTreesInDoc "/page/@type/text()" >>> getText) "" -< tree
-
- lang <- maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< tree
-
- isTheme <- (withDefault (getXPathTreesInDoc "/page/@isTheme/text()" >>> getText) "no"
- >>> parseYesOrNo) -< tree
- isFeed <- (withDefault (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText) "no"
- >>> parseYesOrNo) -< tree
- isLocked <- (withDefault (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText) "no"
- >>> parseYesOrNo) -< tree
-
- summary <- (maybeA (getXPathTreesInDoc "/page/summary/text()"
- >>> getText
- >>> deleteIfEmpty)) -< tree
-
- otherLang <- listA (getXPathTreesInDoc "/page/otherLang/link"
- >>>
- (getAttrValue0 "lang"
- &&&
- getAttrValue0 "page")) -< tree
-
- textData <- maybeA (getXPathTreesInDoc "/page/textData/text()" >>> getText) -< tree
- binaryData <- maybeA (getXPathTreesInDoc "/page/binaryData/text()" >>> getText) -< tree
-
- let (isBinary, content)
- = case (textData, binaryData) of
- (Just text, Nothing ) -> (False, L.pack $ UTF8.encode text)
- (Nothing , Just binary) -> (True , L8.pack $ decodeBase64 $ dropWhitespace binary)
- _ -> error "one of textData or binaryData is required"
- mimeType
- = if isBinary then
- if null mimeTypeStr then
- guessMIMEType content
- else
- read mimeTypeStr
- else
- read mimeTypeStr
-
- returnA -< Entity {
- entityName = name
- , entityType = mimeType
- , entityLanguage = lang
- , entityIsTheme = isTheme
- , entityIsFeed = isFeed
- , entityIsLocked = isLocked
- , entityIsBinary = isBinary
- , entityRevision = undefined
- , entityLastMod = undefined
- , entitySummary = summary
- , entityOtherLang = M.fromList otherLang
- , entityContent = content
- , entityUpdateInfo = updateInfo
- }
- where
- dropWhitespace :: String -> String
- dropWhitespace [] = []
- dropWhitespace (x:xs)
- | x == ' ' || x == '\t' || x == '\n'
- = dropWhitespace xs
- | otherwise
- = x : dropWhitespace xs
-
-
-parseUpdateInfo :: (ArrowXml a, ArrowChoice a) => a XmlTree UpdateInfo
-parseUpdateInfo
- = proc tree
- -> do uInfo <- getXPathTreesInDoc "/page/updateInfo" -< tree
- oldRev <- (getAttrValue0 "oldRevision" >>> arr read) -< uInfo
- oldName <- maybeA (getXPathTrees "/updateInfo/move/@from/text()" >>> getText) -< uInfo
- returnA -< UpdateInfo {
- uiOldRevision = oldRev
- , uiOldName = oldName
- }
-
-
rmfile ./Rakka/Page.hs
hunk ./Rakka/Resource/CheckAuth.hs 1
-module Rakka.Resource.CheckAuth
- ( resCheckAuth
- )
- where
-
-import Network.HTTP.Lucu
-import Rakka.Environment
-import Rakka.Resource
-
-
-resCheckAuth :: Environment -> ResourceDef
-resCheckAuth env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = False
- , resGet
- = Just $
- do userID <- getUserID env
- case userID of
- Just _ -> setStatus NoContent
- Nothing -> setStatus Forbidden
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Nothing
- , resDelete = Nothing
- }
rmfile ./Rakka/Resource/CheckAuth.hs
hunk ./Rakka/Resource/DumpRepos.hs 1
-module Rakka.Resource.DumpRepos
- ( resDumpRepos
- )
- where
-
-import Control.Monad.Trans
-import Network.HTTP.Lucu
-import Rakka.Environment
-import Subversion.Repository
-
-resDumpRepos :: Environment -> ResourceDef
-resDumpRepos env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = False
- , resGet = Just $ dumpRepos $ envRepository env
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Nothing
- , resDelete = Nothing
- }
-
-
-dumpRepos :: Repository -> Resource ()
-dumpRepos repos
- = do setContentType $ read "application/octet-stream"
- -- FIXME: 最終更新時刻が判るはず。
- dump <- liftIO $ dumpRepository repos Nothing Nothing False True
- outputLBS dump
rmfile ./Rakka/Resource/DumpRepos.hs
hunk ./Rakka/Resource/Index.hs 1
-module Rakka.Resource.Index
- ( resIndex
- )
- where
-
-import Network.HTTP.Lucu
-import Rakka.Environment
-import Rakka.Page
-import Rakka.SystemConfig
-
-
-resIndex :: Environment -> ResourceDef
-resIndex env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = False
- , resGet
- = Just $ do BaseURI baseURI <- getSysConf (envSysConf env)
- DefaultPage name <- getSysConf (envSysConf env)
- redirect Found (mkPageURI baseURI name)
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Nothing
- , resDelete = Nothing
- }
-
rmfile ./Rakka/Resource/Index.hs
hunk ./Rakka/Resource/Object.hs 1
--- -*- Coding: utf-8 -*-
-module Rakka.Resource.Object
- ( resObject
- )
- where
-
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.Utils
-import Rakka.Environment
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-
-
-resObject :: Environment -> ResourceDef
-resObject env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = True
- , resGet = Just $ getPathInfo >>= handleGet env . toPageName
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Nothing
- , resDelete = Nothing
- }
- where
- toPageName :: [String] -> PageName
- toPageName = decodePageName . joinWith "/"
-
-
-handleGet :: Environment -> PageName -> Resource ()
-handleGet env name
- = do pageM <- getPage (envStorage env) name Nothing
- case pageM of
- Nothing -> foundNoEntity Nothing
- Just page -> if isEntity page then
- handleGetEntity page
- else
- handleRedirect env page
-
-
-{-
- HTTP/1.1 302 Found
- Location: http://example.org/object/Destination
--}
-handleRedirect :: Environment -> Page -> Resource ()
-handleRedirect env redir
- = do BaseURI baseURI <- getSysConf (envSysConf env)
- redirect Found (mkObjectURI baseURI $ redirName redir)
-
-
-{-
- HTTP/1.1 200 OK
- Content-Type: image/png
-
- ...
--}
-handleGetEntity :: Page -> Resource ()
-handleGetEntity page
- = do case entityRevision page of
- 0 -> foundTimeStamp (entityLastMod page) -- 0 はデフォルトページ
- rev -> foundEntity (strongETag $ show rev) (entityLastMod page)
-
- setContentType (entityType page)
- outputLBS (entityContent page)
rmfile ./Rakka/Resource/Object.hs
hunk ./Rakka/Resource/PageEntity.hs 1
-module Rakka.Resource.PageEntity
- ( fallbackPageEntity
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import Control.Monad.Trans
-import qualified Data.ByteString.Lazy as L hiding (ByteString)
-import Data.Char
-import qualified Data.Map as M
-import Data.Maybe
-import Data.Time
-import Network.HTTP.Lucu
-import Network.URI hiding (path)
-import Rakka.Environment
-import Rakka.Page
-import Rakka.Resource
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Utils
-import Rakka.W3CDateTime
-import Rakka.Wiki.Engine
-import System.FilePath.Posix
-import Text.HyperEstraier hiding (getText)
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.XPath
-
-
-fallbackPageEntity :: Environment -> [String] -> IO (Maybe ResourceDef)
-fallbackPageEntity env path
- | null path = return Nothing
- | null $ head path = return Nothing
- | isLower $ head $ head path = return Nothing -- 先頭の文字が小文字であってはならない
- | otherwise
- = return $ Just $ ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = True
- , resGet = Just $ handleGet env (toPageName path)
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Just $ handlePut env (toPageName path)
- , resDelete = Just $ handleDelete env (toPageName path)
- }
- where
- toPageName :: [String] -> PageName
- toPageName = decodePageName . dropExtension . joinPath
-
-
-handleGet :: Environment -> PageName -> Resource ()
-handleGet env name
- = do BaseURI baseURI <- getSysConf (envSysConf env)
- runIdempotentA baseURI $ proc ()
- -> do pageM <- getPageA (envStorage env) -< (name, Nothing)
- case pageM of
- Nothing
- -> do items <- getDirContentsA (envStorage env) -< (name, Nothing)
- case items of
- [] -> handlePageNotFound env -< name
- _ -> handleGetPageListing env -< (name, items)
- Just page
- -> if isEntity page then
- handleGetEntity env -< page
- else
- handleRedirect env -< page
-
-
-{-
- HTTP/1.1 302 Found
- Location: http://example.org/Destination.html#Redirect:Source
--}
-handleRedirect :: (ArrowXml a, ArrowIO a) => Environment -> a Page (Resource ())
-handleRedirect env
- = proc redir
- -> returnA -< do mType <- getEntityType
- case mType of
- MIMEType "text" "xml" _
- -> do setContentType mType
- [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA redir
- >>>
- xmlizePage
- >>>
- writeDocumentToString [ (a_indent , v_1 )
- , (a_output_encoding, utf8)
- , (a_no_xml_pi , v_0 ) ]
- )
- output resultStr
-
- _ -> do BaseURI baseURI <- getSysConf (envSysConf env)
- let uri = mkPageFragmentURI
- baseURI
- (redirDest redir)
- ("Redirect:" ++ redirName redir)
- redirect Found uri
-
-
-handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ())
-handleGetEntity env
- = proc page
- -> do tree <- xmlizePage -< page
- returnA -< outputXmlPage tree [ (MIMEType "application" "xhtml+xml" [], entityToXHTML env)
- , (MIMEType "application" "rss+xml" [], entityToRSS env)
- ]
-
-
-entityToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
-entityToXHTML env
- = proc page
- -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
- StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
- GlobalLock isGLocked <- getSysConfA (envSysConf env) -< ()
-
- name <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page
- isLocked <- (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText >>> parseYesOrNo) -< page
-
- let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""]
- scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI > "js" }) ""]
-
- pageTitle <- listA (readSubPage env) -< (name, Just page, "PageTitle")
- leftSideBar <- listA (readSubPage env) -< (name, Just page, "SideBar/Left")
- rightSideBar <- listA (readSubPage env) -< (name, Just page, "SideBar/Right")
- pageBody <- listA (makeMainXHTML (envStorage env) (envSysConf env) (envInterpTable env)) -< page
-
- ( eelem "/"
- += ( eelem "html"
- += sattr "xmlns" "http://www.w3.org/1999/xhtml"
- += ( getXPathTreesInDoc "/page/@lang"
- `guards`
- qattr (mkQName "xml" "lang" "")
- ( getXPathTreesInDoc "/page/@lang/text()" )
- )
- += ( eelem "head"
- += ( eelem "title"
- += txt siteName
- += txt " - "
- += getXPathTreesInDoc "/page/@name/text()"
- )
- += ( constL cssHref
- >>>
- eelem "link"
- += sattr "rel" "stylesheet"
- += sattr "type" "text/css"
- += attr "href" (arr id >>> mkText)
- )
- += mkFeedList env
- += ( constL scriptSrc
- >>>
- eelem "script"
- += sattr "type" "text/javascript"
- += attr "src" (arr id >>> mkText)
- )
- += ( eelem "script"
- += sattr "type" "text/javascript"
- += txt ("Rakka.baseURI=\"" ++ uriToString id baseURI "" ++ "\";")
- += txt ("Rakka.isLocked=" ++ trueOrFalse isLocked ++ ";")
- += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
- )
- += mkGlobalJSList env
- )
- += ( eelem "body"
- += ( eelem "div"
- += sattr "class" "header"
- )
- += ( eelem "div"
- += sattr "class" "center"
- += ( eelem "div"
- += sattr "class" "title"
- += constL pageTitle
- )
- += ( eelem "div"
- += sattr "class" "body"
- += constL pageBody
- )
- )
- += ( eelem "div"
- += sattr "class" "footer"
- )
- += ( eelem "div"
- += sattr "class" "left sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL leftSideBar
- )
- )
- += ( eelem "div"
- += sattr "class" "right sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL rightSideBar
- )
- )
- )
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< page
-
-
-entityToRSS :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
-entityToRSS env
- = proc page
- -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
-
- name <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page
- summary <- maybeA (getXPathTreesInDoc "/page/summary/text()" >>> getText) -< page
- pages <- makePageLinkList (envStorage env) (envSysConf env) (envInterpTable env) -< page
-
- ( eelem "/"
- += ( eelem "rdf:RDF"
- += sattr "xmlns" "http://purl.org/rss/1.0/"
- += sattr "xmlns:rdf" "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- += sattr "xmlns:dc" "http://purl.org/dc/elements/1.1/"
- += sattr "xmlns:trackback" "http://madskills.com/public/xml/rss/module/trackback/"
- += ( eelem "channel"
- += sattr "rdf:about" (uriToString id (mkFeedURI baseURI name) "")
- += ( eelem "title"
- += txt siteName
- += txt " - "
- += getXPathTreesInDoc "/page/@name/text()"
- )
- += ( eelem "link"
- += txt (uriToString id baseURI "")
- )
- += ( eelem "description"
- += txt (case summary of
- Nothing -> "RSS Feed for " ++ siteName
- Just s -> s)
- )
- += ( eelem "items"
- += ( eelem "rdf:Seq"
- += ( constL pages
- >>>
- eelem "rdf:li"
- += attr "resource" (arr (mkPageURIStr baseURI) >>> mkText)
- )
- )
- )
- )
- += ( constL pages
- >>>
- arr (\ n -> (n, Nothing))
- >>>
- getPageA (envStorage env)
- >>>
- arr fromJust
- >>>
- eelem "item"
- += attr "rdf:about" (arr (mkPageURIStr baseURI . entityName) >>> mkText)
- += ( eelem "title"
- += (arr entityName >>> mkText)
- )
- += ( eelem "link"
- += (arr (mkPageURIStr baseURI . entityName) >>> mkText)
- )
- += ( arrL (\ p -> case entitySummary p of
- Nothing -> []
- Just s -> [s])
- >>>
- eelem "description"
- += mkText
- )
- += ( eelem "dc:date"
- += ( arrIO (utcToLocalZonedTime . entityLastMod)
- >>>
- arr formatW3CDateTime
- >>>
- mkText
- )
- )
- += ( eelem "trackback:ping"
- += attr "rdf:resource" (arr (mkTrackbackURIStr baseURI . entityName) >>> mkText)
- )
- )
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< page
- where
- mkPageURIStr :: URI -> PageName -> String
- mkPageURIStr baseURI name
- = uriToString id (mkPageURI baseURI name) ""
-
- mkTrackbackURIStr :: URI -> PageName -> String
- mkTrackbackURIStr baseURI name
- = uriToString id (mkAuxiliaryURI baseURI ["trackback"] name) ""
-
-
-readSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Environment
- -> a (PageName, Maybe XmlTree, PageName) XmlTree
-readSubPage env
- = proc (mainPageName, mainPage, subPageName) ->
- do langM <- case mainPage of
- Nothing
- -> returnA -< Nothing
- Just p
- -> maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< p
- subPage <- getPageA (envStorage env) >>> arr fromJust -< (subPageName, Nothing)
- localSubPage <- case langM of
- Nothing
- -> returnA -< subPage
- Just l
- -> localize (envStorage env) -< (l, subPage)
- subPageXml <- xmlizePage -< localSubPage
- subXHTML <- makeSubXHTML (envStorage env) (envSysConf env) (envInterpTable env)
- -< (Just mainPageName, mainPage, subPageXml)
- returnA -< subXHTML
- where
- localize :: (ArrowChoice a, ArrowIO a) => Storage -> a (LanguageTag, Page) Page
- localize sto
- = proc (lang, origPage)
- -> do let otherLang = entityOtherLang origPage
- localName = M.lookup lang otherLang
- case localName of
- Nothing
- -> returnA -< origPage
- Just ln
- -> do localPage <- getPageA sto -< (ln, Nothing)
- returnA -< case localPage of
- Nothing -> origPage
- Just p -> p
-
-
-{-
-
-
-
-
--}
-handleGetPageListing :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a (PageName, [PageName]) (Resource ())
-handleGetPageListing env
- = proc (dir, items)
- -> do tree <- ( eelem "/"
- += ( eelem "pageListing"
- += attr "path" (arr fst >>> mkText)
- += ( arrL snd
- >>>
- ( eelem "page"
- += attr "name" (arr id >>> mkText)
- )
- )
- )
- ) -< (dir, items)
- returnA -< outputXmlPage' tree (pageListingToXHTML env) -- FIXME: rss 對應
-
-
-pageListingToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
-pageListingToXHTML env
- = proc pageListing
- -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
- StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
- GlobalLock isGLocked <- getSysConfA (envSysConf env) -< ()
-
- name <- (getXPathTreesInDoc "/pageListing/@path/text()" >>> getText) -< pageListing
-
- let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""]
- scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI > "js" }) ""]
-
- pageTitle <- listA (readSubPage env) -< (name, Nothing, "PageTitle")
- leftSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Left")
- rightSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Right")
-
- ( eelem "/"
- += ( eelem "html"
- += sattr "xmlns" "http://www.w3.org/1999/xhtml"
- += ( eelem "head"
- += ( eelem "title"
- += txt siteName
- += txt " - "
- += getXPathTreesInDoc "/pageListing/@path/text()"
- )
- += ( constL cssHref
- >>>
- eelem "link"
- += sattr "rel" "stylesheet"
- += sattr "type" "text/css"
- += attr "href" (arr id >>> mkText)
- )
- += mkFeedList env
- += ( constL scriptSrc
- >>>
- eelem "script"
- += sattr "type" "text/javascript"
- += attr "src" (arr id >>> mkText)
- )
- += ( eelem "script"
- += sattr "type" "text/javascript"
- += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";")
- += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
- )
- += mkGlobalJSList env
- )
- += ( eelem "body"
- += ( eelem "div"
- += sattr "class" "header"
- )
- += ( eelem "div"
- += sattr "class" "center"
- += ( eelem "div"
- += sattr "class" "title"
- += constL pageTitle
- )
- += ( eelem "div"
- += sattr "class" "body"
- += ( eelem "ul"
- += ( getXPathTreesInDoc "/pageListing/page/@name/text()"
- >>>
- eelem "li"
- += ( eelem "a"
- += attr "href" ( getText
- >>>
- arr (\ x -> uriToString id (mkPageURI baseURI x) "")
- >>>
- mkText
- )
- += this
- )
- )
- )
- )
- )
- += ( eelem "div"
- += sattr "class" "footer"
- )
- += ( eelem "div"
- += sattr "class" "left sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL leftSideBar
- )
- )
- += ( eelem "div"
- += sattr "class" "right sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL rightSideBar
- )
- )
- )
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< pageListing
-
-
-{-
-
--}
-handlePageNotFound :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a PageName (Resource ())
-handlePageNotFound env
- = proc name
- -> do tree <- ( eelem "/"
- += ( eelem "pageNotFound"
- += attr "name" (arr id >>> mkText)
- )
- ) -< name
- returnA -< do setStatus NotFound
- outputXmlPage' tree (notFoundToXHTML env)
-
-
-notFoundToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
-notFoundToXHTML env
- = proc pageNotFound
- -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
- StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
- GlobalLock isGLocked <- getSysConfA (envSysConf env) -< ()
-
- name <- (getXPathTreesInDoc "/pageNotFound/@name/text()" >>> getText) -< pageNotFound
-
- let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""]
- scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI > "js" }) ""]
-
- pageTitle <- listA (readSubPage env) -< (name, Nothing, "PageTitle")
- leftSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Left")
- rightSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Right")
-
- ( eelem "/"
- += ( eelem "html"
- += sattr "xmlns" "http://www.w3.org/1999/xhtml"
- += ( eelem "head"
- += ( eelem "title"
- += txt siteName
- += txt " - "
- += getXPathTreesInDoc "/pageNotFound/@name/text()"
- )
- += ( constL cssHref
- >>>
- eelem "link"
- += sattr "rel" "stylesheet"
- += sattr "type" "text/css"
- += attr "href" (arr id >>> mkText)
- )
- += mkFeedList env
- += ( constL scriptSrc
- >>>
- eelem "script"
- += sattr "type" "text/javascript"
- += attr "src" (arr id >>> mkText)
- )
- += ( eelem "script"
- += sattr "type" "text/javascript"
- += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";")
- += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
- )
- += mkGlobalJSList env
- )
- += ( eelem "body"
- += ( eelem "div"
- += sattr "class" "header"
- )
- += ( eelem "div"
- += sattr "class" "center"
- += ( eelem "div"
- += sattr "class" "title"
- += constL pageTitle
- )
- += ( eelem "div"
- += sattr "class" "body"
- += txt "404 Not Found (FIXME)" -- FIXME
- )
- )
- += ( eelem "div"
- += sattr "class" "footer"
- )
- += ( eelem "div"
- += sattr "class" "left sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL leftSideBar
- )
- )
- += ( eelem "div"
- += sattr "class" "right sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL rightSideBar
- )
- )
- )
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< pageNotFound
-
-
-handlePut :: Environment -> PageName -> Resource ()
-handlePut env name
- = do userID <- getUserID env
- runXmlA env "rakka-page-1.0.rng" $ proc tree
- -> do page <- parseXmlizedPage -< (name, tree)
- status <- putPageA (envStorage env) -< (userID, page)
- returnA -< setStatus status
-
-
-handleDelete :: Environment -> PageName -> Resource ()
-handleDelete env name
- = do userID <- getUserID env
- status <- deletePage (envStorage env) userID name
- setStatus status
-
-
-mkFeedList :: (ArrowIO a, ArrowXml a) => Environment -> a b XmlTree
-mkFeedList env
- = proc _ -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
-
- feed <- unlistA <<< arrIO0 (findFeeds $ envStorage env) -< ()
-
- ( eelem "link"
- += sattr "rel" "alternate"
- += sattr "type" "application/rss+xml"
- += attr "title" (txt siteName <+> txt " - " <+> mkText)
- += attr "href" (arr (mkFeedURIStr baseURI) >>> mkText) ) -<< feed
-
-
-findFeeds :: Storage -> IO [PageName]
-findFeeds sto
- = do cond <- newCondition
- setPhrase cond "[UVSET]"
- addAttrCond cond "rakka:isFeed STREQ yes"
- setOrder cond "@uri STRA"
- result <- searchPages sto cond
- return (map hpPageName $ srPages result)
-
-
-mkGlobalJSList :: (ArrowIO a, ArrowXml a, ArrowChoice a) => Environment -> a b XmlTree
-mkGlobalJSList env
- = proc _ -> do BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
-
- scriptName <- unlistA <<< arrIO0 (findJavaScripts $ envStorage env) -< ()
- pageM <- getPageA (envStorage env) -< (scriptName, Nothing)
-
- case pageM of
- Nothing -> none -< ()
- Just page
- | isEntity page
- -> ( if entityIsBinary page then
- ( eelem "script"
- += sattr "type" "text/javascript"
- += attr "src" (arr (mkObjectURIStr baseURI . pageName) >>> mkText) )
- else
- ( eelem "script"
- += sattr "type" "text/javascript"
- += (arr (UTF8.decode . L.unpack . entityContent) >>> mkText) )
- ) -<< page
- | otherwise
- -> none -< ()
-
-
-findJavaScripts :: Storage -> IO [PageName]
-findJavaScripts sto
- = do cond <- newCondition
- setPhrase cond "[UVSET]"
- addAttrCond cond "@title STRBW Global/"
- addAttrCond cond "@type STRBW text/javascript"
- setOrder cond "@uri STRA"
- result <- searchPages sto cond
- return (map hpPageName $ srPages result)
-
-
-mkFeedURIStr :: URI -> PageName -> String
-mkFeedURIStr baseURI name
- = uriToString id (mkFeedURI baseURI name) ""
-
-
-mkObjectURIStr :: URI -> PageName -> String
-mkObjectURIStr baseURI name
- = uriToString id (mkObjectURI baseURI name) ""
rmfile ./Rakka/Resource/PageEntity.hs
hunk ./Rakka/Resource/Render.hs 1
-module Rakka.Resource.Render
- ( resRender
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowIO
-import Control.Arrow.ArrowList
-import Control.Monad.Trans
-import qualified Data.ByteString.Lazy as Lazy
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.Utils
-import OpenSSL.EVP.Base64
-import Rakka.Environment
-import Rakka.Page
-import Rakka.Utils
-import Rakka.Wiki.Engine
-import Text.XML.HXT.Arrow.Namespace
-import Text.XML.HXT.Arrow.WriteDocument
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.TypeDefs
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-resRender :: Environment -> ResourceDef
-resRender env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = True
- , resGet = Nothing
- , resHead = Nothing
- , resPost = Just $ getPathInfo >>= handleRender env . toPageName
- , resPut = Nothing
- , resDelete = Nothing
- }
- where
- toPageName :: [String] -> PageName
- toPageName = decodePageName . joinWith "/"
-
-
-{-
- --- Request ---
- POST /render/Foo/Bar HTTP/1.0
- Content-Type: text/x-rakka
-
- = foo =
- blah blah...
-
- --- Response ---
- HTTP/1.1 200 OK
- Content-Type: text/xml
-
-
- foo
-
- blah blah...
-
-
--}
-handleRender :: Environment -> PageName -> Resource ()
-handleRender env name
- = do entity <- inputLBS defaultLimit
- cTypeM <- getContentType
-
- let (bin, cType) = case cTypeM of
- Just (MIMEType "application" "x-rakka-base64-stream" _)
- -> let b = decodeBase64LBS entity
- in
- (b, guessMIMEType b)
- Just t
- -> (entity, t)
- Nothing
- -> (entity, guessMIMEType entity)
-
- setContentType $ read "text/xml"
- [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA (name, cType, bin)
- >>>
- render env
- >>>
- writeDocumentToString [ (a_indent , v_1)
- , (a_output_encoding, utf8)
- , (a_no_xml_pi , v_0) ]
- )
- output xmlStr
-
-
-render :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Environment
- -> a (PageName, MIMEType, Lazy.ByteString) XmlTree
-render env
- = proc (pName, pType, pBin)
- -> do pageBody <- listA (makePreviewXHTML (envStorage env) (envSysConf env) (envInterpTable env))
- -< (pName, pType, pBin)
-
- ( eelem "/"
- += ( eelem "renderResult"
- += sattr "name" pName
- += constL pageBody
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< ()
-
rmfile ./Rakka/Resource/Render.hs
hunk ./Rakka/Resource/Search.hs 1
-module Rakka.Resource.Search
- ( resSearch
- )
- where
-
-import qualified Codec.Binary.UTF8.Generic as UTF8
-import Control.Monad.Trans
-import Data.List
-import Data.Maybe
-import Data.Time
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.RFC1123DateTime
-import Network.URI hiding (query, fragment)
-import Rakka.Environment
-import Rakka.Page
-import Rakka.Resource
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Utils
-import Rakka.W3CDateTime
-import Rakka.Wiki.Engine
-import System.FilePath
-import Text.HyperEstraier hiding (getText)
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.XPath
-
-
-resSearch :: Environment -> ResourceDef
-resSearch env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = False
- , resGet = Just $ handleSearch env
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Nothing
- , resDelete = Nothing
- }
-
-
-resultsPerSection :: Int
-resultsPerSection = 10
-
-
-maxSectionWindowSize :: Int
-maxSectionWindowSize = 10
-
-
-findQueryParam :: String -> [FormData] -> Maybe String
-findQueryParam name qps
- = do fd <- find (\ qp -> fdName qp == name) qps
- return $ UTF8.toString $ fdContent fd
-
-{-
-
-
-
- aaa foo bbb
-
-
- ...
-
--}
-handleSearch :: Environment -> Resource ()
-handleSearch env
- = do params <- getQueryForm
-
- let query = fromMaybe "" $ findQueryParam "q" params
- order = findQueryParam "order" params
- from = fromMaybe 0
- $ fmap read $ findQueryParam "from" params
- to = fromMaybe (from + resultsPerSection)
- $ fmap read $ findQueryParam "to" params
-
- cond <- liftIO $ mkCond query order from to
- result <- searchPages (envStorage env) cond
-
- let to' = min (from + length (srPages result)) to
-
- BaseURI baseURI <- getSysConf (envSysConf env)
- runIdempotentA baseURI $ proc ()
- -> do tree <- ( eelem "/"
- += ( eelem "searchResult"
- += sattr "query" query
- += ( case order of
- Just o -> sattr "order" o
- Nothing -> none
- )
- += sattr "from" (show from)
- += sattr "to" (show to')
- += sattr "total" (show $ srTotal result)
- += ( constL (srPages result)
- >>>
- mkPageElem
- )
- )
- ) -< ()
- returnA -< outputXmlPage' tree (searchResultToXHTML env)
- where
- mkCond :: String -> Maybe String -> Int -> Int -> IO Condition
- mkCond query order from to
- = do cond <- newCondition
- setPhrase cond query
- case order of
- Just o -> setOrder cond o
- Nothing -> return ()
- setSkip cond from
- setMax cond (to - from + 1)
- return cond
-
- mkPageElem :: (ArrowChoice a, ArrowXml a, ArrowIO a) => a HitPage XmlTree
- mkPageElem = ( eelem "page"
- += attr "name" (arr hpPageName >>> mkText)
- += attr "lastModified" ( arrIO (utcToLocalZonedTime . hpLastMod)
- >>>
- arr formatW3CDateTime
- >>>
- mkText
- )
- += ( arrL hpSnippet
- >>>
- mkSnippetTree
- )
- )
-
- mkSnippetTree :: (ArrowChoice a, ArrowXml a) => a SnippetFragment XmlTree
- mkSnippetTree = proc fragment
- -> case fragment of
- Boundary -> eelem "boundary" -< ()
- NormalText t -> mkText -< t
- HighlightedWord w -> ( eelem "hit"
- += mkText
- ) -< w
-
-
-searchResultToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
-searchResultToXHTML env
- = proc tree
- -> do SiteName siteName <- getSysConfA (envSysConf env) -< ()
- BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
- StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
- GlobalLock isGLocked <- getSysConfA (envSysConf env) -< ()
-
- let cssHref = [uriToString id (mkObjectURI baseURI styleSheet) ""]
- scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI > "js" }) ""]
-
- pageTitle <- listA (readSubPage env) -< "PageTitle"
- leftSideBar <- listA (readSubPage env) -< "SideBar/Left"
- rightSideBar <- listA (readSubPage env) -< "SideBar/Right"
-
- ( eelem "/"
- += ( eelem "html"
- += sattr "xmlns" "http://www.w3.org/1999/xhtml"
- += ( eelem "head"
- += ( eelem "title"
- += txt siteName
- += txt " - "
- += getXPathTreesInDoc "/searchResult/@query/text()"
- )
- += ( constL cssHref
- >>>
- eelem "link"
- += sattr "rel" "stylesheet"
- += sattr "type" "text/css"
- += attr "href" (arr id >>> mkText)
- )
- += ( constL scriptSrc
- >>>
- eelem "script"
- += sattr "type" "text/javascript"
- += attr "src" (arr id >>> mkText)
- )
- += ( eelem "script"
- += sattr "type" "text/javascript"
- += txt ("Rakka.baseURI=\"" ++ uriToString id baseURI "" ++ "\";")
- += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
- += txt "Rakka.isSpecialPage=true;"
- )
- )
- += ( eelem "body"
- += ( eelem "div"
- += sattr "class" "header"
- )
- += ( eelem "div"
- += sattr "class" "center"
- += ( eelem "div"
- += sattr "class" "title"
- += constL pageTitle
- )
- += ( eelem "div"
- += sattr "class" "body"
- += ( eelem "h1"
- += txt "Search Result"
- )
- += ( eelem "div"
- += sattr "class" "searchStat"
- += txt "Search result for "
- += ( eelem "span"
- += sattr "class" "queryString"
- += getXPathTreesInDoc "/searchResult/@query/text()"
- )
- += txt ": found "
- += getXPathTreesInDoc "/searchResult/@total/text()"
- += txt " pages."
- )
- += ( getXPathTreesInDoc "/searchResult/page"
- >>>
- formatItem baseURI
- )
- += ( ( ( getXPathTreesInDoc "/searchResult/@query/text()"
- >>>
- getText
- )
- &&&
- maybeA ( getXPathTreesInDoc "/searchResult/@order/text()"
- >>>
- getText
- )
- &&&
- ( getXPathTreesInDoc "/searchResult/@from/text()"
- >>>
- getText
- >>>
- arr ((`div` resultsPerSection) . read)
- )
- &&&
- ( getXPathTreesInDoc "/searchResult/@total/text()"
- >>>
- getText
- >>>
- arr ((+ 1) . (`div` resultsPerSection) . (\ x -> x - 1) . read)
- )
- )
- >>>
- ( ((> 1) . snd . snd . snd)
- `guardsP`
- formatPager baseURI
- )
- )
- )
- )
- += ( eelem "div"
- += sattr "class" "footer"
- )
- += ( eelem "div"
- += sattr "class" "left sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL leftSideBar
- )
- )
- += ( eelem "div"
- += sattr "class" "right sideBar"
- += ( eelem "div"
- += sattr "class" "content"
- += constL rightSideBar
- )
- )
- )
- >>>
- uniqueNamespacesFromDeclAndQNames
- ) ) -<< tree
- where
- formatItem :: (ArrowXml a, ArrowChoice a, ArrowIO a) => URI -> a XmlTree XmlTree
- formatItem baseURI
- = ( eelem "div"
- += sattr "class" "searchResult"
- += ( eelem "a"
- += attr "href" ( getAttrValue "name"
- >>>
- arr (\ x -> uriToString id (mkPageURI baseURI x) "")
- >>>
- mkText
- )
- += (getAttrValue "name" >>> mkText)
- )
- += ( eelem "div"
- += sattr "class" "date"
- += ( getAttrValue "lastModified"
- >>>
- arr (zonedTimeToUTC . fromJust . parseW3CDateTime)
- >>>
- arrIO utcToLocalZonedTime
- >>>
- arr formatRFC1123DateTime
- >>>
- mkText
- )
- )
- += ( eelem "p"
- += ( getChildren
- >>>
- choiceA [ isText :-> this
- , hasName "boundary" :-> txt " ... "
- , hasName "hit" :-> ( eelem "span"
- += sattr "class" "highlighted"
- += getChildren
- )
- ]
- )
- )
- )
-
- formatPager :: (ArrowChoice a, ArrowXml a) => URI -> a (String, (Maybe String, (Int, Int))) XmlTree
- formatPager baseURI
- = ( eelem "div"
- += sattr "class" "pager"
- += txt "Page."
- += ( ( arr fst
- &&&
- arr (fst . snd)
- &&&
- arr (fst . snd . snd)
- &&&
- ( arr (snd . snd)
- >>>
- mkSectionWindow
- )
- )
- >>>
- proc (query, (order, (currentSection, section)))
- -> if currentSection == section then
- ( txt " "
- <+>
- eelem "span"
- += sattr "class" "currentSection"
- += (arr show >>> mkText)
- ) -< section
- else
- ( txt " "
- <+>
- eelem "a"
- += attr "href" ( mkSectionURI baseURI
- >>>
- uriToText
- )
- += (arr (show . snd . snd) >>> mkText)
- ) -< (query, (order, section))
- )
- )
-
- mkSectionWindow :: ArrowList a => a (Int, Int) Int
- mkSectionWindow
- = proc (currentSection, totalSections)
- -> let windowWidth = min maxSectionWindowSize totalSections
- windowBegin = currentSection - (windowWidth `div` 2)
- (begin, end) = if windowBegin < 0 then
- -- 左に溢れた
- (0, windowWidth - 1)
- else
- if windowBegin + windowWidth >= totalSections then
- -- 右に溢れた
- (totalSections - windowWidth, totalSections - 1)
- else
- -- どちらにも溢れない
- (windowBegin, windowBegin + windowWidth - 1)
- in
- arrL id -< [begin .. end]
-
-
- mkSectionURI :: Arrow a => URI -> a (String, (Maybe String, Int)) URI
- mkSectionURI baseURI
- = arr $ \ (query, (order, section))
- -> baseURI {
- uriPath = uriPath baseURI > "search.html"
- , uriQuery = '?' : mkQueryString ( [ ("q" , query)
- , ("from", show $ section * resultsPerSection)
- , ("to" , show $ (section + 1) * resultsPerSection - 1)
- ]
- ++
- case order of
- Just o -> [("order", o)]
- Nothing -> []
- )
- }
-
- uriToText :: ArrowXml a => a URI XmlTree
- uriToText = arr (\ uri -> uriToString id uri "") >>> mkText
-
-
--- FIXME: localize
-readSubPage :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Environment -> a PageName XmlTree
-readSubPage env
- = proc (subPageName) ->
- do subPage <- getPageA (envStorage env) >>> arr fromJust >>> xmlizePage -< (subPageName, Nothing)
- subXHTML <- makeSubXHTML (envStorage env) (envSysConf env) (envInterpTable env) -< (Nothing, Nothing, subPage)
- returnA -< subXHTML
rmfile ./Rakka/Resource/Search.hs
hunk ./Rakka/Resource/SystemConfig.hs 1
-module Rakka.Resource.SystemConfig
- ( resSystemConfig
- )
- where
-
-import Data.Maybe
-import Network.HTTP.Lucu
-import Rakka.Environment
-import Rakka.Resource
-import Rakka.SystemConfig
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.XPath
-
-
--- FIXME:
--- GET /systemConfig ==> 全設定値を返す
--- GET /systemConfig/siteName ==> siteName を返す
--- PUT /systemConfig/siteName ==> siteName を設定
-resSystemConfig :: Environment -> ResourceDef
-resSystemConfig env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = False
- , resGet = Just $ handleGet env
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Just $ handlePut env
- , resDelete = Nothing
- }
-
-
-{-
-
- Rakka
- MainPage
-
--}
-handleGet :: Environment -> Resource ()
-handleGet env
- = runIdempotentA' $ proc ()
- -> do tree <- mkSystemConfigTree env -< ()
- returnA -< outputXml tree
-
-
-mkSystemConfigTree :: (ArrowXml a, ArrowIO a) => Environment -> a b XmlTree
-mkSystemConfigTree env
- = let sc = envSysConf env
- in
- proc _
- -> do siteName @ (SiteName _) <- getSysConfA sc -< ()
- baseURI @ (BaseURI _) <- getSysConfA sc -< ()
- defaultPage @ (DefaultPage _) <- getSysConfA sc -< ()
- styleSheet @ (StyleSheet _) <- getSysConfA sc -< ()
- languages @ (Languages _) <- getSysConfA sc -< ()
- globalLock @ (GlobalLock _) <- getSysConfA sc -< ()
-
- ( eelem "/"
- += ( eelem "systemConfig"
- += ( eelem "value"
- += sattr "path" (confPath siteName)
- += txt (serialize siteName)
- )
- += ( eelem "value"
- += sattr "path" (confPath baseURI)
- += txt (serialize baseURI)
- )
- += ( eelem "value"
- += sattr "path" (confPath defaultPage)
- += txt (serialize defaultPage)
- )
- += ( eelem "value"
- += sattr "path" (confPath styleSheet)
- += txt (serialize styleSheet)
- )
- += ( eelem "value"
- += sattr "path" (confPath languages)
- += txt (serialize languages)
- )
- += ( eelem "value"
- += sattr "path" (confPath globalLock)
- += txt (serialize globalLock)
- )
- ) ) -<< ()
-
-
-handlePut :: Environment -> Resource ()
-handlePut env
- = do let sc = envSysConf env
-
- userID <- getUserID env
- case userID of
- Nothing
- -> setStatus Forbidden
- Just uid
- -> runXmlA env "rakka-config-1.0.rng" $ proc tree
- -> do listA ( getXPathTreesInDoc "/systemConfig/value"
- >>>
- choiceA [ branch (undefined :: SiteName )
- , branch (undefined :: BaseURI )
- , branch (undefined :: DefaultPage)
- , branch (undefined :: StyleSheet )
- , branch (undefined :: Languages )
- , branch (undefined :: GlobalLock )
- ]
- ) -< tree
- returnA -< setStatus Ok
- where
- branch :: forall a c. (ArrowXml a, ArrowIO a, SysConfValue c) =>
- c
- -> IfThen (a XmlTree XmlTree) (a XmlTree StatusCode)
- branch c
- = hasAttrValue "path" (== confPath c)
- :->
- ( getChildren
- >>> getText
- >>> arr (fromJust . (deserialize :: String -> Maybe c))
- >>> setSysConfA sc uid )
+
rmfile ./Rakka/Resource/SystemConfig.hs
hunk ./Rakka/Resource/TrackBack.hs 1
-module Rakka.Resource.TrackBack
- ( resTrackBack
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import Control.Arrow
-import Control.Arrow.ArrowList
-import Control.Monad.Trans
-import Data.List
-import Data.Maybe
-import Data.Time
-import Network.Browser
-import Network.HTTP
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.Response
-import Network.HTTP.Lucu.Utils
-import Network.URI
-import Rakka.Environment
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.TrackBack
-import Text.XML.HXT.Arrow.WriteDocument
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.TypeDefs
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-data TBResponse
- = NoError
- | Error !Int !String
- deriving (Show, Eq)
-
-
-resTrackBack :: Environment -> ResourceDef
-resTrackBack env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = True
- , resGet = Nothing
- , resHead = Nothing
- , resPost = Just $ getPathInfo >>= handlePost env . toPageName
- , resPut = Nothing
- , resDelete = Nothing
- }
- where
- toPageName :: [String] -> PageName
- toPageName = decodePageName . joinWith "/"
-
-
-handlePost :: Environment -> PageName -> Resource ()
-handlePost env name
- = do form <- inputForm defaultLimit
- tbParamM <- validateTrackBack form
- case tbParamM of
- Nothing
- -> return ()
- Just tbParam
- -> do cited <- liftIO $ checkCitation tbParam name
- if cited then
- do pageM <- getPage (envStorage env) name Nothing
- case pageM of
- Nothing -> setStatus NotFound
- Just page -> addTB tbParam page
- else
- outputResponse (Error 1 "Failed to confirm if your entry contains any citation to this page.")
- where
- addTB :: TrackBack -> Page -> Resource ()
- addTB tbParam page
- | isRedirect page
- = do BaseURI baseURI <- getSysConf (envSysConf env)
- redirect TemporaryRedirect (mkPageURI baseURI $ redirName page)
- | otherwise
- = do tbListM <- return . fromMaybe [] =<< getAttachment (envStorage env) (pageName page) "trackbacks" Nothing
- st <- putAttachment (envStorage env) Nothing Nothing (pageName page) "trackbacks" (tbParam : tbListM)
- if isSuccessful st then
- outputResponse NoError
- else
- setStatus st
-
-
-validateTrackBack :: [(String, String)] -> Resource (Maybe TrackBack)
-validateTrackBack form
- = do let title = get' "title"
- excerpt = get' "excerpt"
- blogName = get' "blog_name"
- case get' "url" of
- Nothing
- -> do outputResponse (Error 1 "Parameter `url' is missing.")
- return Nothing
- Just u
- -> case parseURI u of
- Nothing
- -> do outputResponse (Error 1 "Parameter `url' is malformed.")
- return Nothing
- Just url
- -> do time <- liftIO getCurrentTime
- return $ Just TrackBack {
- tbTitle = title
- , tbExcerpt = excerpt
- , tbURL = url
- , tbBlogName = blogName
- , tbTime = time
- }
- where
- get' :: String -> Maybe String
- get' = fmap UTF8.decodeString . flip lookup form
-
-
-outputResponse :: TBResponse -> Resource ()
-outputResponse res
- = do setContentType $ read "text/xml"
- [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- mkResponseTree
- >>>
- writeDocumentToString [ (a_indent , v_1 )
- , (a_output_encoding, utf8)
- , (a_no_xml_pi , v_0 ) ]
- )
- output xmlStr
- where
- mkResponseTree :: ArrowXml a => a b XmlTree
- mkResponseTree
- = proc _
- -> ( eelem "/"
- += ( eelem "response"
- += ( eelem "error"
- += txt (case res of
- NoError -> "0"
- Error code _ -> show code)
- )
- += ( case res of
- NoError -> none
- Error _ msg -> ( eelem "message"
- += txt msg
- )
- )
- )
- ) -< ()
-
-
-checkCitation :: TrackBack -> PageName -> IO Bool
-checkCitation param name
- = do (_, res) <- browse $
- do setAllowRedirects True
- setErrHandler (\ _ -> return ())
- setOutHandler (\ _ -> return ())
- request $ defaultGETRequest $ tbURL param
- case rspCode res of
- (2, 0, 0)
- -> return (encodePageName name `isInfixOf` rspBody res)
- _ -> return False
rmfile ./Rakka/Resource/TrackBack.hs
hunk ./Rakka/Resource/Users.hs 1
-module Rakka.Resource.Users
- ( resUsers
- )
- where
-
-import Control.Monad
-import Control.Monad.Trans
-import Data.Maybe
-import Network.HTTP.Lucu
-import Rakka.Authorization
-import Rakka.Environment
-import Rakka.Resource
-import Text.XML.HXT.Arrow hiding (when)
-
-
-resUsers :: Environment -> ResourceDef
-resUsers env
- = ResourceDef {
- resUsesNativeThread = False
- , resIsGreedy = True
- , resGet = Just $ handleGet env
- , resHead = Nothing
- , resPost = Nothing
- , resPut = Just $ handlePut env
- , resDelete = Just $ handleDelete env
- }
-
-
-{-
- [GET /users]
-
-
-
- ...
-
-
- [GET /users/foo]
- 204 No Content
-
- [GET /users/nonexistent]
- 404 Not Found
--}
-handleGet :: Environment -> Resource ()
-handleGet env
- = do userID <- getUserID env
- when (isNothing userID)
- $ abort Forbidden [] Nothing
-
- path <- getPathInfo
- case path of
- [] -> returnUserList
- [name] -> returnUser name
- _ -> foundNoEntity Nothing
- where
- returnUserList :: Resource ()
- returnUserList
- = do users <- liftIO $ getUserList $ envAuthDB env
- runIdempotentA' $ proc ()
- -> do tree <- ( eelem "/"
- += ( eelem "users"
- += ( constL users
- >>>
- ( eelem "user"
- += attr "id" mkText
- )
- )
- )
- ) -< ()
- returnA -< outputXml tree
-
- returnUser :: String -> Resource ()
- returnUser name
- = do users <- liftIO $ getUserList $ envAuthDB env
- if any (== name) users
- then setStatus NoContent
- else foundNoEntity Nothing
-
-
-{-
- > PUT /users/foo HTTP/1.1
- > Content-Type: text/plain
- >
- > password
-
- < HTTP/1.1 201 Created
--}
-handlePut :: Environment -> Resource ()
-handlePut env
- = do userID <- getUserID env
- when (isNothing userID)
- $ abort Forbidden [] Nothing
-
- path <- getPathInfo
- case path of
- [name] -> do mimeType <- getContentType
- case mimeType of
- Nothing
- -> abort BadRequest [] (Just "Missing Content-Type")
- Just (MIMEType "text" "plain" _)
- -> do pass <- input defaultLimit
- addUser (envAuthDB env) name pass
- Just t
- -> abort UnsupportedMediaType [] (Just $ "Unsupported media type: " ++ show t)
- setStatus Created
- _ -> abort BadRequest [] (Just "Invalid URI")
-
-
-handleDelete :: Environment -> Resource ()
-handleDelete env
- = do userID <- getUserID env
- when (isNothing userID)
- $ abort Forbidden [] Nothing
-
- path <- getPathInfo
- case path of
- [name] -> delUser (envAuthDB env) name
- _ -> abort BadRequest [] (Just "Invalid URI")
- setStatus NoContent
rmfile ./Rakka/Resource/Users.hs
rmdir ./Rakka/Resource
hunk ./Rakka/Resource.hs 1
-module Rakka.Resource
- ( runIdempotentA
- , runIdempotentA'
- , runXmlA
- , getEntityType
- , outputXmlPage
- , outputXmlPage'
- , outputXml
- , getUserID
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import Control.Arrow
-import Control.Arrow.ArrowList
-import Control.Monad
-import Control.Monad.Trans
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.Utils
-import Network.URI hiding (path)
-import Rakka.Authorization
-import Rakka.Environment
-import Rakka.Validation
-import System.FilePath.Posix
-import System.Log.Logger
-import Text.XML.HXT.Arrow.ReadDocument
-import Text.XML.HXT.Arrow.WriteDocument
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.TypeDefs
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-logger :: String
-logger = "Rakka.Resource"
-
-
--- "/" ==> "/"
--- "/foo" ==> "/foo.html"
--- "/foo/" ==> "/foo.html"
--- "/foo.bar/" ==> "/foo.bar"
--- "/foo.bar" ==> "/foo.bar"
-canonicalizeURI :: URI -> Resource ()
-canonicalizeURI baseURI
- = do rPath <- return . uriPath =<< getRequestURI
- let newURI = baseURI { uriPath = uriPath baseURI > newPath }
- newPath = foldl (>) "/" newPath'
- newPath' = case [x | x <- splitBy (== '/') rPath, x /= ""] of
- [] -> []
- path -> case break (== '.') $ last path of
- (_, "") -> let basePieces = reverse $ tail $ reverse path
- lastPiece = last path
- in
- basePieces ++ [lastPiece ++ ".html"]
- (_, _) -> path
- when (rPath /= newPath)
- $ abort MovedPermanently
- [("Location", uriToString id newURI $ "")]
- Nothing
-
-
-runIdempotentA :: URI -> IOSArrow () (Resource c) -> Resource c
-runIdempotentA baseURI a
- = do canonicalizeURI baseURI
- [rsrc] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA ()
- >>>
- a
- )
- rsrc
-
-
-runIdempotentA' :: IOSArrow () (Resource c) -> Resource c
-runIdempotentA' a
- = do [rsrc] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA ()
- >>>
- a
- )
- rsrc
-
-
-runXmlA :: Environment -> FilePath -> IOSArrow XmlTree (Resource c) -> Resource c
-runXmlA env schemaPath a
- = do inputA <- getInputXmlA env schemaPath
- [rsrc] <- liftIO $ runX ( inputA
- >>>
- setErrorMsgHandler False fail
- >>>
- a
- )
- rsrc
-
-
--- well-formed でない時は 400 Bad Request になり、valid でない時は 422
--- Unprocessable Entity になる。入力の型が XML でない時は 415
--- Unsupported Media Type を返す。
-getInputXmlA :: Environment -> FilePath -> Resource (IOSArrow b XmlTree)
-getInputXmlA env schemaPath
- = do reader <- getInputReader
- validator <- getValidator env schemaPath
- return ( setErrorMsgHandler False (abort BadRequest [] . Just)
- >>>
- reader
- >>>
- setErrorMsgHandler False (abort UnprocessableEntitiy [] . Just)
- >>>
- validator
- )
-
-
-getInputReader :: Resource (IOSArrow b XmlTree)
-getInputReader
- = do mimeType <- getContentType
- case mimeType of
- Nothing
- -> getFailingReader BadRequest [] (Just "Missing Content-Type")
- Just (MIMEType "text" "xml" _)
- -> getXmlReader
- Just (MIMEType "application" "xml" _)
- -> getXmlReader
- Just t
- -> getFailingReader UnsupportedMediaType [] (Just $ "Unsupported media type: " ++ show t)
- where
- getXmlReader
- = do req <- input defaultLimit
- liftIO $ debugM logger req
- return $ readString [ (a_validate , v_0)
- , (a_check_namespaces , v_1)
- , (a_remove_whitespace, v_0)
- ] (UTF8.decodeString req)
- getFailingReader code headers msg
- = return $ proc _ -> abortA -< (code, (headers, msg))
-
-
-getEntityType :: Resource MIMEType
-getEntityType
- = do uri <- getRequestURI
- let ext = reverse $ takeWhile (/= '.') $ reverse $ uriPath uri
- case lookup ext extMap of
- Just mType -> return mType
- Nothing -> abort NotFound [] (Just $ "Unsupported entity type: " ++ ext)
- where
- extMap :: [(String, MIMEType)]
- extMap = [ ("html", read "application/xhtml+xml")
- , ( "rdf", read "application/rss+xml" )
- , ( "xml", read "text/xml" )
- ]
-
-
-outputXmlPage :: XmlTree -> [(MIMEType, IOSArrow XmlTree XmlTree)] -> Resource ()
-outputXmlPage tree formatters
- = do mType <- getEntityType
- setContentType mType
- let formatter = case lookup mType formatters of
- Just f -> f
- Nothing -> this
- [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA tree
- >>>
- formatter
- >>>
- writeDocumentToString [ (a_indent , v_1 )
- , (a_output_encoding, utf8)
- , (a_no_xml_pi , v_0 ) ]
- )
- output resultStr
-
-
-outputXmlPage' :: XmlTree -> IOSArrow XmlTree XmlTree -> Resource ()
-outputXmlPage' tree toXHTML
- = outputXmlPage tree [(MIMEType "application" "xhtml+xml" [], toXHTML)]
-
-
-outputXml :: XmlTree -> Resource ()
-outputXml tree
- = do setContentType (MIMEType "text" "xml" [])
- [xmlStr] <- liftIO $ runX ( setErrorMsgHandler False fail
- >>>
- constA tree
- >>>
- writeDocumentToString [ (a_indent , v_1 )
- , (a_output_encoding, utf8)
- , (a_no_xml_pi , v_0 ) ]
- )
- output xmlStr
-
-
-getUserID :: Environment -> Resource (Maybe String)
-getUserID env
- = do auth <- getAuthorization
- case auth of
- Just (BasicAuthCredential userID password)
- -> do valid <- isValidPair (envAuthDB env) userID password
- if valid then
- return (Just userID)
- else
- return Nothing
- _ -> return Nothing
rmfile ./Rakka/Resource.hs
hunk ./Rakka/Storage/DefaultPage.hs 1
-module Rakka.Storage.DefaultPage
- ( findAllDefaultPages
- , getDefaultDirContents
- , loadDefaultPage
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowIO
-import Control.Arrow.ArrowList
-import Data.Set (Set)
-import qualified Data.Set as S
-import Data.Time.Clock.POSIX
-import Paths_Rakka -- Cabal が用意する。
-import Rakka.Page
-import System.Directory
-import System.FilePath
-import System.FilePath.Find hiding (fileName, modificationTime)
-import System.Posix.Files
-import Text.XML.HXT.Arrow.ReadDocument
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.XmlKeywords
-
-
-doesLocalDirExist :: IO Bool
-doesLocalDirExist = doesDirectoryExist "defaultPages"
-
-
-findAllDefaultPages :: IO (Set PageName)
-findAllDefaultPages
- -- ./defaultPages が存在するなら、その中を探す。無ければ Cabal で
- -- defaultPages を探す。
- = do localDirExists <- doesLocalDirExist
- if localDirExists then
- findAllIn "defaultPages"
- else
- -- FIXME: この getDataFileName の使ひ方は undocumented
- findAllIn =<< getDataFileName "defaultPages"
- where
- findAllIn :: FilePath -> IO (Set PageName)
- findAllIn dirPath
- = find always (fileType ==? RegularFile) dirPath
- >>=
- return . S.fromList . map (decodePageName . makeRelative dirPath . dropExtension)
-
-
-getDefaultDirContents :: PageName -> IO (Set PageName)
-getDefaultDirContents dir
- -- ./defaultPages が存在するなら、その中を探す。無ければ Cabal で
- -- defaultPages を探す。
- = do localDirExists <- doesLocalDirExist
- if localDirExists then
- getDir' "defaultPages"
- else
- -- FIXME: この getDataFileName の使ひ方は undocumented
- getDir' =<< getDataFileName "defaultPages"
- where
- getDir' :: FilePath -> IO (Set PageName)
- getDir' basePath
- = do let childDirPath = basePath > encodePageName dir
- exists <- doesDirectoryExist childDirPath
- if exists then
- getDirectoryContents childDirPath
- >>=
- return . S.fromList . map (m basePath) . filter f
- else
- return S.empty
-
- m :: FilePath -> FilePath -> PageName
- m basePath = (dir >) . decodePageName . makeRelative basePath . dropExtension
-
- f :: FilePath -> Bool
- f "." = False
- f ".." = False
- f _ = True
-
-
-loadDefaultPage :: PageName -> IO (Maybe Page)
-loadDefaultPage name
- -- ./defaultPages が存在するなら、./defaultPages/Foo.xml を探す。無
- -- ければ Cabal で defaultPages/Foo.xml を探す。
- = do let pagePath = "defaultPages" > encodePageName name <.> "xml"
-
- localDirExists <- doesLocalDirExist
- if localDirExists then
- tryLoad pagePath
- else
- tryLoad =<< getDataFileName pagePath
- where
- tryLoad :: FilePath -> IO (Maybe Page)
- tryLoad fpath
- = do exists <- doesFileExist fpath
- if exists then
- return . Just =<< loadPageFile name fpath
- else
- return Nothing
-
-
-loadPageFile :: PageName -> FilePath -> IO Page
-loadPageFile name path
- = do [page] <- runX ( setErrorMsgHandler False fail
- >>>
- constA (name, path)
- >>>
- loadPageFileA
- )
- return page
-
-
-loadPageFileA :: IOStateArrow s (PageName, FilePath) Page
-loadPageFileA
- = proc (name, fpath) ->
- do tree <- readFromDocument [ (a_validate , v_0)
- , (a_check_namespaces , v_1)
- , (a_remove_whitespace, v_1)
- ] -< fpath
- lastMod <- arrIO (\ x -> getFileStatus x
- >>=
- return . posixSecondsToUTCTime . fromRational . toRational . modificationTime)
- -< fpath
- page <- parseXmlizedPage -< (name, tree)
-
- if isEntity page then
- returnA -< page {
- entityRevision = 0
- , entityLastMod = lastMod
- }
- else
- returnA -< page {
- redirRevision = 0
- , redirLastMod = lastMod
- }
rmfile ./Rakka/Storage/DefaultPage.hs
hunk ./Rakka/Storage/Impl.hs 1
-module Rakka.Storage.Impl
- ( getPage'
- , putPage'
- , deletePage'
- , getDirContents'
- , startIndexManager
-
- , getAttachment'
- , putAttachment'
- )
- where
-
-import Control.Concurrent
-import Control.Concurrent.STM
-import Control.Monad
-import Data.Maybe
-import Data.Set (Set)
-import qualified Data.Set as S
-import Data.Time
-import Network.HTTP.Lucu
-import Network.HTTP.Lucu.Utils
-import Network.URI
-import Prelude hiding (words)
-import Rakka.Attachment
-import Rakka.Page
-import Rakka.Storage.DefaultPage
-import Rakka.Storage.Repos
-import Rakka.Storage.Types
-import Rakka.W3CDateTime
-import Subversion.Types
-import Subversion.FileSystem
-import Subversion.Repository
-import System.Directory
-import System.FilePath
-import System.IO
-import System.IO.Unsafe
-import System.Log.Logger
-import Text.HyperEstraier hiding (WriteLock)
-
-
-logger :: String
-logger = "Rakka.Storage"
-
-
-getPage' :: Repository -> PageName -> Maybe RevNum -> IO (Maybe Page)
-getPage' repos name rev
- = do page <- loadPageInRepository repos name rev
- case page of
- Nothing -> loadDefaultPage name
- p -> return p
-
-
-putPage' :: Repository -> Maybe String -> Page -> IO StatusCode
-putPage' = putPageIntoRepository
-
-
-deletePage' :: Repository -> Maybe String -> PageName -> IO StatusCode
-deletePage' = deletePageFromRepository
-
-
-findAllPages :: Repository -> RevNum -> IO (Set PageName)
-findAllPages _ 0 = findAllDefaultPages
-findAllPages repos rev = do reposPages <- findAllPagesInRevision repos rev
- defaultPages <- findAllDefaultPages
- return (reposPages `S.union` defaultPages)
-
-
-findChangedPages :: Repository -> RevNum -> RevNum -> IO (Set PageName)
-findChangedPages repos 0 newRev = findAllPages repos newRev
-findChangedPages repos oldRev newRev
- = liftM S.unions (mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev])
-
-
-getDirContents' :: Repository -> PageName -> Maybe RevNum -> IO [PageName]
-getDirContents' repos name rev
- = do reposPages <- getDirContentsInRevision repos name rev
- defaultPages <- getDefaultDirContents name
- return $ S.toList (reposPages `S.union` defaultPages)
-
-
-getCurrentRevNum :: Repository -> IO RevNum
-getCurrentRevNum repos
- = getRepositoryFS repos >>= getYoungestRev
-
-
-getAttachment' :: Attachment a =>
- Repository
- -> PageName
- -> String
- -> Maybe RevNum
- -> IO (Maybe a)
-getAttachment' = loadAttachmentInRepository
-
-
-putAttachment' :: Attachment a =>
- Repository
- -> Maybe String
- -> Maybe RevNum
- -> PageName
- -> String
- -> a
- -> IO StatusCode
-putAttachment' = putAttachmentIntoRepository
-
-
-startIndexManager :: FilePath -> Repository -> (Page -> IO Document) -> IO (TChan IndexReq)
-startIndexManager lsdir repos mkDraft
- = do chan <- newTChanIO
- index <- openIndex indexDir revFile
- _ <- forkIO (loop chan index)
- return chan
- where
- indexDir = lsdir > "index"
- revFile = lsdir > "indexRev"
-
- loop :: TChan IndexReq -> Database -> IO ()
- loop chan index
- = do req <- atomically $ readTChan chan
- case req of
- RebuildIndex
- -> do noticeM logger "Rebuilding the H.E. index..."
- closeDatabase index
- removeDirectoryRecursive indexDir
- index' <- openIndex indexDir revFile
- syncIndex' index' revFile repos mkDraft
- loop chan index'
-
- SyncIndex
- -> do syncIndex' index revFile repos mkDraft
- loop chan index
-
- SearchIndex cond var
- -> do result <- searchIndex index cond
- atomically $ putTMVar var result
- loop chan index
-
-
--- casket を R/W モードで開く。成功したらそのまま返し、失敗したら
--- indexDir と revFile を削除してから casket を R/W モードで開く。
-openIndex :: FilePath -> FilePath -> IO Database
-openIndex indexDir revFile
- = do ret <- openDatabase indexDir (Writer [])
- case ret of
- Right index
- -> do debugM logger ("Opened an H.E. index on " ++ indexDir)
- return index
-
- Left err
- -> do noticeM logger ("Failed to open an H.E. index on "
- ++ indexDir ++ ": " ++ show err)
-
- indexExists <- doesDirectoryExist indexDir
- when indexExists
- $ removeDirectoryRecursive indexDir
-
- revFileExists <- doesFileExist revFile
- when revFileExists
- $ removeFile revFile
-
- Right index <- openDatabase indexDir (Writer [Create []])
- addAttrIndex index "@mdate" SeqIndex
- addAttrIndex index "@type" StrIndex
- addAttrIndex index "@uri" SeqIndex
- addAttrIndex index "rakka:revision" SeqIndex
- addAttrIndex index "rakka:isTheme" StrIndex
- addAttrIndex index "rakka:isFeed" StrIndex
- noticeM logger ("Created an H.E. index on " ++ indexDir)
-
- return index
-
-
-syncIndex' :: Database -> FilePath -> Repository -> (Page -> IO Document) -> IO ()
-syncIndex' index revFile repos mkDraft
- = updateIndexRev revFile $ \ oldRev ->
- do debugM logger ("The index revision is currently " ++ show oldRev)
-
- newRev <- getCurrentRevNum repos
- debugM logger ("The repository revision is currently " ++ show newRev)
-
- when (oldRev == 0 || newRev /= oldRev)
- $ syncIndex'' oldRev newRev
- return newRev
- where
- syncIndex'' :: RevNum -> RevNum -> IO ()
- syncIndex'' oldRev newRev
- = do pages <- findChangedPages repos oldRev newRev
- mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages)
-
-
-searchIndex :: Database -> Condition -> IO SearchResult
-searchIndex index cond
- = do (ids, hint) <- searchDatabase' index cond
- let (total, words) = parseHint hint
- pages <- mapM (fromId words) ids
- return SearchResult {
- srTotal = total
- , srPages = pages
- }
- where
- parseHint :: [(String, Int)] -> (Int, [String])
- parseHint xs
- = let total = fromJust $ lookup "" xs
- words = filter (/= "") $ map fst xs
- in
- (total, words)
-
- fromId :: [String] -> DocumentID -> IO HitPage
- fromId words docId
- = do uri <- getDocURI index docId
- rev <- unsafeInterleaveIO $
- liftM (read . fromJust)
- (getDocAttr index docId "rakka:revision")
- lastMod <- unsafeInterleaveIO $
- liftM (zonedTimeToUTC . fromJust . parseW3CDateTime . fromJust)
- (getDocAttr index docId "@mdate")
- summary <- unsafeInterleaveIO $
- getDocAttr index docId "rakka:summary"
- snippet <- unsafeInterleaveIO $
- do doc <- getDocument index docId [NoAttributes, NoKeywords]
- sn <- makeSnippet doc words 300 80 80
- return (trim (== Boundary) $ map toFragment sn)
- return HitPage {
- hpPageName = decodePageName $ uriPath uri
- , hpPageRev = rev
- , hpLastMod = lastMod
- , hpSummary = summary
- , hpSnippet = snippet
- }
-
- toFragment :: Either String (String, String) -> SnippetFragment
- toFragment (Left "") = Boundary
- toFragment (Left t) = NormalText t
- toFragment (Right (w, _)) = HighlightedWord w
-
-
-updateIndex :: Database
- -> Repository
- -> (Page -> IO Document)
- -> RevNum
- -> PageName
- -> IO ()
-updateIndex index repos mkDraft rev name
- = do pageM <- getPage' repos name (Just rev)
- case pageM of
- -- ページが削除された
- Nothing
- -> do docIdM <- getDocIdByURI index (mkRakkaURI name)
- case docIdM of
- Nothing -> return ()
- Just docId -> do removeDocument index docId [CleaningRemove]
- infoM logger ("Removed page " ++ name ++ " from the index")
- Just page
- -> do draft <- mkDraft page
- putDocument index draft [CleaningPut]
- infoM logger ("Indexed page " ++ name ++ " of revision " ++ show (pageRevision page))
-
-
-updateIndexRev :: FilePath -> (RevNum -> IO RevNum) -> IO ()
-updateIndexRev revFile f = withFile revFile ReadWriteMode update
- where
- update :: Handle -> IO ()
- update h = do eof <- hIsEOF h
- rev <- if eof then
- return 0
- else
- liftM read (hGetLine h)
- rev' <- f rev
- hSeek h AbsoluteSeek 0
- hSetFileSize h 0
- hPutStrLn h (show rev')
rmfile ./Rakka/Storage/Impl.hs
hunk ./Rakka/Storage/Repos.hs 1
--- -*- coding: utf-8 -*-
-module Rakka.Storage.Repos
- ( findAllPagesInRevision
- , getDirContentsInRevision
- , findChangedPagesAtRevision
- , loadPageInRepository
- , putPageIntoRepository
- , deletePageFromRepository
- , loadAttachmentInRepository
- , putAttachmentIntoRepository
- )
- where
-
-import Codec.Binary.UTF8.String
-import Control.Monad
-import Data.List
-import qualified Data.Map as M
-import Data.Maybe
-import Data.Set (Set)
-import qualified Data.Set as S hiding (Set)
-import Data.Time
-import Network.HTTP.Lucu hiding (redirect)
-import Rakka.Attachment
-import Rakka.Page
-import Rakka.SystemConfig
-import Rakka.Utils
-import Rakka.W3CDateTime
-import Subversion.FileSystem
-import Subversion.FileSystem.DirEntry
-import Subversion.FileSystem.Revision
-import Subversion.FileSystem.Root
-import Subversion.FileSystem.Transaction
-import Subversion.Repository
-import Subversion.Types
-import System.FilePath.Posix
-
-
-mkPagePath :: PageName -> FilePath
-mkPagePath name
- = "/pages" > encodePageName name <.> "page"
-
-
-mkDirPath :: PageName -> FilePath
-mkDirPath dir
- = "/pages" > encodePageName dir
-
-
-mkAttachmentPath :: PageName -> String -> FilePath
-mkAttachmentPath pName aName
- = "/attachments" > encodePageName pName <.> "page" > aName
-
-
-mkAttachmentDirPath :: PageName -> FilePath
-mkAttachmentDirPath pName
- = "/attachments" > encodePageName pName <.> "page"
-
-
-findAllPagesInRevision :: Repository -> RevNum -> IO (Set PageName)
-findAllPagesInRevision repos rev
- = do fs <- getRepositoryFS repos
- withRevision fs rev
- $ do exists <- isDirectory root
- if exists then
- traverse root
- else
- return S.empty
- where
- root :: FilePath
- root = "/pages"
-
- traverse :: FilePath -> Rev (Set PageName)
- traverse dir
- = liftM S.unions (getDirEntries dir >>= mapM (traverse' dir))
-
- traverse' :: FilePath -> DirEntry -> Rev (Set PageName)
- traverse' dir entry
- = let path = dir > entName entry
- in
- do kind <- checkPath path
- case kind of
- NoNode -> return S.empty
- FileNode -> return $ S.singleton (decodePath path)
- DirNode -> traverse path
-
- decodePath :: FilePath -> PageName
- decodePath = decodePageName . makeRelative root . dropExtension
-
-
-getDirContentsInRevision :: Repository -> PageName -> Maybe RevNum -> IO (Set PageName)
-getDirContentsInRevision repos dir rev
- = do fs <- getRepositoryFS repos
- rev' <- case rev of
- Nothing -> getYoungestRev fs
- Just r -> return r
- withRevision fs rev'
- $ do exists <- isDirectory path
- if exists then
- return . S.fromList =<< getDir'
- else
- return S.empty
- where
- path :: FilePath
- path = mkDirPath dir
-
- getDir' :: Rev [PageName]
- getDir' = liftM (map entToName) (getDirEntries path)
-
- entToName :: DirEntry -> PageName
- entToName = (dir >) . decodePageName . dropExtension . entName
-
-
-findChangedPagesAtRevision :: Repository -> RevNum -> IO (Set PageName)
-findChangedPagesAtRevision repos rev
- = do fs <- getRepositoryFS repos
- withRevision fs rev
- $ liftM (foldl accumulatePages S.empty . map fst) getPathsChanged
- where
- accumulatePages :: Set PageName -> FilePath -> Set PageName
- accumulatePages s path
- | "/pages/" `isPrefixOf` path && ".page" `isSuffixOf` path
- = let encoded = makeRelative "/pages" $ dropExtension path
- name = decodePageName encoded
- in
- S.insert name s
- | otherwise
- = s
-
-
-loadPageInRepository :: Repository -> PageName -> Maybe RevNum -> IO (Maybe Page)
-loadPageInRepository repos name rev
- = do fs <- getRepositoryFS repos
- rev' <- case rev of
- Nothing -> getYoungestRev fs
- Just r -> return r
- withRevision fs rev'
- $ do exists <- isFile path
- if exists then
- return . Just =<< loadPage' fs
- else
- return Nothing
- where
- path :: FilePath
- path = mkPagePath name
-
- loadPage' :: FileSystem -> Rev Page
- loadPage' fs
- = do mType <- liftM (fmap (read . chomp)) (getNodeProp path "svn:mime-type")
- case mType of
- Just (MIMEType "application" "x-rakka-redirection" _)
- -> loadPageRedirect fs
- _
- -> loadPageEntity fs
-
- loadPageEntity :: FileSystem -> Rev Page
- loadPageEntity fs
- = do props <- getNodePropList path
- hist <- getNodeHistory True path
- content <- getFileContentsLBS path
-
- let pageRev = fst $ head hist
- mimeType = read
- $ fromMaybe "text/x-rakka"
- $ fmap chomp (lookup "svn:mime-type" props)
-
- lastMod <- unsafeIOToFS $
- liftM (fromJust . parseW3CDateTime . chomp . fromJust)
- (getRevisionProp' fs pageRev "svn:date")
-
- return Entity {
- entityName = name
- , entityType = mimeType
- , entityLanguage = fmap chomp (lookup "rakka:lang" props)
- , entityIsTheme = any ((== "rakka:isTheme") . fst) props
- , entityIsFeed = any ((== "rakka:isFeed") . fst) props
- , entityIsLocked = any ((== "rakka:isLocked") . fst) props
- , entityIsBinary = case mimeType of
- MIMEType "text" _ _
- -> any ((== "rakka:isBinary") . fst) props
- _
- -> True
- , entityRevision = pageRev
- , entityLastMod = zonedTimeToUTC lastMod
- , entitySummary = fmap decodeString (lookup "rakka:summary" props)
- , entityOtherLang = fromMaybe M.empty
- $ fmap
- (M.fromList . fromJust . deserializeStringPairs . decodeString)
- (lookup "rakka:otherLang" props)
- , entityContent = content
- , entityUpdateInfo = undefined
- }
-
- loadPageRedirect :: FileSystem -> Rev Page
- loadPageRedirect fs
- = do hist <- getNodeHistory True path
- content <- getFileContents path
-
- let pageRev = fst $ head hist
- dest = chomp $ decodeString content
-
- lastMod <- unsafeIOToFS $
- liftM (fromJust . parseW3CDateTime . chomp . fromJust)
- (getRevisionProp' fs pageRev "svn:date")
-
- isLocked <- liftM isJust (getNodeProp path "rakka:isLocked")
-
- return Redirection {
- redirName = name
- , redirDest = dest
- , redirIsLocked = isLocked
- , redirRevision = pageRev
- , redirLastMod = zonedTimeToUTC lastMod
- , redirUpdateInfo = undefined
- }
-
-
-putPageIntoRepository :: Repository -> Maybe String -> Page -> IO StatusCode
-putPageIntoRepository repos userID page
- = do let name = pageName page
- author = fromMaybe "[Rakka]" userID
- case pageUpdateInfo page of
- Just ui
- -> do let oldRev = uiOldRevision ui
- denied <- case uiOldName ui of
- Nothing -> checkDenial oldRev name
- Just oldName -> checkDenial oldRev oldName
- if denied then
- return Forbidden
- else
- do rev <- if oldRev == 0 then
- getRepositoryFS repos >>= getYoungestRev
- else
- return oldRev
- ret <- doReposTxn
- repos
- rev
- author
- (Just "Automatic commit by Rakka for page update")
- $ do
- case uiOldName ui of
- Nothing -> return ()
- Just oldName -> do exists <- isFile (mkPagePath oldName)
- when exists
- $ do movePage (uiOldRevision ui) oldName name
- moveAttachments (uiOldRevision ui) oldName name
- exists <- isFile (mkPagePath name)
- unless exists
- $ createPage name
- updatePage name
- case ret of
- Left _ -> return Conflict
- Right _ -> return Created
- Nothing
- -> do fs <- getRepositoryFS repos
- rev <- getYoungestRev fs
- ret <- doReposTxn
- repos
- rev
- author
- (Just "Automatic commit by Rakka for page creation")
- $ do createPage name
- updatePage name
- case ret of
- Left _ -> return Conflict
- Right _ -> return Created
- where
- checkDenial :: RevNum -> PageName -> IO Bool
- checkDenial rev name
- = do fs <- getRepositoryFS repos
- withRevision fs rev
- $ do exists <- isFile (mkPagePath name)
- if exists then
- do prop <- getNodeProp (mkPagePath name) "rakka:isLocked"
- case prop of
- Just _ -> return (isNothing userID) -- 施錠されてゐるので匿名では駄目
- Nothing -> return False
- else
- return False -- FIXME: 本當は defaultPage の locked 屬性をどうのこうの…
-
- movePage :: RevNum -> PageName -> PageName -> Txn ()
- movePage oldRev oldName newName
- = do let oldPath = mkPagePath oldName
- newPath = mkPagePath newName
- createParentDirectories newPath
- copyEntry oldRev oldPath newPath
- deleteEntry oldPath
- deleteEmptyParentDirectories oldPath
-
- moveAttachments :: RevNum -> PageName -> PageName -> Txn ()
- moveAttachments oldRev oldName newName
- = do let oldPath = mkAttachmentDirPath oldName
- newPath = mkAttachmentDirPath newName
- createParentDirectories newPath
- copyEntry oldRev oldPath newPath
- deleteEntry oldPath
- deleteEmptyParentDirectories oldPath
-
- createPage :: PageName -> Txn ()
- createPage name
- = do let path = mkPagePath name
- createParentDirectories path
- makeFile path
-
- updatePage :: PageName -> Txn ()
- updatePage name
- | isRedirect page = updatePageRedirect name
- | isEntity page = updatePageEntity name
- | otherwise = fail "neither redirection nor page"
-
- updatePageRedirect :: PageName -> Txn ()
- updatePageRedirect name
- = do let path = mkPagePath name
- setNodeProp path "svn:mime-type" (Just "application/x-rakka-redirection")
- setNodeProp path "rakka:lang" Nothing
- setNodeProp path "rakka:isTheme" Nothing
- setNodeProp path "rakka:isFeed" Nothing
- setNodeProp path "rakka:isLocked" (encodeFlag $ redirIsLocked page)
- setNodeProp path "rakka:isBinary" Nothing
- setNodeProp path "rakka:summary" Nothing
- setNodeProp path "rakka:otherLang" Nothing
- applyText path Nothing (encodeString (redirDest page) ++ "\n")
-
- updatePageEntity :: PageName -> Txn ()
- updatePageEntity name
- = do let path = mkPagePath name
- setNodeProp path "svn:mime-type" ((Just . show . entityType) page)
- setNodeProp path "rakka:lang" (entityLanguage page)
- setNodeProp path "rakka:isTheme" (encodeFlag $ entityIsTheme page)
- setNodeProp path "rakka:isFeed" (encodeFlag $ entityIsFeed page)
- setNodeProp path "rakka:isLocked" (encodeFlag $ entityIsLocked page)
- setNodeProp path "rakka:isBinary" (encodeFlag $ entityIsBinary page)
- setNodeProp path "rakka:summary" (fmap encodeString $ entitySummary page)
- setNodeProp path "rakka:otherLang" (let otherLang = entityOtherLang page
- in
- if M.null otherLang then
- Nothing
- else
- Just (encodeString $ serializeStringPairs $ M.toList otherLang))
- applyTextLBS path Nothing (entityContent page)
-
- encodeFlag :: Bool -> Maybe String
- encodeFlag True = Just "*"
- encodeFlag False = Nothing
-
-
-createParentDirectories :: FilePath -> Txn ()
-createParentDirectories path
- = do let parentPath = takeDirectory path
- kind <- checkPath parentPath
- case kind of
- NoNode -> do createParentDirectories parentPath
- makeDirectory parentPath
- FileNode -> fail ("createParentDirectories: already exists a file: " ++ parentPath)
- DirNode -> return ()
-
-
-deletePageFromRepository :: Repository -> Maybe String -> PageName -> IO StatusCode
-deletePageFromRepository repos userID name
- = do let pagePath = mkPagePath name
- attachmentPath = mkAttachmentDirPath name
- fs <- getRepositoryFS repos
- rev <- getYoungestRev fs
- status <- withRevision fs rev
- $ do exists <- isFile pagePath
- if exists then
- do prop <- getNodeProp pagePath "rakka:isLocked"
- return $ case prop of
- Just _
- -> if isNothing userID then
- -- 施錠されてゐるので匿名では駄目
- Forbidden
- else
- NoContent
- Nothing
- -> NoContent
- else
- return NotFound
- when (status == NoContent)
- $ ( (doReposTxn repos
- rev
- "[Rakka]"
- (Just "Automatic commit by Rakka for page deleting")
- $ do deleteEntry pagePath
- deleteEmptyParentDirectories pagePath
-
- attachmentExists <- isDirectory attachmentPath
- when attachmentExists
- $ do deleteEntry attachmentPath
- deleteEmptyParentDirectories attachmentPath)
- >> return () )
- return status
-
-
-deleteEmptyParentDirectories :: FilePath -> Txn ()
-deleteEmptyParentDirectories path
- = do let parentPath = takeDirectory path
- contents <- getDirEntries parentPath
- when (null contents)
- $ do deleteEntry parentPath
- deleteEmptyParentDirectories parentPath
-
-
-loadAttachmentInRepository :: forall a. Attachment a =>
- Repository
- -> PageName
- -> String
- -> Maybe RevNum
- -> IO (Maybe a)
-loadAttachmentInRepository repos pName aName rev
- = do fs <- getRepositoryFS repos
- rev' <- case rev of
- Nothing -> getYoungestRev fs
- Just r -> return r
- withRevision fs rev'
- $ do exists <- isFile path
- if exists then
- return . Just =<< loadAttachment'
- else
- return Nothing
- where
- path :: FilePath
- path = mkAttachmentPath pName aName
-
- loadAttachment' :: Rev a
- loadAttachment' = liftM (deserializeFromString . decodeString) (getFileContents path)
-
-
-putAttachmentIntoRepository :: Attachment a =>
- Repository
- -> Maybe String
- -> Maybe RevNum
- -> PageName
- -> String
- -> a
- -> IO StatusCode
-putAttachmentIntoRepository repos userID oldRev pName aName attachment
- = do let author = fromMaybe "[Rakka]" userID
- path = mkAttachmentPath pName aName
- fs <- getRepositoryFS repos
- oldRev' <- case oldRev of
- Nothing -> getYoungestRev fs
- Just r -> return r
- ret <- doReposTxn
- repos
- oldRev'
- author
- (Just "Automatic commit by Rakka for putting attachment")
- $ do exists <- isFile path
- unless exists
- $ do createParentDirectories path
- makeFile path
- applyText path Nothing (encodeString $ serializeToString attachment)
- case ret of
- Left _ -> return Conflict
- Right _ -> return NoContent
rmfile ./Rakka/Storage/Repos.hs
hunk ./Rakka/Storage/Types.hs 1
-module Rakka.Storage.Types
- ( Storage(..)
- , IndexReq(..)
- , SearchResult(..)
- , HitPage(..)
- , SnippetFragment(..)
- )
- where
-
-import Control.Concurrent.STM
-import Data.Time
-import Rakka.Page
-import Subversion.Repository
-import Subversion.Types
-import Text.HyperEstraier hiding (WriteLock)
-
-
-data Storage
- = Storage {
- stoRepository :: !Repository
- , stoIndexChan :: !(TChan IndexReq)
- }
-
-
-data IndexReq
- = RebuildIndex
- | SyncIndex
- | SearchIndex !Condition !(TMVar SearchResult)
-
-
-data SearchResult
- = SearchResult {
- srTotal :: !Int
- , srPages :: ![HitPage]
- }
- deriving (Show, Eq)
-
-
-data HitPage
- = HitPage {
- hpPageName :: !PageName
- , hpPageRev :: RevNum
- , hpLastMod :: UTCTime
- , hpSummary :: Maybe String
- , hpSnippet :: [SnippetFragment]
- }
- deriving (Show, Eq)
-
-
-data SnippetFragment
- = Boundary
- | NormalText !String
- | HighlightedWord !String
- deriving (Show, Eq)
+
rmfile ./Rakka/Storage/Types.hs
rmdir ./Rakka/Storage
hunk ./Rakka/Storage.hs 1
-module Rakka.Storage
- ( Storage
-
- -- re-export from Rakka.Storage.Types
- , SearchResult(..)
- , HitPage(..)
- , SnippetFragment(..)
-
- , mkStorage -- private
-
- , getPage
- , putPage
- , deletePage
-
- , getPageA
- , putPageA
- , deletePageA
-
- , getAttachment
- , putAttachment
-
- , getDirContents
- , getDirContentsA
-
- , searchPages
-
- , rebuildIndex
- )
- where
-
-import Control.Arrow.ArrowIO
-import Control.Concurrent.STM
-import Control.Monad.Trans
-import Network.HTTP.Lucu
-import Rakka.Attachment
-import Rakka.Page
-import Rakka.Storage.Impl
-import Rakka.Storage.Types
-import Subversion.Types
-import Subversion.Repository
-import Text.HyperEstraier hiding (WriteLock)
-
-
-mkStorage :: FilePath -> Repository -> (Page -> IO Document) -> IO Storage
-mkStorage lsdir repos mkDraft
- = do chan <- startIndexManager lsdir repos mkDraft
- let sto = Storage {
- stoRepository = repos
- , stoIndexChan = chan
- }
- syncIndex sto
- return sto
-
-
-getPage :: MonadIO m => Storage -> PageName -> Maybe RevNum -> m (Maybe Page)
-getPage = ((liftIO .) .) . getPage' . stoRepository
-
-
-putPage :: MonadIO m => Storage -> Maybe String -> Page -> m StatusCode
-putPage sto userID page
- = liftIO $ do st <- putPage' (stoRepository sto) userID page
- syncIndex sto
- return st
-
-
-deletePage :: MonadIO m => Storage -> Maybe String -> PageName -> m StatusCode
-deletePage sto userID name
- = liftIO $ do st <- deletePage' (stoRepository sto) userID name
- syncIndex sto
- return st
-
-
-getPageA :: ArrowIO a => Storage -> a (PageName, Maybe RevNum) (Maybe Page)
-getPageA = arrIO2 . getPage
-
-
-putPageA :: ArrowIO a => Storage -> a (Maybe String, Page) StatusCode
-putPageA = arrIO2 . putPage
-
-
-deletePageA :: ArrowIO a => Storage -> a (Maybe String, PageName) StatusCode
-deletePageA = arrIO2 . deletePage
-
-
-getDirContents :: MonadIO m => Storage -> PageName -> Maybe RevNum -> m [PageName]
-getDirContents = ((liftIO .) .) . getDirContents' . stoRepository
-
-
-getDirContentsA :: ArrowIO a => Storage -> a (PageName, Maybe RevNum) [PageName]
-getDirContentsA = arrIO2 . getDirContents
-
-
-searchPages :: MonadIO m => Storage -> Condition -> m SearchResult
-searchPages sto cond
- = liftIO $
- do var <- newEmptyTMVarIO
- atomically $ writeTChan (stoIndexChan sto) (SearchIndex cond var)
- atomically $ takeTMVar var
-
-
-rebuildIndex :: MonadIO m => Storage -> m ()
-rebuildIndex sto
- = liftIO $ atomically $ writeTChan (stoIndexChan sto) RebuildIndex
-
-
-syncIndex :: Storage -> IO ()
-syncIndex sto
- = atomically $ writeTChan (stoIndexChan sto) SyncIndex
-
-
-getAttachment :: (Attachment a, MonadIO m) =>
- Storage
- -> PageName
- -> String
- -> Maybe RevNum
- -> m (Maybe a)
-getAttachment = (((liftIO .) .) .) . getAttachment' . stoRepository
-
-
-putAttachment :: (Attachment a, MonadIO m) =>
- Storage
- -> Maybe String
- -> Maybe RevNum
- -> PageName
- -> String
- -> a
- -> m StatusCode
-putAttachment = (((((liftIO .) .) .) .) .) . putAttachment' . stoRepository
rmfile ./Rakka/Storage.hs
hunk ./Rakka/SystemConfig.hs 1
-module Rakka.SystemConfig
- ( SystemConfig
- , SysConfValue(..)
-
- , mkSystemConfig -- private
-
- , getSysConf
- , getSysConfA
-
- , setSysConf
- , setSysConfA
-
- , SiteName(..)
- , BaseURI(..)
- , DefaultPage(..)
- , StyleSheet(..)
- , Languages(..)
- , GlobalLock(..)
-
- , serializeStringPairs
- , deserializeStringPairs
- )
- where
-
-import Codec.Binary.UTF8.String
-import Control.Arrow.ArrowIO
-import Control.Concurrent.STM
-import Control.Monad
-import Control.Monad.Trans
-import qualified Data.ByteString.Char8 as C8
-import qualified Data.ByteString.Lazy as L
-import Data.Dynamic
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.Maybe
-import GHC.Conc (unsafeIOToSTM)
-import Network
-import qualified Network.HTTP.Lucu.Config as LC
-import Network.HTTP.Lucu.Utils
-import Network.HTTP.Lucu hiding (Config)
-import Network.URI hiding (path)
-import Rakka.Page
-import Rakka.Utils
-import Subversion.FileSystem
-import Subversion.FileSystem.Revision
-import Subversion.FileSystem.Root
-import Subversion.FileSystem.Transaction
-import Subversion.Repository
-import Subversion.Types
-import System.FilePath.Posix
-import System.Log.Logger
-
-
-logger :: String
-logger = "Rakka.SystemConfig"
-
-
-data SystemConfig = SystemConfig {
- scLucuConf :: !LC.Config
- , scRepository :: !Repository
- , scCache :: !(TVar (Map FilePath Dynamic))
- }
-
-
-class (Typeable a, Show a, Eq a) => SysConfValue a where
- confPath :: a -> FilePath
- serialize :: a -> String
- deserialize :: String -> Maybe a
- defaultValue :: SystemConfig -> a
-
-
-mkSystemConfig :: LC.Config -> Repository -> IO SystemConfig
-mkSystemConfig lc repos
- = do cache <- newTVarIO M.empty
- return SystemConfig {
- scLucuConf = lc
- , scRepository = repos
- , scCache = cache
- }
-
-getSysConf :: forall m a. (MonadIO m, SysConfValue a) => SystemConfig -> m a
-getSysConf sc
- = liftIO $
- atomically $
- do let path = confPath (undefined :: a)
-
- cache <- readTVar (scCache sc)
-
- case M.lookup path cache of
- Just val -> return $ fromJust $ fromDynamic val
- Nothing -> do val <- unsafeIOToSTM (getSysConf' sc)
- writeTVar (scCache sc) (M.insert path (toDyn val) cache)
- return val
-
-
-getSysConf' :: forall a. SysConfValue a => SystemConfig -> IO a
-getSysConf' sc
- = do let path = fromConfPath $ confPath (undefined :: a)
-
- fs <- getRepositoryFS (scRepository sc)
- rev <- getYoungestRev fs
- value <- withRevision fs rev
- $ do exists <- isFile path
- case exists of
- True
- -> do str <- getFileContentsLBS path
- return $ Just $ chomp $ decode $ L.unpack str
- False
- -> return Nothing
-
- case value of
- Just str
- -> case deserialize str of
- Just val
- -> do debugM logger ("Got a config value at `" ++ path ++ "': " ++ show val)
- return val
- Nothing
- -> fail ("Got an invalid config value at `" ++ path ++ "': " ++ str)
- Nothing
- -> do let val = defaultValue sc
- debugM logger ("Got no config value at `" ++ path ++ "'. Defaulting to " ++ show val)
- return val
-
-
-setSysConf :: forall m a. (MonadIO m, SysConfValue a) => SystemConfig -> String -> a -> m StatusCode
-setSysConf sc userID value
- = liftIO $
- do let path = confPath (undefined :: a)
-
- current <- getSysConf sc
- if current == value
- then return NotModified
- else do atomically $ do cache <- readTVar (scCache sc)
- writeTVar (scCache sc) (M.delete path cache)
- setSysConf' sc userID value
-
-
-setSysConf' :: forall a. SysConfValue a => SystemConfig -> String -> a -> IO StatusCode
-setSysConf' sc userID value
- = do let path = fromConfPath $ confPath (undefined :: a)
- str = L.pack $ encode $ serialize value ++ "\n"
- repos = scRepository sc
- fs <- getRepositoryFS repos
- rev <- getYoungestRev fs
- ret <- doReposTxn
- repos
- rev
- userID
- (Just "Automatic commit by Rakka for systemConfig update")
- $ do exists <- isFile path
- unless exists
- $ createValueEntry path
- applyTextLBS path Nothing str
- case ret of
- Left _ -> return Conflict
- Right _ -> do debugM logger ("Set a config value at `" ++ path ++ "': " ++ show value)
- return Created
- where
- createValueEntry :: FilePath -> Txn ()
- createValueEntry path
- = do createParentDirectories path
- makeFile path
-
- createParentDirectories :: FilePath -> Txn ()
- createParentDirectories path
- = do let parentPath = takeDirectory path
- kind <- checkPath parentPath
- case kind of
- NoNode -> do createParentDirectories parentPath
- makeDirectory parentPath
- FileNode -> fail ("createParentDirectories: already exists a file: " ++ parentPath)
- DirNode -> return ()
-
-
-getSysConfA :: (ArrowIO a, SysConfValue c) => SystemConfig -> a b c
-getSysConfA = arrIO0 . getSysConf
-
-
-setSysConfA :: (ArrowIO a, SysConfValue c) => SystemConfig -> String -> a c StatusCode
-setSysConfA = (arrIO .) . setSysConf
-
-
-fromConfPath :: FilePath -> FilePath
-fromConfPath = ("/config" >)
-
-
-serializeStringPairs :: [(String, String)] -> String
-serializeStringPairs = joinWith "\n" . map serializePair'
- where
- serializePair' :: (String, String) -> String
- serializePair' (a, b) = a ++ " " ++ b
-
-
-deserializeStringPairs :: String -> Maybe [(String, String)]
-deserializeStringPairs = mapM deserializePair' . lines
- where
- deserializePair' :: String -> Maybe (String, String)
- deserializePair' s = case break (== ' ') s of
- (a, ' ':b) -> Just (a, b)
- _ -> Nothing
-
-
-
-{- config values -}
-
-newtype SiteName = SiteName String deriving (Show, Typeable, Eq)
-instance SysConfValue SiteName where
- confPath _ = "siteName"
- serialize (SiteName name) = name
- deserialize = Just . SiteName
- defaultValue _ = SiteName "Rakka"
-
-
-newtype BaseURI = BaseURI URI deriving (Show, Typeable, Eq)
-instance SysConfValue BaseURI where
- confPath _ = "baseURI"
- serialize (BaseURI uri) = uriToString id uri ""
- deserialize uri = fmap BaseURI
- $ do parsed <- parseURI uri
- when (uriPath parsed == "" ) (fail undefined)
- when (last (uriPath parsed) /= '/') (fail undefined)
- when (uriQuery parsed /= "" ) (fail undefined)
- when (uriFragment parsed /= "" ) (fail undefined)
- return parsed
- defaultValue sc
- = let conf = scLucuConf sc
- host = C8.unpack $ LC.cnfServerHost conf
- port = case LC.cnfServerPort conf of
- PortNumber num -> fromIntegral num :: Int
- _ -> undefined
- defaultURI
- = "http://" ++ host ++ -- FIXME: consider IPv6 address
- (if port == 80
- then ""
- else ':' : show port) ++ "/"
- in
- BaseURI $ fromJust $ parseURI defaultURI
-
-
-newtype DefaultPage = DefaultPage String deriving (Show, Typeable, Eq)
-instance SysConfValue DefaultPage where
- confPath _ = "defaultPage"
- serialize (DefaultPage name) = name
- deserialize = Just . DefaultPage
- defaultValue _ = DefaultPage "MainPage"
-
-
-newtype StyleSheet = StyleSheet String deriving (Show, Typeable, Eq)
-instance SysConfValue StyleSheet where
- confPath _ = "styleSheet"
- serialize (StyleSheet name) = name
- deserialize = Just . StyleSheet
- defaultValue _ = StyleSheet "StyleSheet/Default"
-
-
-newtype Languages = Languages (Map LanguageTag LanguageName) deriving (Show, Typeable, Eq)
-instance SysConfValue Languages where
- confPath _ = "languages"
- serialize (Languages langs) = serializeStringPairs (M.toList langs)
- deserialize = fmap (Languages . M.fromList) . deserializeStringPairs
- defaultValue _
- = Languages $ M.fromList [ ("en", "English" )
- , ("es", "Español" )
- , ("de", "Deutsch" )
- , ("fi", "Suomi" )
- , ("fr", "Français" )
- , ("ga", "Gaeilge" )
- , ("gd", "Gàidhlig" )
- , ("ja", "日本語" )
- , ("pt", "Português")
- , ("sv", "Svenska" )
- ]
-
-
-newtype GlobalLock = GlobalLock Bool deriving (Show, Typeable, Eq)
-instance SysConfValue GlobalLock where
- confPath _ = "globalLock"
- serialize (GlobalLock isLocked)
- | isLocked = "*"
- | otherwise = ""
- deserialize "*" = Just (GlobalLock True)
- deserialize "" = Just (GlobalLock False)
- deserialize _ = Nothing
- defaultValue _ = GlobalLock False
rmfile ./Rakka/SystemConfig.hs
hunk ./Rakka/TrackBack.hs 1
-module Rakka.TrackBack
- ( TrackBack(..)
- )
- where
-
-import Data.Maybe
-import Data.Time
-import Network.URI
-import Rakka.Attachment
-import Rakka.Utils
-import Rakka.W3CDateTime
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.DOM.TypeDefs
-
-
-data TrackBack
- = TrackBack {
- tbTitle :: !(Maybe String)
- , tbExcerpt :: !(Maybe String)
- , tbURL :: !URI
- , tbBlogName :: !(Maybe String)
- , tbTime :: !UTCTime
- }
- deriving (Show, Eq)
-
-
-{-
-
-
- excerpt...
-
- ...
-
--}
-instance Attachment [TrackBack] where
- serializeToXmlTree
- = proc trackbacks
- -> ( eelem "/"
- += ( eelem "trackbacks"
- += ( arrL id
- >>>
- tbToTree
- )
- )
- ) -< trackbacks
- where
- tbToTree :: ArrowXml a => a TrackBack XmlTree
- tbToTree
- = proc tb
- -> let title = case tbTitle tb of
- Nothing -> none
- Just t -> sattr "title" t
- excerpt = case tbExcerpt tb of
- Nothing -> none
- Just e -> txt e
- url = sattr "url" (uriToString id (tbURL tb) "")
- blogName = case tbBlogName tb of
- Nothing -> none
- Just n -> sattr "blogName" n
- time = sattr "time" (formatW3CDateTime $ utcToZonedTime utc (tbTime tb))
- in
- ( eelem "trackback"
- += title
- += url
- += blogName
- += time
- += excerpt
- ) -<< ()
-
- deserializeFromXmlTree
- = proc doc -> listA (getXPathTreesInDoc "/trackbacks/trackback" >>> treeToTb) -< doc
- where
- treeToTb :: (ArrowChoice a, ArrowXml a) => a XmlTree TrackBack
- treeToTb
- = proc tree
- -> do title <- maybeA (getAttrValue0 "title") -< tree
- url <- ( getAttrValue0 "url"
- >>>
- arr (fromJust . parseURI)
- ) -< tree
- time <- ( getAttrValue0 "time"
- >>>
- arr (zonedTimeToUTC . fromJust . parseW3CDateTime)
- ) -< tree
- blogName <- maybeA (getAttrValue0 "blogName") -< tree
- excerpt <- maybeA ( getChildren
- >>>
- getText
- ) -< tree
- returnA -< TrackBack {
- tbTitle = title
- , tbExcerpt = excerpt
- , tbURL = url
- , tbBlogName = blogName
- , tbTime = time
- }
rmfile ./Rakka/TrackBack.hs
hunk ./Rakka/Utils.hs 1
-module Rakka.Utils
- ( yesOrNo
- , trueOrFalse
- , parseYesOrNo
- , maybeA
- , deleteIfEmpty
- , chomp
- , guessMIMEType
- , isSafeChar
- , mkQueryString
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import Control.Arrow
-import Control.Arrow.ArrowList
-import qualified Data.ByteString.Lazy as Lazy (ByteString)
-import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
-import Magic
-import Network.HTTP.Lucu
-import Network.URI
-import System.IO.Unsafe
-
-
-yesOrNo :: Bool -> String
-yesOrNo True = "yes"
-yesOrNo False = "no"
-
-
-trueOrFalse :: Bool -> String
-trueOrFalse True = "true"
-trueOrFalse False = "false"
-
-
-parseYesOrNo :: ArrowChoice a => a String Bool
-parseYesOrNo
- = proc str -> do case str of
- "yes" -> returnA -< True
- "no" -> returnA -< False
- _ -> returnA -< error ("Expected yes or no: " ++ str)
-
-
-maybeA :: (ArrowList a, ArrowChoice a) => a b c -> a b (Maybe c)
-maybeA a = listA a
- >>>
- proc xs -> case xs of
- [] -> returnA -< Nothing
- (x:_) -> returnA -< Just x
-
-
-deleteIfEmpty :: (ArrowList a, ArrowChoice a) => a String String
-deleteIfEmpty
- = proc str -> do case str of
- "" -> none -< ()
- _ -> returnA -< str
-
-
-chomp :: String -> String
-chomp = reverse . snd . break (/= '\n') . reverse
-
-
-guessMIMEType :: Lazy.ByteString -> MIMEType
-guessMIMEType = read . unsafePerformIO . magicString magic . L8.unpack
- where
- magic :: Magic
- magic = unsafePerformIO
- $ do m <- magicOpen [MagicMime]
- magicLoadDefault m
- return m
-
-
-isSafeChar :: Char -> Bool
-isSafeChar c
- | c == '/' = True
- | isReserved c = False
- | c > ' ' && c <= '~' = True
- | otherwise = False
-
-
-mkQueryString :: [(String, String)] -> String
-mkQueryString [] = ""
-mkQueryString ((k, v) : xs) = encode k ++ "=" ++ encode v ++
- if xs == [] then
- ""
- else
- ';' : mkQueryString(xs)
- where
- encode :: String -> String
- encode = escapeURIString isSafeChar . UTF8.encodeString
+
rmfile ./Rakka/Utils.hs
hunk ./Rakka/Validation.hs 1
-module Rakka.Validation
- ( getValidator
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowList
-import Control.Arrow.ArrowTree
-import Control.Monad.Reader
-import Paths_Rakka -- Cabal が用意する。
-import Rakka.Environment
-import System.Directory
-import System.FilePath
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.Arrow.XmlIOStateArrow
-import Text.XML.HXT.DOM.TypeDefs
-import qualified Text.XML.HXT.RelaxNG.Schema as S
-import Text.XML.HXT.RelaxNG.Validator
-
-
-loadSchema :: FilePath -> IO (IOSArrow XmlTree XmlTree)
-loadSchema fpath
- = do [schema] <- runX ( setErrorMsgHandler False fail
- >>>
- readForRelax [] fpath
- >>>
- perform (validateWithRelaxAndHandleErrors S.relaxSchemaArrow)
- >>>
- createSimpleForm [] True True True
- >>>
- perform ( getErrors
- >>>
- getChildren >>> getAttrValue "desc"
- >>>
- arr ("Relax NG validation: " ++ )
- >>>
- mkError c_err
- >>>
- filterErrorMsg
- )
- )
- return $ validateDocumentWithRelax schema
-
-
-doesLocalDirExist :: IO Bool
-doesLocalDirExist = doesDirectoryExist "schemas"
-
-
-getValidator :: MonadIO m => Environment -> FilePath -> m (IOSArrow XmlTree XmlTree)
-getValidator _ fname
- = liftIO $
- do let schemaPath = "schemas" > fname
-
- localDirExists <- doesLocalDirExist
- if localDirExists then
- loadSchema schemaPath
- else
- getDataFileName ("schemas" > fname) >>= loadSchema
rmfile ./Rakka/Validation.hs
hunk ./Rakka/W3CDateTime.hs 1
-module Rakka.W3CDateTime
- ( formatW3CDateTime
- , parseW3CDateTime
- )
- where
-
-import Control.Monad
-import Data.Time
-import Prelude hiding (min)
-import Text.ParserCombinators.Parsec
-import Text.Printf
-
-
-formatW3CDateTime :: ZonedTime -> String
-formatW3CDateTime zonedTime
- = formatLocalTime (zonedTimeToLocalTime zonedTime)
- ++
- formatTimeZone (zonedTimeZone zonedTime)
- where
- formatLocalTime :: LocalTime -> String
- formatLocalTime localTime
- = let (year, month, day) = toGregorian (localDay localTime)
- timeOfDay = localTimeOfDay localTime
- (secInt, secFrac) = properFraction (todSec timeOfDay)
- in
- printf "%04d-%02d-%02dT%02d:%02d:%02d"
- year
- month
- day
- (todHour timeOfDay)
- (todMin timeOfDay)
- (secInt :: Int)
- ++
- (if secFrac == 0
- then ""
- else tail (show secFrac))
-
- formatTimeZone :: TimeZone -> String
- formatTimeZone tz
- = case timeZoneMinutes tz of
- offset | offset < 0 -> '-' : (showTZ $ negate offset)
- | offset == 0 -> "Z"
- | otherwise -> '+' : showTZ offset
-
- showTZ :: Int -> String
- showTZ offset
- = let hour = offset `div` 60
- minute = offset - hour * 60
- in
- show2 hour ++ ":" ++ show2 minute
-
- show2 :: Int -> String
- show2 n | n < 10 = '0' : show n
- | otherwise = show n
-
-
-parseW3CDateTime :: String -> Maybe ZonedTime
-parseW3CDateTime src
- = case parse w3cDateTime "" src of
- Right zt -> Just zt
- Left _ -> Nothing
-
-w3cDateTime :: Parser ZonedTime
-w3cDateTime = do year <- liftM read (count 4 digit)
- mon <- option 1 (char '-' >> liftM read (count 2 digit))
- day <- option 1 (char '-' >> liftM read (count 2 digit))
- (hour, min, sec, offMin)
- <- option (0, 0, 0, 0) time
- eof
-
- let julianDay = fromGregorian year mon day
- timeOfDay = TimeOfDay hour min (fromRational $ toRational sec)
- localTime = LocalTime julianDay timeOfDay
- timeZone = minutesToTimeZone offMin
- zonedTime = ZonedTime localTime timeZone
-
- return zonedTime
- where
- time :: Parser (Int, Int, Double, Int)
- time = do _ <- char 'T'
- hour <- liftM read (count 2 digit)
- _ <- char ':'
- min <- liftM read (count 2 digit)
- sec <- option 0 $ do _ <- char ':'
- secInt <- count 2 digit
- secFrac <- option "" $ do c <- char '.'
- cs <- many1 digit
- return (c:cs)
- return $ read (secInt ++ secFrac)
- offMin <- (char 'Z' >> return 0)
- <|>
- (do sign <- (char '+' >> return 1)
- <|>
- (char '-' >> return (-1))
- h <- liftM read (count 2 digit)
- _ <- char ':'
- m <- liftM read (count 2 digit)
- return $ sign * h * 60 + m)
- return (hour, min, sec, offMin)
+
rmfile ./Rakka/W3CDateTime.hs
hunk ./Rakka/Wiki/Engine.hs 1
-module Rakka.Wiki.Engine
- ( InterpTable
- , makeMainXHTML
- , makeSubXHTML
- , makePreviewXHTML
- , makePageLinkList
- , makeDraft
- )
- where
-
-import qualified Codec.Binary.UTF8.String as UTF8
-import qualified Data.ByteString.Lazy as Lazy
-import qualified Data.ByteString.Lazy.Char8 as L8 hiding (ByteString)
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.Maybe
-import Network.HTTP.Lucu
-import Network.URI
-import OpenSSL.EVP.Base64
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Utils
-import Rakka.Wiki
-import Rakka.Wiki.Parser
-import Rakka.Wiki.Formatter
-import Rakka.Wiki.Interpreter
-import Text.HyperEstraier hiding (getText)
-import Text.ParserCombinators.Parsec
-import Text.XML.HXT.Arrow hiding (err)
-import Text.XML.HXT.XPath
-
-
-type InterpTable = Map String Interpreter
-
-
-wikifyPage :: (ArrowXml a, ArrowChoice a) => InterpTable -> a XmlTree WikiPage
-wikifyPage interpTable
- = proc tree
- -> do pType <- getXPathTreesInDoc "/page/@type/text()" >>> getText >>> arr read -< tree
- textData <- maybeA (getXPathTreesInDoc "/page/textData/text()" >>> getText) -< tree
- base64Data <- maybeA (getXPathTreesInDoc "/page/binaryData/text()" >>> getText) -< tree
-
- let dataURI = fmap (binToURI pType) base64Data
-
- case pType of
- MIMEType "text" "x-rakka" _
- -> case parse (wikiPage $ cmdTypeOf interpTable) "" (fromJust textData) of
- Left err -> wikifyParseError -< err
- Right xs -> returnA -< xs
-
- MIMEType "image" _ _
- --
- -> returnA -< [ Paragraph [Image (Left $ fromJust dataURI) Nothing] ]
-
- _ -> if isJust dataURI then
- --
- -- application/zip
- --
- returnA -< [ Paragraph [ Anchor
- [("href", show dataURI)]
- [Text (show pType)]
- ]
- ]
- else
- -- pre
- returnA -< [ Preformatted [Text $ fromJust textData] ]
- where
- binToURI :: MIMEType -> String -> URI
- binToURI pType base64Data
- = nullURI {
- uriScheme = "data:"
- , uriPath = show pType ++ ";base64," ++ (stripWhiteSpace base64Data)
- }
-
- stripWhiteSpace :: String -> String
- stripWhiteSpace [] = []
- stripWhiteSpace (x:xs)
- | x `elem` " \t\n" = stripWhiteSpace xs
- | otherwise = x : stripWhiteSpace xs
-
-
-wikifyBin :: (ArrowXml a, ArrowChoice a) => InterpTable -> a (MIMEType, Lazy.ByteString) WikiPage
-wikifyBin interpTable
- = proc (pType, pBin)
- -> do let text = UTF8.decode $ Lazy.unpack pBin
- dataURI = binToURI pType pBin
-
- case pType of
- MIMEType "text" "x-rakka" _
- -> case parse (wikiPage $ cmdTypeOf interpTable) "" text of
- Left err -> wikifyParseError -< err
- Right xs -> returnA -< xs
-
- MIMEType "image" _ _
- --
- -> returnA -< [ Paragraph [Image (Left dataURI) Nothing] ]
-
-
- _
- --
- -- application/zip (19372 bytes)
- --
- -> returnA -< [ Paragraph [ Anchor
- [("href", show dataURI)]
- [Text (show pType ++
- " (" ++
- show (Lazy.length pBin) ++
- " bytes)")]
- ]
- ]
- where
- binToURI :: MIMEType -> Lazy.ByteString -> URI
- binToURI m b
- = nullURI {
- uriScheme = "data:"
- , uriPath = show m ++ ";base64," ++ (L8.unpack $ encodeBase64LBS b)
- }
-
-
-cmdTypeOf :: InterpTable -> String -> Maybe CommandType
-cmdTypeOf interpTable name
- = fmap commandType (M.lookup name interpTable)
-
-
-makeMainXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Storage
- -> SystemConfig
- -> InterpTable
- -> a XmlTree XmlTree
-makeMainXHTML sto sysConf interpTable
- = proc tree
- -> do BaseURI baseURI <- getSysConfA sysConf -< ()
- wiki <- wikifyPage interpTable -< tree
- pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
- interpreted <- interpretCommands sto sysConf interpTable
- -< (Just pName, Just tree, Just wiki, wiki)
- formatWikiBlocks -< (baseURI, interpreted)
-
-
-makeSubXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Storage
- -> SystemConfig
- -> InterpTable
- -> a (Maybe PageName, Maybe XmlTree, XmlTree) XmlTree
-makeSubXHTML sto sysConf interpTable
- = proc (mainPageName, mainPage, subPage)
- -> do BaseURI baseURI <- getSysConfA sysConf -< ()
- mainWiki <- case mainPage of
- Just page
- -> do wiki <- wikifyPage interpTable -< page
- returnA -< Just (page, wiki)
- Nothing
- -> returnA -< Nothing
- subWiki <- wikifyPage interpTable -< subPage
- interpreted <- interpretCommands sto sysConf interpTable
- -< (mainPageName, fmap fst mainWiki, fmap snd mainWiki, subWiki)
- formatWikiBlocks -< (baseURI, interpreted)
-
-
-makePreviewXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Storage
- -> SystemConfig
- -> InterpTable
- -> a (PageName, MIMEType, Lazy.ByteString) XmlTree
-makePreviewXHTML sto sysConf interpTable
- = proc (name, pageType, pageBin)
- -> do BaseURI baseURI <- getSysConfA sysConf -< ()
- wiki <- wikifyBin interpTable -< (pageType, pageBin)
- interpreted <- interpretCommands sto sysConf interpTable
- -< (Just name, Nothing, Just wiki, wiki)
- formatWikiBlocks -< (baseURI, interpreted)
-
-
-interpretCommands :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Storage
- -> SystemConfig
- -> InterpTable
- -> a (Maybe PageName, Maybe XmlTree, Maybe WikiPage, WikiPage) WikiPage
-interpretCommands sto sysConf interpTable
- = proc (name, mainPage, mainWiki, targetWiki)
- -> let ctx = InterpreterContext {
- ctxPageName = name
- , ctxMainPage = mainPage
- , ctxMainWiki = mainWiki
- , ctxTargetWiki = targetWiki
- , ctxStorage = sto
- , ctxSysConf = sysConf
- }
- in
- arrIO2 (mapM . interpBlock) -< (ctx, targetWiki)
- where
- interpElem :: InterpreterContext -> Element -> IO Element
- interpElem ctx (Block b) = interpBlock ctx b >>= return . Block
- interpElem ctx (Inline i) = interpInline ctx i >>= return . Inline
-
- interpBlock :: InterpreterContext -> BlockElement -> IO BlockElement
- interpBlock ctx (List lType lItems) = mapM (interpListItem ctx) lItems >>= return . List lType
- interpBlock ctx (DefinitionList defs) = mapM (interpDefinition ctx) defs >>= return . DefinitionList
- interpBlock ctx (Preformatted inlines) = mapM (interpInline ctx) inlines >>= return . Preformatted
- interpBlock ctx (Paragraph inlines) = mapM (interpInline ctx) inlines >>= return . Paragraph
- interpBlock ctx (Div attrs elems) = mapM (interpElem ctx) elems >>= return . Div attrs
- interpBlock ctx (BlockCmd bcmd) = interpBlockCommand ctx bcmd
- interpBlock _ x = return x
-
- interpInline :: InterpreterContext -> InlineElement -> IO InlineElement
- interpInline ctx (Italic inlines) = mapM (interpInline ctx) inlines >>= return . Italic
- interpInline ctx (Bold inlines) = mapM (interpInline ctx) inlines >>= return . Bold
- interpInline ctx (Span attrs inlines) = mapM (interpInline ctx) inlines >>= return . Span attrs
- interpInline ctx (Anchor attrs inlines) = mapM (interpInline ctx) inlines >>= return . Anchor attrs
- interpInline ctx (InlineCmd icmd) = interpInlineCommand ctx icmd
- interpInline _ x = return x
-
- interpListItem :: InterpreterContext -> ListItem -> IO ListItem
- interpListItem = mapM . interpElem
-
- interpDefinition :: InterpreterContext -> Definition -> IO Definition
- interpDefinition ctx (Definition term desc)
- = do term' <- mapM (interpInline ctx) term
- desc' <- mapM (interpInline ctx) desc
- return (Definition term' desc')
-
- interpBlockCommand :: InterpreterContext -> BlockCommand -> IO BlockElement
- interpBlockCommand ctx cmd
- = case M.lookup (bCmdName cmd) interpTable of
- Nothing
- -> fail ("no such interpreter: " ++ bCmdName cmd)
-
- Just interp
- -> bciInterpret interp ctx cmd
- >>=
- interpBlock ctx
-
- interpInlineCommand :: InterpreterContext -> InlineCommand -> IO InlineElement
- interpInlineCommand ctx cmd
- = case M.lookup (iCmdName cmd) interpTable of
- Nothing
- -> fail ("no such interpreter: " ++ iCmdName cmd)
-
- Just interp
- -> iciInterpret interp ctx cmd
- >>=
- interpInline ctx
-
-
-makeDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => InterpTable -> a XmlTree Document
-makeDraft interpTable
- = proc tree ->
- do redir <- maybeA (getXPathTreesInDoc "/page/@redirect") -< tree
- case redir of
- Nothing -> makeEntityDraft -< tree
- Just _ -> makeRedirectDraft -< tree
- where
- makeEntityDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a XmlTree Document
- makeEntityDraft
- = proc tree ->
- do doc <- arrIO0 newDocument -< ()
-
- pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
- pType <- getXPathTreesInDoc "/page/@type/text()" >>> getText -< tree
- pLastMod <- getXPathTreesInDoc "/page/@lastModified/text()" >>> getText -< tree
- pIsLocked <- getXPathTreesInDoc "/page/@isLocked/text()" >>> getText -< tree
- pIsBinary <- getXPathTreesInDoc "/page/@isBinary/text()" >>> getText -< tree
- pRevision <- getXPathTreesInDoc "/page/@revision/text()" >>> getText -< tree
- pLang <- maybeA (getXPathTreesInDoc "/page/@lang/text()" >>> getText) -< tree
- pIsTheme <- maybeA (getXPathTreesInDoc "/page/@isTheme/text()" >>> getText) -< tree
- pIsFeed <- maybeA (getXPathTreesInDoc "/page/@isFeed/text()" >>> getText) -< tree
- pSummary <- maybeA (getXPathTreesInDoc "/page/summary/text()" >>> getText) -< tree
-
- arrIO2 setURI -< (doc, Just $ mkRakkaURI pName)
- arrIO2 (flip setAttribute "@title" ) -< (doc, Just pName)
- arrIO2 (flip setAttribute "@type" ) -< (doc, Just pType)
- arrIO2 (flip setAttribute "@mdate" ) -< (doc, Just pLastMod)
- arrIO2 (flip setAttribute "@lang" ) -< (doc, pLang)
- arrIO2 (flip setAttribute "rakka:isLocked") -< (doc, Just pIsLocked)
- arrIO2 (flip setAttribute "rakka:isBinary") -< (doc, Just pIsBinary)
- arrIO2 (flip setAttribute "rakka:revision") -< (doc, Just pRevision)
- arrIO2 (flip setAttribute "rakka:summary" ) -< (doc, pSummary)
-
- arrIO2 addHiddenText -< (doc, pName)
-
- case pSummary of
- Just s -> arrIO2 addHiddenText -< (doc, s)
- Nothing -> returnA -< ()
-
- -- otherLang はリンク先ページ名を hidden text で入れる。
- otherLangs <- listA (getXPathTreesInDoc "/page/otherLang/link/@page/text()" >>> getText) -< tree
- listA ( (arr fst &&& arrL snd)
- >>>
- arrIO2 addHiddenText
- >>>
- none
- ) -< (doc, otherLangs)
-
- case read pType of
- MIMEType "text" "css" _
- -> arrIO2 (flip setAttribute "rakka:isTheme") -< (doc, pIsTheme)
-
- MIMEType "text" "x-rakka" _
- -- wikify して興味のある部分を addText する。
- -> do arrIO2 (flip setAttribute "rakka:isFeed") -< (doc, pIsFeed)
- wiki <- wikifyPage interpTable -< tree
- arrIO2 (mapM_ . addBlockText) -< (doc, wiki)
-
- MIMEType _ _ _
- -> returnA -< ()
-
- returnA -< doc
-
- makeRedirectDraft :: (ArrowXml a, ArrowChoice a, ArrowIO a) => a XmlTree Document
- makeRedirectDraft
- = proc tree ->
- do doc <- arrIO0 newDocument -< ()
-
- pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
- pRedir <- getXPathTreesInDoc "/page/@redirect/text()" >>> getText -< tree
- pIsLocked <- getXPathTreesInDoc "/page/@isLocked/text()" >>> getText -< tree
- pRevision <- getXPathTreesInDoc "/page/@revision/text()" >>> getText -< tree
- pLastMod <- getXPathTreesInDoc "/page/@lastModified/text()" >>> getText -< tree
-
- arrIO2 setURI -< (doc, Just $ mkRakkaURI pName)
- arrIO2 (flip setAttribute "@title" ) -< (doc, Just pName)
- arrIO2 (flip setAttribute "@type" ) -< (doc, Just "application/x-rakka-redirection")
- arrIO2 (flip setAttribute "@mdate" ) -< (doc, Just pLastMod)
- arrIO2 (flip setAttribute "rakka:isLocked") -< (doc, Just pIsLocked)
- arrIO2 (flip setAttribute "rakka:revision") -< (doc, Just pRevision)
-
- -- リダイレクト先ページ名はテキストとして入れる
- arrIO2 addText -< (doc, pRedir)
-
- returnA -< doc
-
- addElemText :: Document -> Element -> IO ()
- addElemText doc (Block b) = addBlockText doc b
- addElemText doc (Inline i) = addInlineText doc i
-
- addBlockText :: Document -> BlockElement -> IO ()
- addBlockText doc (Heading _ text) = addText doc text
- addBlockText _ HorizontalLine = return ()
- addBlockText doc (List _ items) = mapM_ (addListItemText doc) items
- addBlockText doc (DefinitionList defs) = mapM_ (addDefinitionText doc) defs
- addBlockText doc (Preformatted inlines) = mapM_ (addInlineText doc) inlines
- addBlockText doc (Paragraph inlines) = mapM_ (addInlineText doc) inlines
- addBlockText doc (Div _ elems) = mapM_ (addElemText doc) elems
- addBlockText _ EmptyBlock = return ()
- addBlockText doc (BlockCmd bcmd) = addBlockCmdText doc bcmd
-
- addInlineText :: Document -> InlineElement -> IO ()
- addInlineText doc (Text text) = addText doc text
- addInlineText doc (Italic inlines) = mapM_ (addInlineText doc) inlines
- addInlineText doc (Bold inlines) = mapM_ (addInlineText doc) inlines
- addInlineText doc (ObjectLink page Nothing) = addText doc page
- addInlineText doc (ObjectLink page (Just text)) = addHiddenText doc page
- >> addText doc text
- addInlineText doc (PageLink page fragm Nothing) = addText doc (fromMaybe "" page ++ fromMaybe "" fragm)
- addInlineText doc (PageLink page fragm (Just text)) = addHiddenText doc (fromMaybe "" page ++ fromMaybe "" fragm)
- >> addText doc text
- addInlineText doc (ExternalLink uri Nothing) = addText doc (uriToString id uri "")
- addInlineText doc (ExternalLink uri (Just text)) = addHiddenText doc (uriToString id uri "")
- >> addText doc text
- addInlineText _ (LineBreak _) = return ()
- addInlineText doc (Span _ inlines) = mapM_ (addInlineText doc) inlines
- addInlineText doc (Image src alt) = do case src of
- Left uri -> addHiddenText doc (uriToString id uri "")
- Right page -> addHiddenText doc page
- case alt of
- Just text -> addHiddenText doc text
- Nothing -> return ()
- addInlineText doc (Anchor _ inlines) = mapM_ (addInlineText doc) inlines
- addInlineText _ (Input _) = return ()
- addInlineText _ EmptyInline = return ()
- addInlineText doc (InlineCmd icmd) = addInlineCmdText doc icmd
-
- addListItemText :: Document -> ListItem -> IO ()
- addListItemText = mapM_ . addElemText
-
- addDefinitionText :: Document -> Definition -> IO ()
- addDefinitionText doc (Definition term desc)
- = do mapM_ (addInlineText doc) term
- mapM_ (addInlineText doc) desc
-
- addBlockCmdText :: Document -> BlockCommand -> IO ()
- addBlockCmdText doc (BlockCommand _ _ blocks) = mapM_ (addBlockText doc) blocks
-
- addInlineCmdText :: Document -> InlineCommand -> IO ()
- addInlineCmdText doc (InlineCommand _ _ inlines) = mapM_ (addInlineText doc) inlines
-
-
-makePageLinkList :: (ArrowXml a, ArrowChoice a, ArrowIO a) =>
- Storage
- -> SystemConfig
- -> InterpTable
- -> a XmlTree [PageName]
-makePageLinkList sto sysConf interpTable
- = proc tree
- -> do wiki <- wikifyPage interpTable -< tree
- pName <- getXPathTreesInDoc "/page/@name/text()" >>> getText -< tree
- interpreted <- interpretCommands sto sysConf interpTable
- -< (Just pName, Just tree, Just wiki, wiki)
- returnA -< concatMap extractFromBlock interpreted
- where
- extractFromElem :: Element -> [PageName]
- extractFromElem (Block b) = extractFromBlock b
- extractFromElem (Inline i) = extractFromInline i
-
- extractFromBlock :: BlockElement -> [PageName]
- extractFromBlock (List _ items) = concatMap extractFromListItem items
- extractFromBlock (DefinitionList defs) = concatMap extractFromDefinition defs
- extractFromBlock (Preformatted inlines) = concatMap extractFromInline inlines
- extractFromBlock (Paragraph inlines) = concatMap extractFromInline inlines
- extractFromBlock (Div _ elems) = concatMap extractFromElem elems
- extractFromBlock _ = []
-
- extractFromInline :: InlineElement -> [PageName]
- extractFromInline (Italic inlines) = concatMap extractFromInline inlines
- extractFromInline (Bold inlines) = concatMap extractFromInline inlines
- extractFromInline (Span _ inlines) = concatMap extractFromInline inlines
- extractFromInline (PageLink (Just name) _ _) = [name]
- extractFromInline _ = []
-
- extractFromListItem :: ListItem -> [PageName]
- extractFromListItem = concatMap extractFromElem
-
- extractFromDefinition :: Definition -> [PageName]
- extractFromDefinition (Definition term desc)
- = concatMap extractFromInline term
- ++
- concatMap extractFromInline desc
-
-
-wikifyParseError :: Arrow a => a ParseError WikiPage
-wikifyParseError = proc err
- -> returnA -< [Div [("class", "error")]
- [ Block (Preformatted [Text (show err)]) ]]
rmfile ./Rakka/Wiki/Engine.hs
hunk ./Rakka/Wiki/Formatter.hs 1
-module Rakka.Wiki.Formatter
- ( formatWikiBlocks
- )
- where
-
-import Control.Arrow
-import Control.Arrow.ArrowIf
-import Control.Arrow.ArrowList
-import Control.Arrow.ArrowTree
-import Data.Maybe
-import Network.URI hiding (fragment)
-import Rakka.Page
-import Rakka.Wiki
-import Text.XML.HXT.Arrow.XmlArrow
-import Text.XML.HXT.DOM.TypeDefs
-
-
-formatWikiBlocks :: (ArrowXml a, ArrowChoice a) => a (URI, [BlockElement]) XmlTree
-formatWikiBlocks
- = proc (baseURI, blocks)
- -> do block <- arrL id -< blocks
- tree <- formatBlock -< (baseURI, block)
- attachXHtmlNS -< tree
-
-
-formatElement :: (ArrowXml a, ArrowChoice a) => a (URI, Element) XmlTree
-formatElement
- = proc (baseURI, e)
- -> case e of
- Block b -> formatBlock -< (baseURI, b)
- Inline i -> formatInline -< (baseURI, i)
-
-
-formatBlock :: (ArrowXml a, ArrowChoice a) => a (URI, BlockElement) XmlTree
-formatBlock
- = proc (baseURI, block)
- -> case block of
- Heading level text
- -> formatHeading -< (level, text)
-
- HorizontalLine
- -> eelem "hr" -< ()
-
- list@(List _ _)
- -> formatListElement -< (baseURI, list)
-
- DefinitionList list
- -> formatDefinitionList -< (baseURI, list)
-
- Preformatted inlines
- -> formatPreformatted -< (baseURI, inlines)
-
- Paragraph inlines
- -> formatParagraph -< (baseURI, inlines)
-
- Div attrs contents
- -> formatElem "div" -< (baseURI, attrs, contents)
-
- EmptyBlock
- -> none -< ()
-
- _ -> arr (error . ("formatBlock: unsupported BlockElement: " ++) . show) -< block
- where
- formatElem :: (ArrowXml a, ArrowChoice a) =>
- String
- -> a (URI, [Attribute], [Element]) XmlTree
- formatElem name
- = proc (baseURI, attrs, contents)
- -> ( eelem name
- += ( arrL (fst . snd)
- >>>
- attrFromPair
- )
- += ( (arr fst &&& arrL (snd . snd))
- >>>
- formatElement
- )
- ) -< (baseURI, (attrs, contents))
-
-
-formatHeading :: ArrowXml a => a (Int, String) XmlTree
-formatHeading
- = proc (level, text)
- -> mkelem ("h" ++ show level)
- [ sattr "id" text ]
- [ txt text ] -<< ()
-
-
-formatListElement :: (ArrowXml a, ArrowChoice a) => a (URI, BlockElement) XmlTree
-formatListElement
- = proc (baseURI, list)
- -> let tag = case listType list of
- Bullet -> "ul"
- Numbered -> "ol"
- in
- ( eelem tag
- += ( (constA baseURI &&& constL (listItems list))
- >>>
- formatListItem
- )
- ) -<< ()
- where
- formatListItem :: (ArrowXml a, ArrowChoice a) => a (URI, ListItem) XmlTree
- formatListItem
- = proc (baseURI, item)
- -> eelem "li"
- += ( (arr fst &&& arrL snd)
- >>>
- formatElement
- ) -< (baseURI, item)
-
-
-formatDefinitionList :: (ArrowXml a, ArrowChoice a) => a (URI, [Definition]) XmlTree
-formatDefinitionList
- = proc (baseURI, list)
- -> ( eelem "dl"
- += ( (arr fst &&& arrL snd)
- >>>
- formatDefinition
- )
- ) -< (baseURI, list)
- where
- formatDefinition :: (ArrowXml a, ArrowChoice a) => a (URI, Definition) XmlTree
- formatDefinition
- = proc (baseURI, def)
- -> ( eelem "dt"
- += ( (arr fst &&& arrL (defTerm . snd))
- >>>
- formatInline
- )
- <+>
- eelem "dd"
- += ( (arr fst &&& arrL (defDesc . snd))
- >>>
- formatInline
- )
- ) -< (baseURI, def)
-
-
-formatPreformatted :: (ArrowXml a, ArrowChoice a) => a (URI, [InlineElement]) XmlTree
-formatPreformatted
- = eelem "pre"
- += ( (arr fst &&& arrL snd)
- >>>
- formatInline
- )
-
-
-formatParagraph :: (ArrowXml a, ArrowChoice a) => a (URI, [InlineElement]) XmlTree
-formatParagraph
- = eelem "p"
- += ( (arr fst &&& arrL snd)
- >>>
- formatInline
- )
-
-
-formatInline :: (ArrowXml a, ArrowChoice a) => a (URI, InlineElement) XmlTree
-formatInline
- = proc (baseURI, i)
- -> case i of
- Text text
- -> mkText -< text
-
- Italic contents
- -> formatElem "i" -< (baseURI, [], contents)
-
- Bold contents
- -> formatElem "b" -< (baseURI, [], contents)
-
- link@(ObjectLink _ _)
- -> formatObjectLink -< (baseURI, link)
-
- link@(PageLink _ _ _)
- -> formatPageLink -< (baseURI, link)
-
- link@(ExternalLink _ _)
- -> formatExternalLink -< link
-
- LineBreak attrs
- -> formatElem "br" -< (baseURI, attrs, [])
-
- Span attrs contents
- -> formatElem "span" -< (baseURI, attrs, contents)
-
- img@(Image _ _)
- -> formatImage -< (baseURI, img)
-
- Anchor attrs contents
- -> formatElem "a" -< (baseURI, attrs, contents)
-
- Input attrs
- -> formatElem "input" -< (baseURI, attrs, [])
-
- EmptyInline
- -> none -< ()
-
- _ -> arr (error . ("formatInline: unsupported InlineElement: " ++) . show) -< i
- where
- formatElem :: (ArrowXml a, ArrowChoice a) =>
- String
- -> a (URI, [Attribute], [InlineElement]) XmlTree
- formatElem name
- = proc (baseURI, attrs, contents)
- -> ( eelem name
- += ( arrL (fst . snd)
- >>>
- attrFromPair
- )
- += ( (arr fst &&& arrL (snd . snd))
- >>>
- formatInline
- )
- ) -< (baseURI, (attrs, contents))
-
-
-attrFromPair :: (ArrowXml a) => a (String, String) XmlTree
-attrFromPair = proc (name, value)
- -> attr name (txt value) -<< ()
-
-
-formatObjectLink :: (ArrowXml a) => a (URI, InlineElement) XmlTree
-formatObjectLink
- = proc (baseURI, ObjectLink page text)
- -> let uri = mkObjectURI baseURI page
- href = uriToString id uri ""
- label = fromMaybe ("{" ++ page ++ "}") text
- in
- mkAnchor -< (href, label)
-
-
-formatPageLink :: (ArrowXml a) => a (URI, InlineElement) XmlTree
-formatPageLink
- = proc (baseURI, PageLink page fragment text)
- -> let uri = case (page, fragment) of
- (Just x, Just y) -> mkPageFragmentURI baseURI x y
- (Just x, Nothing) -> mkPageURI baseURI x
- (Nothing, Just y) -> mkFragmentURI y
- _ -> undefined
- href = uriToString id uri ""
- dLabel = fromMaybe "" page ++ fromMaybe "" (fmap ('#':) fragment)
- label = fromMaybe dLabel text
- in
- mkAnchor -< (href, label)
-
-
-formatImage :: (ArrowXml a) => a (URI, InlineElement) XmlTree
-formatImage = proc (baseURI, Image src alt)
- -> let uri = case src of
- Left u -> u
- Right name -> mkObjectURI baseURI name
- href = uriToString id uri ""
- in
- ( eelem "img"
- += sattr "src" href
- += ( case alt of
- Just x -> sattr "alt" x
- Nothing -> none
- )
- ) -<< ()
-
-
-formatExternalLink :: (ArrowXml a) => a InlineElement XmlTree
-formatExternalLink
- = proc (ExternalLink uri text)
- -> let href = uriToString id uri ""
- label = fromMaybe href text
- in
- mkAnchor -< (href, label)
-
-
-mkAnchor :: (ArrowXml a) => a (String, String) XmlTree
-mkAnchor = eelem "a"
- += attr "href" (arr fst >>> mkText)
- += (arr snd >>> mkText)
-
-
-attachXHtmlNS :: (ArrowXml a) => a XmlTree XmlTree
-attachXHtmlNS = processTopDown (changeQName attach `when` isElem)
- where
- attach :: QName -> QName
- attach = setNamePrefix' (newXName "xhtml") .
- setNamespaceUri' (newXName "http://www.w3.org/1999/xhtml")
rmfile ./Rakka/Wiki/Formatter.hs
hunk ./Rakka/Wiki/Interpreter/Base.hs 1
-module Rakka.Wiki.Interpreter.Base
- ( interpreters
- )
- where
-
-import Data.Map (Map)
-import qualified Data.Map as M
-import Data.Maybe
-import Rakka.Page
-import Rakka.SystemConfig
-import Rakka.Wiki
-import Rakka.Wiki.Interpreter
-import Text.XML.HXT.Arrow
-import Text.XML.HXT.XPath
-
-
-interpreters :: [Interpreter]
-interpreters = [ lineBreakInterp
- , spanInterp
- , divInterp
- , pageNameInterp
- , otherLangsInterp
- , newPageInterp
- , editPageInterp
- , loginInterp
- , searchFieldInterp
- , configurationInterp
- ]
-
-
-lineBreakInterp :: Interpreter
-lineBreakInterp = InlineCommandInterpreter {
- iciName = "br"
- , iciInterpret
- = \ _ (InlineCommand _ attrs _) -> return $ LineBreak attrs
- }
-
-
-spanInterp :: Interpreter
-spanInterp = InlineCommandInterpreter {
- iciName = "span"
- , iciInterpret
- = \ _ (InlineCommand _ attrs contents) -> return $ Span attrs contents
- }
-
-
-divInterp :: Interpreter
-divInterp = BlockCommandInterpreter {
- bciName = "div"
- , bciInterpret
- = \ _ (BlockCommand _ attrs contents)
- -> return $ Div attrs (map Block contents)
- }
-
-
-pageNameInterp :: Interpreter
-pageNameInterp = InlineCommandInterpreter {
- iciName = "pageName"
- , iciInterpret
- = \ ctx _ -> return $ Text (fromMaybe "" $ ctxPageName ctx)
- }
-
-
-otherLangsInterp :: Interpreter
-otherLangsInterp
- = BlockCommandInterpreter {
- bciName = "inOtherLanguages"
- , bciInterpret
- = \ ctx _ ->
- let linkTable = case ctxMainPage ctx of
- Just page -> runLA ( getXPathTreesInDoc "/page/otherLang/link"
- >>>
- ( getAttrValue0 "lang"
- &&&
- getAttrValue0 "page"
- )
- ) page
- Nothing -> []
- in
- case linkTable of
- [] -> return EmptyBlock
- _ -> do Languages langTable <- getSysConf (ctxSysConf ctx)
- let merged = mergeTables langTable linkTable
- return $ mkLangList merged
- }
- where
- mergeTables :: Map LanguageTag LanguageName
- -> [(LanguageTag, PageName)]
- -> [(LanguageName, PageName)]
- mergeTables _ [] = []
- mergeTables m (x:xs) = let (langTag, name) = x
- langName = fromMaybe langTag (M.lookup langTag m)
- in
- (langName, name) : mergeTables m xs
-
- mkLangList :: [(LanguageName, PageName)] -> BlockElement
- mkLangList = List Bullet . map mkLangLink
-
- mkLangLink :: (LanguageName, PageName) -> ListItem
- mkLangLink (langName, name)
- = [Inline (PageLink (Just name) Nothing (Just langName))]
-
-
---
-newPageInterp :: Interpreter
-newPageInterp
- = InlineCommandInterpreter {
- iciName = "newPage"
- , iciInterpret
- = \ _ (InlineCommand _ args _) ->
- let label = fromMaybe "Create new page" (lookup "label" args)
- attrs = [ ("type" , "button")
- , ("value" , label)
- , ("onclick", "Rakka.newPage()")
- , ("class" , "newButton controls")
- ]
- in
- return (Input attrs)
- }
-
-
---
-editPageInterp :: Interpreter
-editPageInterp
- = InlineCommandInterpreter {
- iciName = "editPage"
- , iciInterpret
- = \ ctx (InlineCommand _ args _) ->
- let name = fromMaybe (fromMaybe "" $ ctxPageName ctx) (lookup "page" args)
- label = fromMaybe "Edit this page" (lookup "label" args)
- attrs = [ ("type" , "button")
- , ("value" , label)
- , ("onclick", "Rakka.editPage(\"" ++ name ++ "\")")
- , ("class" , "editButton controls")
- ]
- in
- return (Input attrs)
- }
-
-
---
-loginInterp :: Interpreter
-loginInterp
- = InlineCommandInterpreter {
- iciName = "login"
- , iciInterpret
- = \ _ _ ->
- let attrs = [ ("type" , "button")
- , ("value", "Login")
- , ("class", "loginButton controls")
- ]
- in
- return (Input attrs)
- }
-
-
---
-searchFieldInterp :: Interpreter
-searchFieldInterp
- = InlineCommandInterpreter {
- iciName = "searchField"
- , iciInterpret
- = \ _ _ ->
- let attrs = [ ("type" , "text")
- , ("class", "searchField")
- ]
- in
- return (Input attrs)
- }
-
---
-configurationInterp :: Interpreter
-configurationInterp
- = InlineCommandInterpreter {
- iciName = "configuration"
- , iciInterpret
- = \ _ _ ->
- let attrs = [ ("type" , "button")
- , ("value", "Configuration")
- , ("class", "configButton controls")
- ]
- in
- return (Input attrs)
- }
rmfile ./Rakka/Wiki/Interpreter/Base.hs
hunk ./Rakka/Wiki/Interpreter/Image.hs 1
-module Rakka.Wiki.Interpreter.Image
- ( interpreters
- )
- where
-
-import Network.URI
-import Rakka.Page
-import Rakka.SystemConfig
-import Rakka.Wiki.Interpreter
-import Rakka.Wiki
-
-
-interpreters :: [Interpreter]
-interpreters = [ imageInterp
- , imgFrameInterp
- ]
-
-
---
-- 空文字列の場合はリンク無し
-
---
---
---
-imageInterp :: Interpreter
-imageInterp
- = InlineCommandInterpreter {
- iciName = "img"
- , iciInterpret
- = \ ctx (InlineCommand _ attrs _) ->
- do BaseURI baseURI <- getSysConf (ctxSysConf ctx)
-
- let name = case lookup "src" attrs of
- Just x -> x
- Nothing -> error "\"src\" attribute is missing"
- link = case lookup "link" attrs of
- Just "" -> Nothing
- Just x -> if isURI x then
- Just x
- else
- Just (uriToString id (mkPageURI baseURI x) "")
- Nothing -> Just (uriToString id (mkPageURI baseURI name) "")
- alt = lookup "alt" attrs
- classAttr = case lookup "float" attrs of
- Nothing -> "inlineImage"
- Just "left" -> "inlineImage leftFloat"
- Just "right" -> "inlineImage rightFloat"
- Just others -> error ("unknown \"float\" attribute: " ++ others)
- result = case link of
- Nothing -> Span [("class", classAttr)] [Image (Right name) alt]
- Just x -> Anchor [ ("class", classAttr)
- , ("href" , x ) ] [Image (Right name) alt]
- return result
- }
-
-
---
-imgFrameInterp :: Interpreter
-imgFrameInterp
- = BlockCommandInterpreter {
- bciName = "imgframe"
- , bciInterpret
- = \ ctx (BlockCommand _ attrs inside) ->
- do BaseURI baseURI <- getSysConf (ctxSysConf ctx)
-
- let name = case lookup "src" attrs of
- Just x -> x
- Nothing -> error "\"src\" attribute is missing"
- link = case lookup "link" attrs of
- Just "" -> Nothing
- Just x -> if isURI x then
- Just x
- else
- Just (uriToString id (mkPageURI baseURI x) "")
- Nothing -> Just (uriToString id (mkPageURI baseURI name) "")
- classAttr = case lookup "float" attrs of
- Nothing -> ("class", "imageFrame")
- Just "left" -> ("class", "imageFrame leftFloat")
- Just "right" -> ("class", "imageFrame rightFloat")
- Just others -> error ("unknown \"float\" attribute: " ++ others)
- image = case link of
- Nothing -> Image (Right name) Nothing
- Just x -> Anchor [("href" , x)] [Image (Right name) Nothing]
-
- return (Div [classAttr]
- [ Block (Div [("class", "imageData")]
- [ Inline image ])
- , Block (Div [("class", "imageCaption")]
- [ Block x | x <- inside ])
- ]
- )
- }
rmfile ./Rakka/Wiki/Interpreter/Image.hs
hunk ./Rakka/Wiki/Interpreter/Outline.hs 1
-module Rakka.Wiki.Interpreter.Outline
- ( interpreters
- )
- where
-
-import Data.Maybe
-import Rakka.Wiki
-import Rakka.Wiki.Interpreter
-
-
-interpreters :: [Interpreter]
-interpreters = [ outlineInterp ]
-
-
-outlineInterp :: Interpreter
-outlineInterp = BlockCommandInterpreter {
- bciName = "outline"
- , bciInterpret
- = \ ctx _ ->
- case ctxMainWiki ctx of
- Just tree -> return $ Div [("class", "outline")] [Block $ mkOutline tree]
- Nothing -> return EmptyBlock
- }
-
-
-mkOutline :: WikiPage -> BlockElement
-mkOutline tree = fst (mkOutline' emptyOutline 1 headings)
- where
- headings :: [BlockElement]
- headings = concatMap collectInBlock tree
-
- collectInBlock :: BlockElement -> [BlockElement]
- collectInBlock hd@(Heading _ _)
- = [hd]
- collectInBlock (Div _ xs)
- = concatMap collectInBlock $ catMaybes (map castToBlock xs)
- collectInBlock (BlockCmd (BlockCommand _ _ xs))
- = concatMap collectInBlock xs
- collectInBlock _
- = []
-
- castToBlock :: Element -> Maybe BlockElement
- castToBlock (Block e) = Just e
- castToBlock _ = Nothing
-
-
-emptyOutline :: BlockElement
-emptyOutline = List Bullet []
-
-
-mkOutline' :: BlockElement -> Int -> [BlockElement] -> (BlockElement, [BlockElement])
-mkOutline' soFar _ [] = (soFar, [])
-mkOutline' soFar level (x:xs)
- = case x of
- Heading n text
- | n == level
- -- 同じレベルなので soFar に單獨の ListItem を追加して
- -- 續行。
- -> let link = PageLink {
- linkPage = Nothing
- , linkFragment = Just text
- , linkText = Just text
- }
- item = [Inline link]
- in
- mkOutline' (soFar { listItems = listItems soFar ++ [item] }) n xs
-
- | n < level
- -- 低いレベルなのでここで終了。
- -> (soFar, x:xs)
-
- | n > level
- -- 高いレベルなので再帰して ListElement を作り、
- -- それを soFar の最後の ListItem に追加する。
- -> let (nested, ys) = mkOutline' emptyOutline (level + 1) (x:xs)
- itemsSoFar = listItems soFar
-
- nonLastItems, lastItem :: [ListItem]
- (nonLastItems, lastItem) = splitAt (length itemsSoFar - 1) itemsSoFar
-
- lastItem' :: ListItem
- lastItem' = case lastItem of
- [] -> [Block nested]
- i:[] -> i ++ [Block nested]
- _ -> undefined
-
- soFar' = soFar { listItems = nonLastItems ++ [lastItem'] }
- in
- mkOutline' soFar' level ys
- _ -> undefined
+
rmfile ./Rakka/Wiki/Interpreter/Outline.hs
hunk ./Rakka/Wiki/Interpreter/PageList.hs 1
-module Rakka.Wiki.Interpreter.PageList
- ( interpreters
- )
- where
-
-import Control.Monad
-import Data.Maybe
-import Data.Time
-import Network.HTTP.Lucu.RFC1123DateTime
-import Network.URI
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Utils
-import Rakka.Wiki
-import Rakka.Wiki.Interpreter
-import System.FilePath
-import Text.HyperEstraier
-
-
-interpreters :: [Interpreter]
-interpreters = [ recentUpdatesURLInterp
- , recentUpdatesInterp
- ]
-
-
-recentUpdatesURLInterp :: Interpreter
-recentUpdatesURLInterp
- = InlineCommandInterpreter {
- iciName = "recentUpdatesURL"
- , iciInterpret
- = \ ctx _ -> do BaseURI baseURI <- getSysConf (ctxSysConf ctx)
- let uri = baseURI {
- uriPath = uriPath baseURI > "search.html"
- , uriQuery = '?' : mkQueryString [ ("q" , "[UVSET]")
- , ("order", "@mdate NUMD")
- ]
- }
- return $ ExternalLink uri (Just "List all pages")
- }
-
-
---
---
--- -
--- ...
---
...
---
--- blah blah...
---
---
--- ...
---
---
-recentUpdatesInterp :: Interpreter
-recentUpdatesInterp
- = BlockCommandInterpreter {
- bciName = "recentUpdates"
- , bciInterpret
- = \ ctx (BlockCommand _ args _)
- -> do let items = fromMaybe 10 $ fmap read $ lookup "items" args
- showSummary = fromMaybe True $ fmap parseYesOrNo $ lookup "showSummary" args
- onlyEntity = fromMaybe True $ fmap parseYesOrNo $ lookup "onlyEntity" args
- onlySummarized = fromMaybe True $ fmap parseYesOrNo $ lookup "onlySummarized" args
- sto = ctxStorage ctx
-
- cond <- newCondition
- when onlyEntity
- $ addAttrCond cond "@type STRNE application/x-rakka-redirection"
- when onlySummarized
- $ addAttrCond cond "rakka:summary STRNE" -- summary が空でない
- setPhrase cond "[UVSET]"
- setOrder cond "@mdate NUMD"
- setMax cond items
-
- result <- searchPages sto cond
- mkPageList showSummary (srPages result)
- }
- where
- mkPageList :: Bool -> [HitPage] -> IO BlockElement
- mkPageList showSummary pages
- = do items <- mapM (mkListItem showSummary) pages
- return (Div [("class", "recentUpdates")]
- [ Block (List Bullet items) ])
-
- mkListItem :: Bool -> HitPage -> IO ListItem
- mkListItem showSummary page
- = do lastMod <- utcToLocalZonedTime (hpLastMod page)
- return ( [ Inline PageLink {
- linkPage = Just (hpPageName page)
- , linkFragment = Nothing
- , linkText = Nothing
- }
- , Block ( Div [("class", "date")]
- [Inline (Text (formatRFC1123DateTime lastMod))]
- )
- ]
- ++
- case (showSummary, hpSummary page) of
- (True, Just s)
- -> [ Block (Paragraph [Text s]) ]
- _ -> []
- )
rmfile ./Rakka/Wiki/Interpreter/PageList.hs
hunk ./Rakka/Wiki/Interpreter/Trackback.hs 1
-module Rakka.Wiki.Interpreter.Trackback
- ( interpreters
- )
- where
-
-import Data.Maybe
-import Data.Time
-import Network.HTTP.Lucu.RFC1123DateTime
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.TrackBack
-import Rakka.Wiki
-import Rakka.Wiki.Interpreter
-
-
-interpreters :: [Interpreter]
-interpreters = [ trackbackURLInterp
- , trackbacksInterp
- ]
-
-
-trackbackURLInterp :: Interpreter
-trackbackURLInterp
- = InlineCommandInterpreter {
- iciName = "trackbackURL"
- , iciInterpret
- = \ ctx _ -> case ctxPageName ctx of
- Nothing
- -> return (Text "No trackbacks for this page.")
- Just name
- -> do BaseURI baseURI <- getSysConf (ctxSysConf ctx)
- let uri = mkAuxiliaryURI baseURI ["trackback"] name
- return $ ExternalLink uri (Just "Trackback URL")
- }
-
-
-trackbacksInterp :: Interpreter
-trackbacksInterp
- = BlockCommandInterpreter {
- bciName = "trackbacks"
- , bciInterpret
- = \ ctx _ ->
- do trackbacks <- case ctxPageName ctx of
- Nothing
- -> return []
- Just name
- -> liftM (fromMaybe [])
- (getAttachment (ctxStorage ctx) name "trackbacks" Nothing)
- items <- mapM mkListItem trackbacks
-
- let divElem = Div [("class", "trackbacks")] [list]
- list = Block (List Bullet items)
-
- return divElem
- }
- where
- mkListItem :: TrackBack -> IO ListItem
- mkListItem tb
- = do zonedTime <- utcToLocalZonedTime (tbTime tb)
-
- let anchor = Just (Inline (ExternalLink (tbURL tb) label))
- label = case (tbTitle tb, tbBlogName tb) of
- (Nothing , Nothing ) -> Nothing
- (Just title, Nothing ) -> Just title
- (Nothing , Just blogName) -> Just blogName
- (Just title, Just blogName) -> Just (title ++ " (" ++ blogName ++ ")")
- date = Just ( Block ( Div [("class", "date")]
- [Inline (Text (formatRFC1123DateTime zonedTime))]
- )
- )
- excerpt = do e <- tbExcerpt tb
- return $ Block $ Paragraph [Text e]
-
- return $ catMaybes [anchor, date, excerpt]
+
rmfile ./Rakka/Wiki/Interpreter/Trackback.hs
rmdir ./Rakka/Wiki/Interpreter
hunk ./Rakka/Wiki/Interpreter.hs 1
-module Rakka.Wiki.Interpreter
- ( Interpreter(..)
- , InterpreterContext(..)
-
- , commandName -- private
- , commandType -- private
- )
- where
-
-import Rakka.Page
-import Rakka.Storage
-import Rakka.SystemConfig
-import Rakka.Wiki
-import Text.XML.HXT.DOM.TypeDefs
-
-
-data Interpreter
- = InlineCommandInterpreter {
- iciName :: !String
- , iciInterpret :: !(InterpreterContext -> InlineCommand -> IO InlineElement)
- }
- | BlockCommandInterpreter {
- bciName :: !String
- , bciInterpret :: !(InterpreterContext -> BlockCommand -> IO BlockElement)
- }
-
-
-data InterpreterContext
- = InterpreterContext {
- ctxPageName :: !(Maybe PageName)
- , ctxMainPage :: !(Maybe XmlTree)
- , ctxMainWiki :: !(Maybe WikiPage)
- , ctxTargetWiki :: !WikiPage
- , ctxStorage :: !Storage
- , ctxSysConf :: !SystemConfig
- }
-
-
-commandName :: Interpreter -> String
-commandName (InlineCommandInterpreter name _) = name
-commandName (BlockCommandInterpreter name _) = name
-
-
-commandType :: Interpreter -> CommandType
-commandType (InlineCommandInterpreter _ _) = InlineCommandType
-commandType (BlockCommandInterpreter _ _) = BlockCommandType
rmfile ./Rakka/Wiki/Interpreter.hs
hunk ./Rakka/Wiki/Parser.hs 1
-module Rakka.Wiki.Parser
- ( CommandTypeOf
- , wikiPage
- )
- where
-
-import Control.Monad
-import Data.Maybe
-import Network.URI hiding (fragment)
-import Rakka.Wiki
-import Text.ParserCombinators.Parsec hiding (label)
-
-
-type CommandTypeOf = String -> Maybe CommandType
-
-
-wikiPage :: CommandTypeOf -> Parser WikiPage
-wikiPage cmdTypeOf
- = do xs <- many (blockElement cmdTypeOf)
- skipMany ( comment
- <|>
- (newline >> return ())
- )
- eof
- return xs
-
-
-blockElement :: CommandTypeOf -> Parser BlockElement
-blockElement cmdTypeOf
- = try $ do skipMany ( comment
- <|>
- (newline >> return ())
- )
- foldr (<|>) pzero [ heading
- , horizontalLine
- , listElement cmdTypeOf
- , definitionList cmdTypeOf
- , verbatim
- , leadingSpaced cmdTypeOf
- , paragraph cmdTypeOf
- , blockCmd cmdTypeOf
- ]
-
-
-heading :: Parser BlockElement
-heading = foldr (<|>) pzero (map heading' [1..5])
- >
- "heading"
- where
- heading' :: Int -> Parser BlockElement
- heading' n = do try $ do _ <- count n (char '=')
- notFollowedBy (char '=')
- ws
- x <- notFollowedBy (char '=') >> anyChar
- xs <- manyTill anyChar (try $ ws >> ( count n (char '=')
- >
- ("trailing " ++ replicate n '=')
- )
- )
- ws
- eol
- return (Heading n (x:xs))
-
-
-horizontalLine :: Parser BlockElement
-horizontalLine = try ( do _ <- count 4 (char '-')
- _ <- many (char '-')
- ws
- eol
- return HorizontalLine
- )
- >
- "horizontal line"
-
-
-listElement :: CommandTypeOf -> Parser BlockElement
-listElement cmdTypeOf = listElement' []
- where
- listElement' :: [Char] -> Parser BlockElement
- listElement' stack
- = do t <- oneOf "*#"
- ws
- xs <- items (stack ++ [t])
- return (List (toType t) xs)
-
- items :: [Char] -> Parser [ListItem]
- items stack = do xs <- many1 $ inlineElement cmdTypeOf
- nested <- option Nothing
- $ try $ do skipMany comment
- _ <- newline
- _ <- string stack
- liftM Just (listElement' stack)
- rest <- items stack
- return $ (map Inline xs ++ map Block (catMaybes [nested])) : rest
- <|>
- (try $ do skipMany comment
- _ <- newline
- _ <- string stack
- ws
- items stack
- )
- <|>
- return []
-
- toType :: Char -> ListType
- toType '*' = Bullet
- toType '#' = Numbered
- toType _ = undefined
-
-
-definitionList :: CommandTypeOf -> Parser BlockElement
-definitionList cmdTypeOf = liftM DefinitionList (many1 definition)
- where
- definition :: Parser Definition
- definition = do _ <- char ';'
- _ <- ws
- tHead <- inlineElement cmdTypeOf
- tRest <- term
- d <- description
- return (Definition (tHead:tRest) d)
- >
- "definition list"
-
- term :: Parser [InlineElement]
- term = (char ':' >> ws >> return [])
- <|>
- (newline >> char ':' >> ws >> return [])
- <|>
- do x <- inlineElement cmdTypeOf
- xs <- term
- return (x:xs)
- >
- "term to be defined"
-
- description :: Parser [InlineElement]
- description = do x <- inlineElement cmdTypeOf
- xs <- description
- return (x:xs)
- <|>
- try ( do _ <- newline
- _ <- char ':'
- _ <- ws
- xs <- description
- return (Text "\n" : xs)
- )
- <|>
- (newline >> return [])
- <|>
- (eof >> return [])
- >
- "description of term"
-
-
-verbatim :: Parser BlockElement
-verbatim = do _ <- try (string "> string "]>")
- return []
- <|>
- do x <- anyChar
- xs <- verbatim'
- return (x:xs)
-
-
-leadingSpaced :: CommandTypeOf -> Parser BlockElement
-leadingSpaced cmdTypeOf = liftM Preformatted (char ' ' >> leadingSpaced')
- >
- "leading space"
- where
- leadingSpaced' :: Parser [InlineElement]
- leadingSpaced' = do x <- inlineElement cmdTypeOf
- xs <- leadingSpaced'
- return (x:xs)
- <|>
- try ( liftM (Text "\n" :) ( newline
- >>
- char ' '
- >>
- leadingSpaced'
- )
- )
- <|>
- return []
-
-
-paragraph :: CommandTypeOf -> Parser BlockElement
-paragraph cmdTypeOf = liftM Paragraph paragraph'
- where
- paragraph' :: Parser [InlineElement]
- paragraph' = do x <- inlineElement cmdTypeOf
- xs <- try ( do _ <- newline
- _ <- eof
- return []
- -- \n で文字列が終はってゐたら、ここ
- -- で終了。
- )
- <|>
- try ( do _ <- newline
- _ <- ((oneOf ('\n':blockSymbols) >> pzero) <|> return ())
- ys <- (paragraph' <|> return [])
- return (Text "\n" : ys)
- -- \n があり、その次に \n または
- -- blockSymbols があれば、fail して
- -- 最初の newline を讀んだ所まで卷き
- -- 戻す。
-
- -- FIXME: 本當にそのやうな動作になつ
- -- てゐるか?偶然動いてゐるだけではな
- -- いか?確かにこの實裝でユニットテス
- -- トは通るのだが、私の理解を越えてし
- -- まったやうだ。
- )
- <|>
- paragraph'
- -- それ以外の場合は次の inlineElement から
- -- を讀んで見る。但し一つも無くても良い。
- <|>
- return [] -- 全部失敗したらここで終了。
- return (x:xs)
-
-
-blockCmd :: CommandTypeOf -> Parser BlockElement
-blockCmd cmdTypeOf
- = (try $ do (tagName, tagAttrs) <- openTag
- case cmdTypeOf tagName of
- Just BlockCommandType
- -> do xs <- contents
- closeTag tagName
- return $ BlockCmd BlockCommand {
- bCmdName = tagName
- , bCmdAttributes = tagAttrs
- , bCmdContents = xs
- }
-
- Just InlineCommandType
- -> pzero
-
- _ -> return $ undefinedCmdErr tagName
- )
- <|>
- (try $ do (tagName, tagAttrs) <- emptyTag
- case cmdTypeOf tagName of
- Just BlockCommandType
- -> return $ BlockCmd BlockCommand {
- bCmdName = tagName
- , bCmdAttributes = tagAttrs
- , bCmdContents = []
- }
-
- Just InlineCommandType
- -> pzero
-
- _ -> return $ undefinedCmdErr tagName
- )
- >
- "block command"
- where
- contents :: Parser [BlockElement]
- contents = do x <- blockElement cmdTypeOf
- xs <- contents
- return (x:xs)
- <|>
- (newline >> contents)
- <|>
- (comment >> contents)
- <|>
- return []
-
- undefinedCmdErr :: String -> BlockElement
- undefinedCmdErr name
- = Div [("class", "error")]
- [ Block (Paragraph [Text ("The command `" ++ name ++ "' is not defined. " ++
- "Make sure you haven't mistyped.")
- ])
- ]
-
-
-inlineElement :: CommandTypeOf -> Parser InlineElement
-inlineElement cmdTypeOf
- = try $ do skipMany comment
- foldr (<|>) pzero [ nowiki
- , apostrophes cmdTypeOf
- , text
- , objLink
- , pageLink
- , extLink
- , inlineCmd cmdTypeOf
- ]
-
-
-nowiki :: Parser InlineElement
-nowiki = liftM Text (try (string "> nowiki')
- where
- nowiki' :: Parser String
- nowiki' = do _ <- try (string "]>")
- return []
- <|>
- do x <- anyChar
- xs <- nowiki'
- return (x:xs)
-
-
-text :: Parser InlineElement
-text = liftM (Text . (':' :)) ( char ':'
- >>
- many (noneOf ('\n':inlineSymbols))
- )
- -- 定義リストとの關係上、コロンは先頭にしか來られない。
- <|>
- liftM Text (many1 (noneOf ('\n':inlineSymbols)))
- >
- "text"
-
-
-apostrophes :: CommandTypeOf -> Parser InlineElement
-apostrophes cmdTypeOf = foldr (<|>) pzero (map try [apos1, apos2, apos3, apos4, apos5])
- where
- apos1 = apos 1 >> return (Text "'")
-
- apos2 = do apos 2
- xs <- many1 $ inlineElement cmdTypeOf
- apos 2
- return (Italic xs)
-
- apos3 = do apos 3
- xs <- many1 $ inlineElement cmdTypeOf
- apos 3
- return (Bold xs)
-
- apos4 = apos 4 >> return (Text "'")
-
- apos5 = do apos 5
- xs <- many1 $ inlineElement cmdTypeOf
- apos 5
- return (Italic [Bold xs])
-
- apos :: Int -> Parser ()
- apos n = count n (char '\'') >> notFollowedBy (char '\'')
-
-
-objLink :: Parser InlineElement
-objLink = do _ <- try (string "[[[")
- page <- many1 (noneOf "|]")
- label <- option Nothing
- (liftM Just (char '|' >> many1 (satisfy (/= ']'))))
- _ <- string "]]]"
- return $ ObjectLink page label
- >
- "object link"
-
-
-pageLink :: Parser InlineElement
-pageLink = do _ <- try (string "[[")
- page <- option Nothing
- (liftM Just (many1 (noneOf "#|]")))
- fragment <- option Nothing
- (liftM Just (char '#' >> many1 (noneOf "|]")))
- label <- option Nothing
- (liftM Just (char '|' >> many1 (satisfy (/= ']'))))
-
- case (page, fragment) of
- (Nothing, Nothing) -> pzero
- (_, _) -> return ()
-
- _ <- string "]]"
- return $ PageLink page fragment label
- >
- "page link"
-
-
-extLink :: Parser InlineElement
-extLink = do _ <- char '['
- uriStr <- many1 (noneOf " \t]")
- _ <- skipMany (oneOf " \t")
- label <- option Nothing
- (liftM Just (many1 (noneOf "]")))
-
- case parseURI uriStr of
- Just uri -> char ']' >> return (ExternalLink uri label)
- Nothing -> pzero > "absolute URI"
- >
- "external link"
-
-
-inlineCmd :: CommandTypeOf -> Parser InlineElement
-inlineCmd cmdTypeOf
- = (try $ do (tagName, tagAttrs) <- openTag
- case cmdTypeOf tagName of
- Just InlineCommandType
- -> do xs <- contents
- closeTag tagName
- return $ InlineCmd InlineCommand {
- iCmdName = tagName
- , iCmdAttributes = tagAttrs
- , iCmdContents = xs
- }
- _ -> pzero
- )
- <|>
- (try $ do (tagName, tagAttrs) <- emptyTag
- case cmdTypeOf tagName of
- Just InlineCommandType
- -> return $ InlineCmd InlineCommand {
- iCmdName = tagName
- , iCmdAttributes = tagAttrs
- , iCmdContents = []
- }
- _ -> pzero
- )
- >
- "inline command"
- where
- contents :: Parser [InlineElement]
- contents = do x <- inlineElement cmdTypeOf
- xs <- contents
- return (x:xs)
- <|>
- (comment >> contents)
- <|>
- liftM (Text "\n" :) (newline >> contents)
- <|>
- return []
-
-
-openTag :: Parser (String, [Attribute])
-openTag = try $ do _ <- char '<'
- _ <- many space
- name <- many1 letter
- _ <- many space
- attrs <- many $ do attr <- tagAttr
- _ <- many space
- return attr
- _ <- char '>'
- return (name, attrs)
-
-
-emptyTag :: Parser (String, [Attribute])
-emptyTag = try $ do _ <- char '<'
- _ <- many space
- name <- many1 letter
- _ <- many space
- attrs <- many $ do attr <- tagAttr
- _ <- many space
- return attr
- _ <- char '/'
- _ <- many space
- _ <- char '>'
- return (name, attrs)
-
-
-closeTag :: String -> Parser ()
-closeTag name = try $ do _ <- char '<'
- _ <- many space
- _ <- char '/'
- _ <- many space
- _ <- string name
- _ <- many space
- _ <- char '>'
- return ()
-
-
-tagAttr :: Parser (String, String)
-tagAttr = do name <- many1 letter
- _ <- char '='
- _ <- char '"'
- value <- many (satisfy (/= '"'))
- _ <- char '"'
- return (name, value)
-
-
-comment :: Parser ()
-comment = (try (string "") >> case level of
- 1 -> return ()
- n -> skipTillEnd (n - 1))
- <|>
- (anyChar >> skipTillEnd level)
-
-
-blockSymbols :: [Char]
-blockSymbols = " =-*#;<"
-
-
-inlineSymbols :: [Char]
-inlineSymbols = "<[:'"
-
--- white space
-ws :: Parser ()
-ws = skipMany ( (oneOf " \t" >> return ())
- <|>
- comment
- )
-
--- end of line
-eol :: Parser ()
-eol = (newline >> return ())
- <|>
- eof
rmfile ./Rakka/Wiki/Parser.hs
rmdir ./Rakka/Wiki
hunk ./Rakka/Wiki.hs 1
-module Rakka.Wiki
- ( WikiPage
-
- , Element(..)
- , Attribute
-
- , BlockElement(..)
- , InlineElement(..)
-
- , Definition(..)
-
- , ListType(..)
- , ListItem
-
- , CommandType(..)
- , BlockCommand(..)
- , InlineCommand(..)
- )
- where
-
-import Network.URI
-import Rakka.Page
-
-
-type WikiPage = [BlockElement]
-
-
-data Element
- = Block !BlockElement
- | Inline !InlineElement
- deriving (Eq, Show)
-
-
-type Attribute = (String, String)
-
-
-data BlockElement
- = Heading {
- headingLevel :: !Int
- , headingText :: !String
- }
- | HorizontalLine
- | List {
- listType :: !ListType
- , listItems :: ![ListItem]
- }
- | DefinitionList ![Definition]
- | Preformatted ![InlineElement]
- | Paragraph ![InlineElement]
- | Div ![Attribute] ![Element]
- | EmptyBlock
- | BlockCmd !BlockCommand
- deriving (Eq, Show)
-
-
-data InlineElement
- = Text !String
- | Italic ![InlineElement]
- | Bold ![InlineElement]
- | ObjectLink {
- objLinkPage :: !PageName
- , objLinkText :: !(Maybe String)
- }
- | PageLink {
- linkPage :: !(Maybe PageName)
- , linkFragment :: !(Maybe String)
- , linkText :: !(Maybe String)
- }
- | ExternalLink {
- extLinkURI :: !URI
- , extLinkText :: !(Maybe String)
- }
- | LineBreak ![Attribute]
- | Span ![Attribute] ![InlineElement]
- | Image {
- imgSource :: !(Either URI PageName)
- , imgAlt :: !(Maybe String)
- }
- | Anchor ![Attribute] ![InlineElement]
- | Input ![Attribute]
- | EmptyInline
- | InlineCmd !InlineCommand
- deriving (Eq, Show)
-
-
-data ListType
- = Bullet
- | Numbered
- deriving (Eq, Show)
-
-
-type ListItem = [Element]
-
-
-data Definition
- = Definition {
- defTerm :: ![InlineElement]
- , defDesc :: ![InlineElement]
- }
- deriving (Eq, Show)
-
-
-data CommandType
- = InlineCommandType
- | BlockCommandType
- deriving (Eq, Show)
-
-
-data BlockCommand
- = BlockCommand {
- bCmdName :: !String
- , bCmdAttributes :: ![Attribute]
- , bCmdContents :: ![BlockElement]
- }
- deriving (Eq, Show)
-
-
-data InlineCommand
- = InlineCommand {
- iCmdName :: !String
- , iCmdAttributes :: ![Attribute]
- , iCmdContents :: ![InlineElement]
- }
- deriving (Eq, Show)
rmfile ./Rakka/Wiki.hs
rmdir ./Rakka
hunk ./Rakka.buildinfo.in 1
--- -*- haskell-cabal -*-
-Executable: rakka
-GHC-Options:
- -DLOCALSTATEDIR="@RAKKA_LOCALSTATEDIR@"
rmfile ./Rakka.buildinfo.in
hunk ./Rakka.cabal 1
-Name: Rakka
-Synopsis: RESTful Wiki engine with Subversion backend
-Description:
- Rakka is a RESTful wiki engine with Subversion backend. Its syntax
- is similar to MediaWiki.
-Version: 0.1
-License: PublicDomain
-Author: PHO
-Maintainer: PHO
-Stability: experimental
-Homepage: http://rakka.cielonegro.org/
-Category: Web
-Tested-With: GHC == 6.6.1
-Cabal-Version: >= 1.2
-Build-Type: Custom
-
-Data-Files:
- defaultPages/Feed.xml
- defaultPages/Help/SampleImage/Large.xml
- defaultPages/Help/SampleImage/Small.xml
- defaultPages/Help/Syntax.xml
- defaultPages/MainPage.xml
- defaultPages/PageTitle.xml
- defaultPages/SideBar/Left.xml
- defaultPages/SideBar/Right.xml
- defaultPages/StyleSheet/CieloNegro/Logo.xml
- defaultPages/StyleSheet/CieloNegro/Moon.xml
- defaultPages/StyleSheet/CieloNegro.xml
- defaultPages/StyleSheet/Default.xml
- schemas/rakka-page-1.0.rng
-
-Extra-Source-Files:
- Rakka.buildinfo.in
- configure
- configure.ac
- js/Makefile
- js/base.js
- js/base64.js
- js/editPage.js
- js/hexDump.js
- js/jquery-1.2.2.js
- js/jquery-dom.js
- js/localFile.js
- js/login.js
- js/parseuri.js
- js/screen.js
- js/search.js
- js/uri.js
- tests/RakkaUnitTest.hs
- tests/WikiParserTest.hs
-
-Flag build-test-suite
- Description: Build the test suite.
- Default: False
-
-Executable rakka
- Build-Depends:
- FileManip, HTTP, HUnit, HsHyperEstraier, HsOpenSSL, HsSVN >=
- 0.3.2, Lucu, base, bytestring, containers, dataenc, directory,
- utf8-string, filepath, hslogger, hxt, hxt-xpath, magic, mtl,
- network, parsec, stm, time, unix, zlib
- Main-Is:
- Main.hs
- Other-Modules:
- Rakka.Attachment
- Rakka.Authorization
- Rakka.Environment
- Rakka.Page
- Rakka.Resource
- Rakka.Resource.CheckAuth
- Rakka.Resource.DumpRepos
- Rakka.Resource.Index
- Rakka.Resource.JavaScript
- Rakka.Resource.Object
- Rakka.Resource.PageEntity
- Rakka.Resource.Render
- Rakka.Resource.Search
- Rakka.Resource.SystemConfig
- Rakka.Resource.TrackBack
- Rakka.Resource.Users
- Rakka.Storage
- Rakka.Storage.DefaultPage
- Rakka.Storage.Repos
- Rakka.Storage.Types
- Rakka.Storage.Impl
- Rakka.SystemConfig
- Rakka.TrackBack
- Rakka.Utils
- Rakka.Validation
- Rakka.W3CDateTime
- Rakka.Wiki
- Rakka.Wiki.Interpreter
- Rakka.Wiki.Interpreter.Base
- Rakka.Wiki.Interpreter.Image
- Rakka.Wiki.Interpreter.PageList
- Rakka.Wiki.Interpreter.Trackback
- Rakka.Wiki.Interpreter.Outline
- Rakka.Wiki.Engine
- Rakka.Wiki.Formatter
- Rakka.Wiki.Parser
- Extensions:
- Arrows, ExistentialQuantification, ScopedTypeVariables, DeriveDataTypeable, FlexibleInstances
- GHC-Options:
- -Wall -threaded
-
-Executable RakkaUnitTest
- if flag(build-test-suite)
- Buildable: True
- else
- Buildable: False
- Main-Is:
- RakkaUnitTest.hs
- Hs-Source-Dirs:
- ., tests
- Other-Modules:
- WikiParserTest
- Extensions:
- Arrows
- GHC-Options:
- -Wall -Werror
rmfile ./Rakka.cabal
hunk ./Setup.hs 1
-#!/usr/bin/env runghc
-
-import Distribution.Simple
-import System.Cmd
-import System.Exit
-
-main = defaultMainWithHooks (autoconfUserHooks { runTests = runTestUnit })
- where
- runTestUnit _ _ _ _
- = system "./dist/build/RakkaUnitTest/RakkaUnitTest" >> return ()
rmfile ./Setup.hs
hunk ./configure.ac 1
-AC_INIT([Rakka], [], [pho at cielonegro dot org])
-
-AC_CONFIG_SRCDIR([Rakka.cabal])
-
-
-# $localstatedir has a reference to ${prefix} but the ${prefix} is
-# "NONE" at this time. AC_OUTPUT changes the value of ${prefix} from
-# "NONE" to $ac_default_prefix but it's too late!
-if test "x$prefix" = "xNONE"; then
- prefix=$ac_default_prefix
-fi
-
-RAKKA_LOCALSTATEDIR=`eval echo "$localstatedir"`/rakka
-AC_SUBST([RAKKA_LOCALSTATEDIR])
-
-
-AC_CONFIG_FILES([
- Rakka.buildinfo
-])
-AC_OUTPUT
-
rmfile ./configure.ac
hunk ./defaultPages/Feed.xml 1
-
-
-
-
-]]>
-
-
+
rmfile ./defaultPages/Feed.xml
hunk ./defaultPages/Help/SampleImage/Large.xml 1
-
-
-
-
- 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
- +otaXBkGORXUy42sgLk7wK6kv//Z
-
-
+
rmfile ./defaultPages/Help/SampleImage/Large.xml
hunk ./defaultPages/Help/SampleImage/Small.xml 1
-
-
-
-
- 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
-
-
+
rmfile ./defaultPages/Help/SampleImage/Small.xml
rmdir ./defaultPages/Help/SampleImage
hunk ./defaultPages/Help/Syntax.xml 1
-
-
-
-
-
-== nowiki section ==
-<!nowiki[
-[[Wiki]] markup is ignored here
-but the text is reformatted.
-]>
-
-== verbatim section ==
-<!verbatim[
-[[Wiki]] markup is ignored here
- and reformatting is also disabled.
-]>
-
-
-blah blah blah...
-blah blah blah blah...
--- John Doe
-
--->
-
-== Listing ==
-* foo
-** bar
-*** baz
-
-# foo
-## bar
-### baz
-
-* foo
-*# bar
-*#* baz
-*# bar
-
-== Definition ==
-; AAA : aaa
-; BBB
-: bbb
-
-== Link ==
-* [[Page]]
-* [[page]]
-* [[space in a page name]]
-* [[Page|Link to "Page"]]
-* [[Page#Heading]]
-* [[#Heading]]
-* [[Page#Heading|Link to "Page#Heading"]]
-* [[#example]]
-* [http://www.google.com/]
-* [http://www.google.com/ Google]
-* [[[Page]]]
-* [[[Page|Link to object of "Page"]]]
-
-
-example
-]]>
-
-
rmfile ./defaultPages/Help/Syntax.xml
rmdir ./defaultPages/Help
hunk ./defaultPages/MainPage.xml 1
-
-
-
-
-
-
-
- foo
-
-
-Another paragraph...
-
-別の段落...
次の行...
-red blue red
-
-== Subsection ==
-
-* [[Help/Syntax]]
-* [http://cielonegro.org/]
-* [http://cielonegro.org/ CieloNegro]
-]]>
-
rmfile ./defaultPages/MainPage.xml
hunk ./defaultPages/PageTitle.xml 1
-
-
-
-]]>
-
rmfile ./defaultPages/PageTitle.xml
hunk ./defaultPages/SideBar/Left.xml 1
-
-
-
-
-= Menu =
-* [[MainPage|Main]]
-* [[Help/Syntax|Syntax Help]]
-
-]]>
-
rmfile ./defaultPages/SideBar/Left.xml
hunk ./defaultPages/SideBar/Right.xml 1
-
-
-
-*
-*
-*
-*
-
-= In other languages =
-
-
-= Recent updates =
-
-
-
-]]>
-
rmfile ./defaultPages/SideBar/Right.xml
rmdir ./defaultPages/SideBar
hunk ./defaultPages/StyleSheet/CieloNegro/Logo.xml 1
-
-
-
-
- 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
- TkSuQmCC
-
-
+
rmfile ./defaultPages/StyleSheet/CieloNegro/Logo.xml
hunk ./defaultPages/StyleSheet/CieloNegro/Moon.xml 1
-
-
-
-
- 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
-
-
+
rmfile ./defaultPages/StyleSheet/CieloNegro/Moon.xml
rmdir ./defaultPages/StyleSheet/CieloNegro
hunk ./defaultPages/StyleSheet/CieloNegro.xml 1
-
-
-
-/* global configuration *******************************************************/
-* {
- padding: 0;
- margin: 0;
-}
-
-/* layout *********************************************************************/
-.center {
- position: absolute;
-
- overflow: auto;
-
- top: 20px;
- right: 15em;
- left: 15em;
- bottom: 20px;
-}
-
-.left {
- top: 0em;
- width: 15em;
- left: 0;
- bottom: 0;
-}
-
-.right {
- top: 0em;
- width: 15em;
- right: 0;
- bottom: 0;
-}
-
-.header {
- position: absolute;
- height: 20px;
- left: 15em;
- right: 15em;
- top: 0;
-}
-
-.footer {
- position: absolute;
- height: 20px;
- left: 15em;
- right: 15em;
- bottom: 0;
-}
-
-.sideBar {
- position: absolute;
- overflow: auto;
-}
-
-/* spacing ********************************************************************/
-input[type="button"] {
- padding: 0px;
-}
-
-td, th {
- padding: 3px;
-}
-
-option {
- padding: 3px 3px 1px 3px;
-}
-
-.title {
- padding: 5px 20px;
-}
-
-.title p {
- margin: 0;
-}
-
-.body {
- padding: 25px 30px;
-}
-
-.body p {
- margin: 0 0 0.8em 0;
-}
-
-.sideBar p {
- margin: 0.2em 0;
-}
-
-.body h1, .body h2, .body h3, .body h4, .body h5, .body h6 {
- margin: 5px 0px;
-}
-
-.body * + h2 {
- margin-top: 20px;
-}
-
-.body ul, .body ol {
- list-style-position: inside;
- margin: 0 0 0.8em 0;
-}
-.body ul ul, .body ul ol, .body ol ul, .body ol ol {
- margin: 0;
-}
-
-.body li {
- margin: 3px 5px;
-}
-.body li li {
- margin-left: 20px;
-}
-
-.body dl {
- margin: 1em 2em;
-}
-.body dt {
- font-weight: bold;
-}
-.body dd {
- margin-left: 3em;
- margin-top: 0.1em;
-}
-.body dd + dt {
- margin-top: 0.9em;
-}
-
-.sideBar h1 {
- margin-bottom: 5px;
- padding: 0px 5px;
-}
-
-.sideBar .content {
- padding: 20px;
-}
-
-.sideBar p {
- margin-left: 5px;
-}
-
-.sideBar .outline li {
- margin-left: 1em;
- padding: 0;
-}
-
-.sideBar li {
- padding: 3px;
-}
-
-.sideBar ul, .sideBar ol {
- list-style-type: none;
- margin-top: 0.4em;
- margin-bottom: 0.4em;
-}
-
-.sideBar li + li {
- margin-top: 0.3em;
-}
-
-.sideBar * + h1 {
- margin-top: 1.2em;
-}
-
-.sideBar .date {
- padding: 0.2em 0 0 0;
-}
-
-.sideBar input[type="text"],
-.sideBar input[type="password"] {
- width: 97%;
- padding: 1px;
-}
-
-table.pageEditor {
- width: 100%;
-}
-table.pageEditor.vertical td {
- text-align: center;
-}
-.pageEditor th {
- width: 6em;
-}
-.pageEditor ul {
- list-style-type: none;
- margin: 0;
-}
-.pageEditor li {
- margin: 0;
- padding: 3px;
-}
-.pageEditor input[type="radio"] {
- margin-right: 10px;
-}
-.pageEditor input[type="checkbox"] {
- margin-right: 5px;
-}
-.pageEditor input[type="text"],
-.pageEditor input[type="password"],
-.pageEditor input[type="file"],
-.pageEditor textarea {
- width: 97%;
- padding: 3px;
-}
-.pageEditor input.smallField {
- width: 50%;
- margin-left: 1em;
-}
-.pageEditor textarea {
- height: 5em;
-}
-.pageEditor textarea.summary {
- height: 5em;
-}
-.pageEditor textarea.source {
- height: 30em;
-}
-.pageEditor textarea.hexDump {
- font-size: 70%;
- font-family: monospace;
- white-space: pre;
- height: 10em;
-}
-.pageEditor input[type="button"] {
- margin: 0 2px;
-}
-
-.searchStat {
- margin-bottom: 1.5em;
-}
-
-.searchResult {
- margin-bottom: 1.5em;
-}
-
-.pager {
- width: 20em;
-
- margin-left: auto;
- margin-right: auto;
-
- padding: 10px;
-}
-
-.pager a,
-.pager .currentSection {
- padding: 4px;
-}
-
-/* color and text *************************************************************/
-* {
- font-family: sans-serif;
-}
-
-.header, .footer {
- background-color: #0e192d;
-}
-
-.sideBar {
- background-color: black;
- color: white;
-}
-
-.body {
- line-height: 1.3;
-}
-
-.center {
- background-color: #bbbbbb;
-}
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: normal;
-}
-
-hr {
- border-color: #555555;
- border-width: 1px;
- border-style: dashed;
-}
-
-th, td {
- border-color: #777777;
- border-width: 1px;
- border-style: solid;
-}
-th {
- background-color: #aaaaaa;
- font-weight: bold;
- text-align: center;
-}
-td {
- background-color: #cccccc;
-}
-
-p {
- text-indent: 1em;
-}
-
-.title {
- background-color: #0e192d;
- color: white;
-
- background-image: url("./CieloNegro/Moon");
- background-repeat: no-repeat;
- /* (175px - 20px - 136px) / 2 = 9.5px
- * where
- * 175px: height of .title
- * 20px : height of .head
- * 136px: height of ./CieloNegro/Moon
- */
- background-position: 100% 9.5px;
-
- position: relative;
- height: 165px;
-
- border-width: 0 0 10px 0;
- border-style: double;
- border-color: #bbbbbb;
-}
-
-#logo {
- width: 317px;
- height: 56px;
-
- background-image: url("./CieloNegro/Logo");
-
- margin-left: 0px;
- margin-top: 100px;
-}
-
-.body h1 {
- font-size: 200%;
-}
-.body h2 {
- font-size: 150%;
-}
-.body h3 {
- font-size: 130%;
-}
-.body h4 {
- font-size: 110%;
-}
-.body h5 {
- font-size: 90%;
-}
-.body h1, .body h2, .body h3, .body h4, .body h5 {
- background-color: #aaaaaa;
-
- border-color: #888888;
- border-width: 1px;
- border-style: solid;
-
- padding: 0 10px;
-}
-
-a {
- color: #000088;
- text-decoration: none;
-}
-a:hover {
- text-decoration: underline;
-}
-
-input[type="button"] {
- background-color: #333333;
- color: #aaaaff;
-
- border-color: #555555;
- border-width: 2px;
- border-style: solid;
-
- border-radius: 10px;
- -moz-border-radius: 10px;
-}
-input[type="button"]:active {
- background-color: black;
-}
-input[type="button"][disabled] {
- border-color: #444444;
- color: #888888;
-}
-input[type="button"][disabled]:active {
- background-color: #444444;
-}
-
-.sideBar h1 {
- font-size: 120%;
-}
-.sideBar h1, .sideBar h2, .sideBar h3, .sideBar h4, .sideBar h5 {
- font-weight: normal;
-
- color: #aaaaaa;
- background-color: #222222;
-
- border-color: #111111 #333333 #333333 #111111;
- border-width: 1px;
- border-style: solid;
-}
-
-.sideBar a {
- color: #4e8eff;
-}
-
-.sideBar a:visited {
- color: #3f73d0;
-}
-
-.sideBar .date {
- font-size: 70%;
- white-space: nowrap;
- color: #999999;
-}
-
-.searchResult .date {
- font-size: 70%;
- white-space: nowrap;
- color: #555555;
-}
-
-.sideBar p {
- text-indent: 0;
-}
-
-.sideBar .recentUpdates p,
-.sideBar .trackbacks p {
- font-size: 90%;
-}
-
-.sideBar .outline li {
- list-style-type: disc;
- background-color: inherit;
-}
-.sideBar .outline li li {
- list-style-type: circle;
-}
-.sideBar .outline li li li {
- list-style-type: square;
-}
-.sideBar .outline li li li li {
- list-style-type: disc;
-}
-.sideBar .outline li li li li li {
- list-style-type: circle;
-}
-
-.sideBar li {
- padding: 3px 5px;
- background-color: #0e192d;
-
- border-radius: 10px;
- -moz-border-radius: 10px;
-}
-
-.sideBar input[type="text"],
-.sideBar input[type="password"] {
- background-color: #333333;
-
- border-style: inset;
- border-width: 1px;
- border-color: #333333;
-}
-
-.activeField {
- color: white;
-}
-
-.inactiveField {
- color: #aaaaaa;
-}
-
-.pageEditor input[type="text"],
-.pageEditor input[type="password"],
-.pageEditor input[type="file"],
-.pageEditor textarea {
- border-color: #aaaaaa #eeeeee #eeeeee #aaaaaa;
- border-width: 2px;
- border-style: solid;
-
- background-color: #dddddd;
-}
-
-.searchStat {
- color: #444444;
- font-size: 90%;
-}
-
-.searchResult a {
- font-size: 120%;
-}
-.searchResult {
- border-style: dotted;
- border-width: 1px 0 0 0;
- border-color: #444444;
-}
-
-.highlighted {
- background-color: #ffefd5;
-}
-
-.pager {
- text-align: center;
-
- background-color: #b0b0b0;
-
- border-color: #888888;
- border-width: 1px;
- border-style: dotted;
-}
-.pager .currentSection,
-.pager a {
- border-style: solid;
- border-width: 1px;
-}
-.pager .currentSection {
- background-color: #bbbbbb;
- border-color: #888888 #bbbbbb #bbbbbb #888888;
-}
-.pager a {
- background-color: #aaaaaa;
- border-color: #bbbbbb #999999 #999999 #bbbbbb;
-}
-
-/* float **********************************************************************/
-h1, h2, h3, h4, h5, h6 {
- clear: both;
-}
-
-/* image **********************************************************************/
-img {
- border-width: 0;
-}
-
-.inlineImage {
- margin-top: 5px;
- margin-bottom: 5px;
-}
-
-.leftFloat {
- float: left;
- margin-right: 25px;
-}
-
-.rightFloat {
- float: right;
- margin-left: 25px;
-}
-
-.imageFrame {
- background-color: #999999;
- padding: 5px;
-
- border-color: #888888;
- border-width: 1px;
- border-style: solid;
-
- margin-top: 5px;
- margin-bottom: 10px;
-}
-
-.imageFrame p {
- margin: 0;
-}
-
-.imageData {
- text-align: center;
-}
-
-.imageCaption {
- margin-top: 3px;
-}
-
-.sideBar .imageFrame {
- background-color: #222222;
-}
-
-/* error **********************************************************************/
-.error {
- color: red;
- background-color: white;
-
- font-weight: bold;
-
- border-color: #880000;
- border-width: 3px;
- border-style: double;
-
- padding: 10px;
-}
-
-.error p, .error pre {
- margin: 0;
-}
-
-.error:before {
- content: "Error: "
-}
-
-/* sidebar mask ***************************************************************/
-.sideBarMask {
- position: fixed;
-
- background-color: black;
- color: white;
- opacity: 0.7;
-
- z-index: 1;
-}
-
-.sideBarMask .content {
- padding: 40px 0;
-}
-
-.sideBarMask .content input[type="button"] {
- font-size: 120%;
- font-weight: bold;
-
- background-color: #f5f5f5;
- color: #000055;
-
- border-color: #dddddd;
- border-width: 2px;
- border-style: solid;
-
- border-radius: 10px;
- -moz-border-radius: 10px;
-}
-
-/* waiting message ************************************************************/
-.waitingMessageBoard {
- position: fixed;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
-
- z-index: 1;
-}
-
-.waitingMessageBoard p {
- font-size: 200%;
-
- background-color: white;
- color: black;
- opacity: 0.7;
-
- position: fixed;
- bottom: 1em;
- right: 1em;
-
- text-indent: 0;
- padding: 5px 30px;
-}
-
-/* redirection message ********************************************************/
-.redirection {
- margin: 5px;
- padding: 2px;
-
- font-size: 80%;
-
- background-color: #a6a6a6;
- color: #333333;
-
- border-color: #777777;
- border-width: 1px;
- border-style: dotted
-}
-
-.redirection input[type="button"] {
- color: inherit;
- background-color: #a0a0a0;
-
- border-width: 1px;
-
- border-radius: 5px;
- -moz-border-radius: 5px;
-
- margin-left: 0.8em;
-}
-
-.redirection input[type="button"]:active {
- background-color: #888888;
-}
-
-/* preview ********************************************************************/
-.preview {
- background-color: #b5b5b5;
-
- margin: 0 0 20px 0;
- padding: 10px;
-
- border-style: solid;
- border-width: 1px;
- border-color: #888888;
-}
-
-
rmfile ./defaultPages/StyleSheet/CieloNegro.xml
hunk ./defaultPages/StyleSheet/Default.xml 1
-
-
-
-/* global configuration *******************************************************/
-* {
- padding: 0;
- margin: 0;
-}
-
-/* layout *********************************************************************/
-.center {
- position: absolute;
-
- overflow: auto;
-
- top: 20px;
- right: 15em;
- left: 15em;
- bottom: 20px;
-}
-
-.left {
- top: 0em;
- width: 15em;
- left: 0;
- bottom: 0;
-}
-
-.right {
- top: 0em;
- width: 15em;
- right: 0;
- bottom: 0;
-}
-
-.header {
- position: absolute;
- height: 20px;
- left: 15em;
- right: 15em;
- top: 0;
-}
-
-.footer {
- position: absolute;
- height: 20px;
- left: 15em;
- right: 15em;
- bottom: 0;
-}
-
-.sideBar {
- position: absolute;
- overflow: auto;
-}
-
-/* spacing ********************************************************************/
-input[type="button"] {
- padding: 0px;
-}
-
-td, th {
- padding: 3px;
-}
-
-option {
- padding: 3px 3px 1px 3px;
-}
-
-.title {
- padding: 5px 20px;
-}
-
-.title p {
- margin: 0;
-}
-
-.body {
- padding: 25px 30px;
-}
-
-.body p {
- margin: 0 0 0.8em 0;
-}
-
-.sideBar p {
- margin: 0.2em 0;
-}
-
-.body h1, .body h2, .body h3, .body h4, .body h5, .body h6 {
- margin: 5px 0px;
-}
-
-.body * + h2 {
- margin-top: 20px;
-}
-
-.body ul, .body ol {
- list-style-position: inside;
- margin: 0 0 0.8em 0;
-}
-.body ul ul, .body ul ol, .body ol ul, .body ol ol {
- margin: 0;
-}
-
-.body li {
- margin: 3px 5px;
-}
-.body li li {
- margin-left: 20px;
-}
-
-.body dl {
- margin: 1em 2em;
-}
-.body dt {
- font-weight: bold;
-}
-.body dd {
- margin-left: 3em;
- margin-top: 0.1em;
-}
-.body dd + dt {
- margin-top: 0.9em;
-}
-
-.sideBar h1 {
- margin-bottom: 5px;
- padding: 0px 5px;
-}
-
-.sideBar .content {
- padding: 20px;
-}
-
-.sideBar p {
- margin-left: 5px;
-}
-
-.sideBar .outline li {
- margin-left: 1em;
- padding: 0;
-}
-
-.sideBar li {
- padding: 3px;
-}
-
-.sideBar ul, .sideBar ol {
- list-style-type: none;
- margin-top: 0.4em;
- margin-bottom: 0.4em;
-}
-
-.sideBar li + li {
- margin-top: 0.3em;
-}
-
-.sideBar * + h1 {
- margin-top: 1.2em;
-}
-
-.sideBar .date {
- padding: 0.2em 0 0 0;
-}
-
-.sideBar input[type="text"],
-.sideBar input[type="password"] {
- width: 97%;
- padding: 1px;
-}
-
-table.configPanel {
- width: 100%;
-}
-
-table.pageEditor {
- width: 100%;
-}
-table.pageEditor.vertical td {
- text-align: center;
-}
-.pageEditor th {
- width: 6em;
-}
-.pageEditor ul {
- list-style-type: none;
- margin: 0;
-}
-.pageEditor li {
- margin: 0;
- padding: 3px;
-}
-.pageEditor input[type="radio"] {
- margin-right: 10px;
-}
-.pageEditor input[type="checkbox"] {
- margin-right: 5px;
-}
-.pageEditor input[type="text"],
-.pageEditor input[type="password"],
-.pageEditor input[type="file"],
-.pageEditor textarea {
- width: 97%;
- padding: 3px;
-}
-.pageEditor input.smallField {
- width: 50%;
- margin-left: 1em;
-}
-.pageEditor textarea {
- height: 5em;
-}
-.pageEditor textarea.summary {
- height: 5em;
-}
-.pageEditor textarea.source {
- height: 30em;
-}
-.pageEditor textarea.hexDump {
- font-size: 70%;
- font-family: monospace;
- white-space: pre;
- height: 10em;
-}
-.pageEditor input[type="button"] {
- margin: 0 2px;
-}
-
-.searchStat {
- margin-bottom: 1.5em;
-}
-
-.searchResult {
- margin-bottom: 1.5em;
-}
-
-.pager {
- width: 20em;
-
- margin-left: auto;
- margin-right: auto;
-
- padding: 10px;
-}
-
-.pager a,
-.pager .currentSection {
- padding: 4px;
-}
-
-/* color and text *************************************************************/
-* {
- font-family: sans-serif;
-}
-
-body {
- background-color: white;
- color: black;
-}
-
-.body {
- line-height: 1.3;
-}
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: normal;
-}
-
-hr {
- border-color: #bbbbbb;
- border-width: 1px;
- border-style: dashed;
-}
-
-th, td {
- border-color: #dddddd;
- border-width: 1px;
- border-style: solid;
-}
-th {
- background-color: #eeeeee;
- font-weight: bold;
- text-align: center;
-}
-td {
- background-color: #fafafa;
-}
-
-p {
- text-indent: 1em;
-}
-
-.title {
- background-color: #fafafa;
-
- border-color: #cccccc;
- border-width: 0 0 1px 0;
- border-style: solid;
-
- font-size: 1.2em;
-}
-
-.body h1 {
- font-size: 200%;
-}
-.body h2 {
- font-size: 150%;
-}
-.body h3 {
- font-size: 130%;
-}
-.body h4 {
- font-size: 110%;
-}
-.body h5 {
- font-size: 90%;
-}
-.body h1, .body h2, .body h3, .body h4, .body h5 {
- background-color: #fafafa;
-
- border-color: #dddddd;
- border-width: 1px;
- border-style: solid;
-
- padding: 0 10px;
-}
-
-a {
- color: #008800;
- text-decoration: none;
-}
-a:hover {
- text-decoration: underline;
-}
-
-input[type="button"] {
- background-color: #f5f5f5;
- color: #000055;
-
- border-color: #dddddd;
- border-width: 2px;
- border-style: solid;
-
- border-radius: 10px;
- -moz-border-radius: 10px;
-}
-input[type="button"]:active {
- background-color: #999999;
-}
-input[type="button"][disabled] {
- border-color: #e5e5e5;
- color: #b5b5b5;
-}
-input[type="button"][disabled]:active {
- background-color: #f5f5f5;
-}
-
-.header, .footer, .sideBar {
- background-color: #eeeeee;
-}
-
-.sideBar h1 {
- font-size: 120%;
-}
-.sideBar h1, .sideBar h2, .sideBar h3, .sideBar h4, .sideBar h5 {
- font-weight: normal;
-
- color: #555555;
- background-color: #fafafa;
-
- border-color: #dddddd white white #dddddd;
- border-width: 1px;
- border-style: solid;
-}
-
-.sideBar .date {
- font-size: 70%;
- white-space: nowrap;
- color: #666666;
-}
-
-.searchResult .date {
- font-size: 70%;
- white-space: nowrap;
- color: #666666;
-}
-
-.sideBar p {
- text-indent: 0;
-}
-
-.sideBar .recentUpdates p,
-.sideBar .trackbacks p {
- font-size: 90%;
-}
-
-.sideBar .outline li {
- list-style-type: disc;
- background-color: inherit;
-}
-.sideBar .outline li li {
- list-style-type: circle;
-}
-.sideBar .outline li li li {
- list-style-type: square;
-}
-.sideBar .outline li li li li {
- list-style-type: disc;
-}
-.sideBar .outline li li li li li {
- list-style-type: circle;
-}
-
-.sideBar li {
- padding: 3px 5px;
- background-color: #f5f5f5;
-
- border-radius: 10px;
- -moz-border-radius: 10px;
-}
-
-.sideBar .recentUpdates li, .sideBar .trackbacks li {
- background-color: #e0e0e0;
-}
-
-.sideBar input[type="text"],
-.sideBar input[type="password"] {
- background-color: #dddddd;
-
- border-style: inset;
- border-width: 1px;
- border-color: #dddddd;
-}
-
-.activeField {
- color: black;
-}
-
-.inactiveField {
- color: #888888;
-}
-
-.pageEditor input[type="text"],
-.pageEditor input[type="password"],
-.pageEditor input[type="file"],
-.pageEditor textarea {
- border-color: #dddddd #fafafa #fafafa #dddddd;
- border-width: 2px;
- border-style: solid;
-
- background-color: white;
-}
-
-.searchStat {
- color: #888888;
- font-size: 90%;
-}
-
-.searchResult a {
- font-size: 120%;
-}
-.searchResult {
- border-style: dotted;
- border-width: 1px 0 0 0;
- border-color: #aaaaaa;
-}
-
-.highlighted {
- background-color: #ffefd5;
-}
-
-.pager {
- text-align: center;
-
- background-color: #f5f5f5;
-
- border-color: #cccccc;
- border-width: 1px;
- border-style: dotted;
-}
-.pager .currentSection,
-.pager a {
- border-style: solid;
- border-width: 1px;
-}
-.pager .currentSection {
- background-color: white;
- border-color: #cccccc white white #cccccc;
-}
-.pager a {
- background-color: #e8e8e8;
- border-color: white #cccccc #cccccc white;
-}
-
-/* float **********************************************************************/
-h1, h2, h3, h4, h5, h6 {
- clear: both;
-}
-
-/* image **********************************************************************/
-img {
- border-width: 0;
-}
-
-.inlineImage {
- margin-top: 5px;
- margin-bottom: 5px;
-}
-
-.leftFloat {
- float: left;
- margin-right: 25px;
-}
-
-.rightFloat {
- float: right;
- margin-left: 25px;
-}
-
-.imageFrame {
- background-color: #eeeeee;
- padding: 5px;
-
- border-color: #cccccc;
- border-width: 1px;
- border-style: solid;
-
- margin-top: 5px;
- margin-bottom: 10px;
-}
-
-.imageFrame p {
- margin: 0;
-}
-
-.imageData {
- text-align: center;
-}
-
-.imageCaption {
- margin-top: 3px;
-}
-
-/* error **********************************************************************/
-.error {
- color: red;
- background-color: white;
-
- font-weight: bold;
-
- border-color: #880000;
- border-width: 3px;
- border-style: double;
-
- padding: 10px;
-}
-
-.error p, .error pre {
- margin: 0;
-}
-
-.error:before {
- content: "Error: "
-}
-
-/* sidebar mask ***************************************************************/
-.sideBarMask {
- position: fixed;
-
- background-color: black;
- color: white;
- opacity: 0.7;
-
- z-index: 1;
-}
-
-.sideBarMask .content {
- padding: 40px 0;
-}
-
-.sideBarMask .content input[type="button"] {
- font-size: 120%;
- font-weight: bold;
-}
-
-/* waiting message ************************************************************/
-.waitingMessageBoard {
- position: fixed;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
-
- margin: 0;
- padding: 0;
-
- z-index: 1;
-}
-
-.waitingMessageBoard p {
- font-size: 200%;
-
- background-color: black;
- color: white;
- opacity: 0.7;
-
- position: fixed;
- bottom: 1em;
- right: 1em;
-
- text-indent: 0;
- padding: 5px 30px;
-}
-
-/* redirection message ********************************************************/
-.redirection {
- margin: 5px;
- padding: 2px;
-
- font-size: 80%;
-
- background-color: #fafafa;
- color: #888888;
-
- border-color: #eeeeee;
- border-width: 1px;
- border-style: dotted
-}
-
-.redirection input[type="button"] {
- color: inherit;
- background-color: #fcfcfc;
-
- border-width: 1px;
-
- border-radius: 5px;
- -moz-border-radius: 5px;
-
- margin-left: 0.8em;
-}
-
-.redirection input[type="button"]:active {
- background-color: #eeeeee;
-}
-
-/* preview ********************************************************************/
-.preview {
- background-color: #eeeeee;
-
- margin: 0 0 20px 0;
- padding: 10px;
-
- border-style: solid;
- border-width: 1px;
- border-color: #bbbbbb;
-}
-
-
rmfile ./defaultPages/StyleSheet/Default.xml
rmdir ./defaultPages/StyleSheet
rmdir ./defaultPages
hunk ./js/Makefile 1
-JQUERY_SOURCE = jquery-1.2.6.js
-COMPRESSOR = yuicompressor-2.3.5.jar
-
-SOURCES = \
- $(JQUERY_SOURCE) \
- jquery-dom.js \
- base.js \
- base64.js \
- editPage.js \
- hashedParam.js \
- hexDump.js \
- localFile.js \
- login.js \
- redirection.js \
- parseuri.js \
- screen.js \
- search.js \
- systemConfig.js \
- uri.js \
- $(NULL)
-
-COMPRESS = java -jar $(COMPRESSOR) --type js --charset UTF-8
-
-
-build: ../Rakka/Resource/JavaScript.hs
-
-
-packed.js: $(SOURCES) $(COMPRESSOR)
- cat $(SOURCES) > $@
-# cat $(SOURCES) | $(COMPRESS) -o $@
-
-
-../Rakka/Resource/JavaScript.hs: packed.js
- lucu-implant-file -o $@ -m Rakka.Resource.JavaScript -t text/javascript packed.js
-
-
-clean:
- rm -f ../Rakka/Resource/JavaScript.hs packed.js $(JQUERY_PACKED)
-
-
-$(COMPRESSOR):
- @echo "Error: $(COMPRESSOR) has to be placed on this directory."
- @echo " See http://www.julienlecomte.net/yuicompressor/"
- @exit 1
rmfile ./js/Makefile
hunk ./js/base.js 1
-/* Namespace Rakka */
-var Rakka = {};
-
-/* These are constants that may be overwritten by HTML itself. */
-Rakka.baseURI = null;
-Rakka.isLocked = false;
-Rakka.isGlobalLocked = false;
-Rakka.isSpecialPage = false;
-
-/* Common regular expressions */
-Rakka.rePageName = /^[^ a-z.|#\[\]][^ .|#\[\]]*$/;
rmfile ./js/base.js
hunk ./js/base64.js 1
-(function () {
-
- var encTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- var decTable = new Array(
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
-
- Rakka.encodeBase64 = function (src) {
- var len = src.length;
- var i = 0;
- var ret = "";
-
- while (i < len) {
- var c1 = src.charCodeAt(i++);
-
- if (i == len) {
- ret += encTable.charAt(c1 >> 2);
- ret += encTable.charAt((c1 & 0x03) << 4);
- ret += "==";
- }
- else {
- var c2 = src.charCodeAt(i++);
-
- if (i == len) {
- ret += encTable.charAt(c1 >> 2);
- ret += encTable.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4));
- ret += encTable.charAt((c2 & 0x0F) << 2);
- ret += "=";
- }
- else {
- var c3 = src.charCodeAt(i++);
-
- ret += encTable.charAt(c1 >> 2);
- ret += encTable.charAt(((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4));
- ret += encTable.charAt(((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6));
- ret += encTable.charAt(c3 & 0x3F);
- }
- }
- }
-
- return ret;
- };
-
- Rakka.decodeBase64 = function (src) {
- var len = src.length;
- var i = 0;
- var ret = "";
-
- while (i < len) {
- var c1;
- do {
- c1 = decTable[src.charCodeAt(i++)];
- } while (i < len && c1 == -1);
-
- if (c1 != -1) {
- var c2;
- do {
- c2 = decTable[src.charCodeAt(i++)];
- } while (i < len && c2 == -1);
-
- if (c2 != -1) {
-
- ret += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
-
- var c3;
- do {
- c3 = src.charCodeAt(i++);
- if (c3 == 61) {
- return ret;
- }
- c3 = decTable[c3];
- } while (i < len && c3 == -1);
-
- if (c3 != -1) {
- ret += String.fromCharCode(((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2));
-
- var c4;
- do {
- c4 = src.charCodeAt(i++);
- if (c4 == 61) {
- return ret;
- }
- c4 = decTable[c4];
- } while (i < len && c4 == -1);
-
- if (c4 != -1) {
- ret += String.fromCharCode(((c3 & 0x03) << 6) | c4);
- }
- }
- }
- }
- }
-
- return ret;
- };
-
-})();
+
rmfile ./js/base64.js
hunk ./js/editPage.js 1
-(function () {
-
- var $previewHeader = null;
- var $previewArea = null;
-
- Rakka.editPage = function (pageName) {
- var $area = Rakka.switchScreen();
-
- Rakka.displayWaitingMessage("Loading... please wait.");
-
- // XML 版のページを取得する。
- $.ajax({
- url : Rakka.baseURI + pageName + ".xml",
- success: function (pageXml) {
- Rakka.hideWaitingMessage();
-
- if (pageXml.documentElement.tagName == "page") {
- var $page = $(pageXml).find("page");
- var oldRevision = $page.attr("revision");
- var defaultType
- = $page.attr("isBinary") == "yes" ? "binary"
- : $page.attr("type") == "text/x-rakka" ? "rakka"
- : $page.attr("type") == "text/css" ? "css"
- : $page.attr("type") == "text/javascript" ? "js"
- : $page.attr("redirect") != null ? "redirect"
- : "unknown"
- ;
- var lang = $page.attr("lang");
- var isLocked = $page.attr("isLocked") == "yes";
- var otherLangs = (function () {
- var obj = {};
- $page.find("otherLang > link").each(function () {
- obj[this.getAttribute("lang")] = this.getAttribute("page");
- });
- return obj;
- })();
- var source
- = $page.attr("redirect") != null ? $page.attr("redirect")
- : $page.attr("isBinary") == "yes" ? Rakka.decodeBase64($page.find("binaryData").text())
- : $page.find("textData").text()
- ;
- var summary = $page.find("summary").text();
-
- displayPageEditor(pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary);
- }
- else {
- displayPageEditor(pageName, null, "rakka", null, false, {}, null, "");
- }
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
-
- if (req.status == 404) {
- displayPageEditor(pageName, null, "rakka", null, false, {}, null, "");
- }
- else {
- $area.text("Error: " + req.status + " " + req.statusText);
- }
- }
- });
- };
-
- Rakka.newPage = function () {
- displayPageEditor("", null, "rakka", null, false, {}, null, "");
- };
-
- var displayPageEditor = function (pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary) {
- var $area = Rakka.switchScreen();
-
- $previewHeader = $( $.H1({}, "Preview") );
- $area.append($previewHeader);
- $previewHeader.hide();
-
- $previewArea = $( $.DIV({className: "preview"}) );
- $area.append($previewArea);
- $previewArea.hide();
-
- $area.append($.H1({}, pageName == "" ? "Create page" : "Edit page"));
-
- var isDirty = null;
- var makeDirty = function () {
- isDirty = true;
- };
-
- var fldPageName
- = $.INPUT({type : "text", value: pageName});
-
- $(fldPageName).change(makeDirty);
-
- var chkIsLocked
- = $.INPUT({type : "checkbox",
- checked : (isLocked ? "checked" : "")});
-
- $(chkIsLocked).change(makeDirty);
-
- var trIsLocked
- = $.TR({},
- $.TH({}, "Page lock"),
- $.TD({},
- $.LABEL({},
- chkIsLocked,
- "Disallow anonymous users to edit or delete this page")));
-
- var btnTypeRakka
- = $.INPUT({type : "radio",
- name : "type",
- checked: (defaultType == "rakka" ? "checked" : "")});
-
- $(btnTypeRakka).change(makeDirty);
-
- var btnTypeCSS
- = $.INPUT({type : "radio",
- name : "type",
- checked: (defaultType == "css" ? "checked" : "")});
-
- $(btnTypeCSS).change(makeDirty);
-
- var btnTypeJS
- = $.INPUT({type : "radio",
- name : "type",
- checked: (defaultType == "js" ? "checked" : "")});
- $(btnTypeJS).change(makeDirty);
-
- var btnTypeBinary
- = $.INPUT({type : "radio",
- name : "type",
- checked: (defaultType == "binary" ? "checked" : "")});
-
- $(btnTypeBinary).change(makeDirty);
-
- var btnTypeRedirect
- = $.INPUT({type : "radio",
- name : "type",
- checked: (defaultType == "redirect" ? "checked" : "")});
-
- $(btnTypeRedirect).change(makeDirty);
-
- var selPageLang
- = $.SELECT({},
- $.OPTION({value: ""}, "(unspecified)"),
- (function () {
- var options = [];
-
- $.each(Rakka.getSystemConfig().languages, function (tag, name) {
- options.push(
- $.OPTION({value: tag}, name));
- });
-
- return options;
- })());
-
- $(selPageLang).change(makeDirty);
-
- if (lang == null || lang == "") {
- $(selPageLang).val($("html").attr("xml:lang"));
- }
- else {
- $(selPageLang).val(lang);
- }
-
- var trPageLang
- = $.TR({},
- $.TH({}, "Page language"),
- $.TD({}, selPageLang));
-
- var trOtherLangs = (function () {
- var options = [];
-
- $.each(Rakka.getSystemConfig().languages, function (tag, name) {
- options.push(
- $.OPTION({value: tag}, name));
- });
-
- var selLang = $.SELECT({}, options);
- var fldLink = $.INPUT({type: "text", className: "smallField"});
-
- $(selLang).change(function () {
- var pageName = otherLangs[$(selLang).val()];
- $(fldLink).val(
- pageName == null ? "" : pageName
- );
- }).trigger("change");
-
- var onLinkChanged = function () {
- isDirty = true;
-
- var lang = $(selLang).val();
- var pageName = $(this).val();
-
- if (pageName == "") {
- delete otherLangs[lang];
- }
- else {
- otherLangs[lang] = pageName;
- }
- };
- $(fldLink).change(onLinkChanged).keyup(onLinkChanged);
-
- return $.TR({},
- $.TH({}, "Language links"),
- $.TD({}, selLang, fldLink));
- })();
-
- var fldSummary
- = $.TEXTAREA({className: "summary"}, summary);
-
- $(fldSummary).change(makeDirty);
-
- var trSummary
- = $.TR({},
- $.TH({}, "Summary"),
- $.TD({}, fldSummary));
-
- var fldRakkaSource
- = $.TEXTAREA({className: "source"},
- (defaultType == "rakka" && source != null ? source : ""));
-
- $(fldRakkaSource).change(makeDirty);
-
- var fldCSSSource
- = $.TEXTAREA({className: "source"},
- (defaultType == "css" && source != null ? source : ""));
-
- $(fldCSSSource).change(makeDirty);
-
- var fldJSSource
- = $.TEXTAREA({className: "source"},
- (defaultType == "js" && source != null ? source : ""));
-
- $(fldJSSource).change(makeDirty);
-
- var uploadFileBin
- = (defaultType == "binary" && source != null ? source : "");
- var fldUploadFile
- = $.TEXTAREA({className: "hexDump", disabled: true}, Rakka.hexDump(uploadFileBin, 128));
- var btnSelectFile
- = $.INPUT({type: "button", value: "Select file..."});
-
- $(btnSelectFile).click(function () {
- var path = Rakka.selectFile("Select a binary file to upload", "open");
- if (path != null) {
- uploadFileBin = Rakka.loadLocalBinaryFile(path);
- fldUploadFile.value = Rakka.hexDump(uploadFileBin, 128);
- makeDirty();
- }
- });
-
- var fldRedirect
- = $.INPUT({type: "text", value: (defaultType == "redirect" ? source : "")});
-
- $(fldRedirect).change(makeDirty);
-
- var trContent
- = $.TR({},
- $.TH({}),
- $.TD({})
- );
-
- var btnPreview
- = $.INPUT({type: "button", value: "Preview page"});
-
- $(btnPreview).click(function () {
- if (btnTypeRakka.checked) {
- previewRakkaPage(
- fldPageName.value, fldRakkaSource.value);
- }
- else if (btnTypeBinary.checked) {
- if (uploadFileBin != "") {
- previewBinaryPage(
- fldPageName.value, uploadFileBin);
- }
- }
- });
-
- var btnSubmit
- = $.INPUT({type: "button", value: "Submit page"});
-
- $(btnSubmit).click(function () {
- if (btnTypeRakka.checked) {
- submitTextPage(
- pageName,
- oldRevision,
- fldPageName.value,
- chkIsLocked.checked,
- "text/x-rakka",
- $(selPageLang).val(),
- otherLangs,
- fldSummary.value,
- fldRakkaSource.value);
- }
- else if (btnTypeCSS.checked) {
- submitTextPage(
- pageName,
- oldRevision,
- fldPageName.value,
- chkIsLocked.checked,
- "text/css",
- $(selPageLang).val(),
- otherLangs,
- fldSummary.value,
- fldCSSSource.value);
- }
- else if (btnTypeJS.checked) {
- submitTextPage(
- pageName,
- oldRevision,
- fldPageName.value,
- chkIsLocked.checked,
- "text/javascript",
- $(selPageLang).val(),
- otherLangs,
- fldSummary.value,
- fldJSSource.value);
- }
- else if (btnTypeBinary.checked) {
- if (fldUploadFile.value != "") {
- submitBinaryPage(
- pageName,
- oldRevision,
- fldPageName.value,
- chkIsLocked.checked,
- $(selPageLang).val(),
- otherLangs,
- fldSummary.value,
- uploadFileBin);
- }
- }
- else if (btnTypeRedirect.checked) {
- submitRedirection(
- pageName,
- oldRevision,
- fldPageName.value,
- chkIsLocked.checked,
- fldRedirect.value);
- }
- });
-
- var btnDelete
- = $.INPUT({type: "button", value: "Delete this page"});
-
- $(btnDelete).click(function () {
- if (window.confirm("Do you really want to delete this page?")) {
- deletePage(pageName);
- }
- });
-
- var updateTRContent = function () {
- if (btnTypeRakka.checked) {
- $(trPageLang).show();
- $(trOtherLangs).show();
- $(trSummary).show();
- $(trContent).find("th").text("Wiki source");
- $(trContent).find("td").empty().append(fldRakkaSource);
- $(btnPreview).show();
- }
- else if (btnTypeCSS.checked) {
- $(trPageLang).show();
- $(trOtherLangs).show();
- $(trSummary).show();
- $(trContent).find("th").text("CSS source");
- $(trContent).find("td").empty().append(fldCSSSource);
- $(btnPreview).hide();
- }
- else if (btnTypeJS.checked) {
- $(trPageLang).show();
- $(trOtherLangs).show();
- $(trSummary).show();
- $(trContent).find("th").text("JavaScript source");
- $(trContent).find("td").empty().append(fldJSSource);
- $(btnPreview).hide();
- }
- else if (btnTypeBinary.checked) {
- $(trPageLang).show();
- $(trOtherLangs).show();
- $(trSummary).show();
- $(trContent).find("th").text("File");
- $(trContent).find("td").empty().append(fldUploadFile).append(btnSelectFile);
- $(btnPreview).show();
- }
- else if (btnTypeRedirect.checked) {
- $(trPageLang).hide();
- $(trOtherLangs).hide();
- $(trSummary).hide();
- $(trContent).find("th").text("Destination Page");
- $(trContent).find("td").empty().append(fldRedirect);
- $(btnPreview).hide();
- }
- };
- $(btnTypeRakka ).change(updateTRContent);
- $(btnTypeCSS ).change(updateTRContent);
- $(btnTypeJS ).change(updateTRContent);
- $(btnTypeBinary ).change(updateTRContent);
- $(btnTypeRedirect).change(updateTRContent);
- updateTRContent();
-
- var pageEditor
- = $.TABLE({className: "pageEditor"},
- $.TBODY({},
- $.TR({},
- $.TH({}, "Page name"),
- $.TD({}, fldPageName)
- ),
- trIsLocked,
- $.TR({},
- $.TH({}, "Page type"),
- $.TD({},
- $.UL({},
- $.LI({},
- $.LABEL({},
- btnTypeRakka,
- "Wiki page"
- )
- ),
- $.LI({},
- $.LABEL({},
- btnTypeCSS,
- "Style sheet"
- )
- ),
- $.LI({},
- $.LABEL({},
- btnTypeJS,
- "JavaScript"
- )
- ),
- $.LI({},
- $.LABEL({},
- btnTypeBinary,
- "Binary file"
- )
- ),
- $.LI({},
- $.LABEL({},
- btnTypeRedirect,
- "Redirection"
- )
- )
- )
- )
- ),
- trPageLang,
- trOtherLangs,
- trSummary,
- trContent,
- $.TR({},
- $.TH({}),
- $.TD({}, btnPreview, btnSubmit, btnDelete)
- )
- )
- );
-
- var validate = function () {
- var isValid = (function () {
- if (fldPageName.value.match(Rakka.rePageName) == null) {
- return false;
- }
-
- if (btnTypeRedirect.checked) {
- if (fldRedirect.value.match(Rakka.rePageName) == null) {
- return false;
- }
- }
- else {
- for (var tag in otherLangs) {
- if (otherLangs[tag].match(Rakka.rePageName) == null) {
- return false;
- }
- }
-
- if (btnTypeBinary.checked) {
- if (uploadFileBin == "") {
- return false;
- }
- }
- }
-
- return true;
- })();
-
- $(btnSubmit).attr({disabled: (isValid ? "" : "disabled")});
- };
- $(fldPageName)
- .add(btnTypeRakka)
- .add(btnTypeCSS)
- .add(btnTypeJS)
- .add(btnTypeBinary)
- .add(btnTypeRedirect)
- .add($(trOtherLangs).find("input"))
- .add(fldUploadFile)
- .add(fldRedirect)
- .change(validate)
- .keyup(validate);
- $(btnSelectFile).click(validate);
- validate();
-
- if (oldRevision == null || oldRevision == 0) {
- // 削除不可
- $(btnDelete).hide();
- }
-
- $area.append(pageEditor);
-
- if (!Rakka.isLoggedIn() || Rakka.isGlobalLocked) {
- $(trIsLocked).hide();
- }
- };
-
- var previewRakkaPage = function (pageName, source) {
- Rakka.displayWaitingMessage("Loading... please wait.");
-
- var url = Rakka.baseURI + "render/" + encodeURI(pageName);
- $.ajax({
- type : "POST",
- url : url,
- contentType: "text/x-rakka",
- data : source,
- processData: false,
- success : function (resultDoc) {
- Rakka.hideWaitingMessage();
- showPreview(resultDoc);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
- alert("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
- var previewBinaryPage = function (pageName, data) {
- Rakka.displayWaitingMessage("Loading... please wait.");
-
- /* Firefox でバイナリを送らうとすると 0x00 の位置で切れてしまふ。*/
- var url = Rakka.baseURI + "render/" + encodeURI(pageName);
- $.ajax({
- type : "POST",
- url : url,
- contentType: "application/x-rakka-base64-stream",
- data : Rakka.encodeBase64(data),
- processData: false,
- success : function (resultDoc) {
- Rakka.hideWaitingMessage();
- showPreview(resultDoc);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
- alert("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
- var showPreview = function (doc) {
- $previewArea.empty();
-
- $previewHeader.show();
- $previewArea.show();
-
- var root = doc.documentElement;
- var child = root.firstChild;
- do {
- if (child.nodeType == 1) {
- // 要素だったので複製
- $previewArea.append(child.cloneNode(true));
- }
- } while (child = child.nextSibling);
-
- Rakka.scrollToTopLeft();
- };
-
- var submitTextPage
- = function (pageName, oldRevision, givenPageName, isLocked, mimeType, lang, otherLangs, summary, text) {
- var NS = "http://cielonegro.org/schema/Rakka/Page/1.0";
- var doc = document.implementation.createDocument(NS, "page", null);
- var page = doc.documentElement;
-
- if (oldRevision != null) {
- // ページ書換時
- var updateInfo = doc.createElementNS(NS, "updateInfo");
- updateInfo.setAttribute("oldRevision", oldRevision);
-
- if (pageName != givenPageName) {
- var move = doc.createElementNS(NS, "move");
- move.setAttribute("from", pageName);
- updateInfo.appendChild(move);
- }
-
- page.appendChild(updateInfo);
- }
-
- page.setAttribute("isLocked", isLocked ? "yes" : "no");
- page.setAttribute("type", mimeType);
-
- if (lang != null && lang != "") {
- page.setAttribute("lang", lang);
- }
-
- if (summary != null && summary != "") {
- var s = doc.createElementNS(NS, "summary");
- s.appendChild(
- doc.createTextNode(summary));
- page.appendChild(s);
- }
-
- var oLang = doc.createElementNS(NS, "otherLang");
- for (var tag in otherLangs) {
- var link = doc.createElementNS(NS, "link");
- link.setAttribute("lang", tag);
- link.setAttribute("page", otherLangs[tag]);
- oLang.appendChild(link);
- }
- page.appendChild(oLang);
-
- var textData = doc.createElementNS(NS, "textData");
- textData.appendChild(
- doc.createTextNode(text));
-
- page.appendChild(textData);
-
- Rakka.displayWaitingMessage("Submitting... please wait.");
-
- var url = Rakka.baseURI + encodeURI(givenPageName);
- $.ajax({
- type : "PUT",
- url : url,
- contentType: "text/xml",
- data : doc,
- processData: false,
- beforeSend : function (req) {
- Rakka.setAuthorization(req);
- },
- success : function () {
- window.location.replace(url);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
-
- var $area = Rakka.switchScreen();
- $area.text("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
- var submitBinaryPage = function (pageName, oldRevision, givenPageName, isLocked, lang, otherLangs, summary, data) {
- var NS = "http://cielonegro.org/schema/Rakka/Page/1.0";
- var doc = document.implementation.createDocument(NS, "page", null);
- var page = doc.documentElement;
-
- if (oldRevision != null) {
- // ページ書換時
- var updateInfo = doc.createElementNS(NS, "updateInfo");
- updateInfo.setAttribute("oldRevision", oldRevision);
-
- if (pageName != givenPageName) {
- var move = doc.createElementNS(NS, "move");
- move.setAttribute("from", pageName);
- updateInfo.appendChild(move);
- }
-
- page.appendChild(updateInfo);
- }
-
- page.setAttribute("isLocked", isLocked ? "yes" : "no");
- page.setAttribute("type", "");
-
- if (lang != null && lang != "") {
- page.setAttribute("lang", lang);
- }
-
- if (summary != null) {
- var s = doc.createElementNS(NS, "summary");
- s.appendChild(
- doc.createTextNode(summary));
- page.appendChild(s);
- }
-
- var oLang = doc.createElementNS(NS, "otherLang");
- for (var tag in otherLangs) {
- var link = doc.createElementNS(NS, "link");
- link.setAttribute("lang", tag);
- link.setAttribute("page", otherLangs[tag]);
- oLang.appendChild(link);
- }
- page.appendChild(oLang);
-
- var b64 = Rakka.encodeBase64(data);
- var binaryData = doc.createElementNS(NS, "binaryData");
- binaryData.appendChild(
- doc.createTextNode(b64));
-
- page.appendChild(binaryData);
-
- Rakka.displayWaitingMessage("Submitting... please wait.");
-
- var url = Rakka.baseURI + encodeURI(givenPageName);
- $.ajax({
- type : "PUT",
- url : url,
- contentType: "text/xml",
- data : doc,
- processData: false,
- beforeSend : function (req) {
- Rakka.setAuthorization(req);
- },
- success : function () {
- window.location.replace(url);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
-
- var $area = Rakka.switchScreen();
- $area.text("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
- var submitRedirection = function (pageName, oldRevision, givenPageName, isLocked, destination) {
- var NS = "http://cielonegro.org/schema/Rakka/Page/1.0";
- var doc = document.implementation.createDocument(NS, "page", null);
- var page = doc.documentElement;
-
- if (oldRevision != null) {
- // ページ書換時
- var updateInfo = doc.createElementNS(NS, "updateInfo");
- updateInfo.setAttribute("oldRevision", oldRevision);
-
- if (pageName != givenPageName) {
- var move = doc.createElementNS(NS, "move");
- move.setAttribute("from", pageName);
- updateInfo.appendChild(move);
- }
-
- page.appendChild(updateInfo);
- }
-
- page.setAttribute("isLocked", isLocked ? "yes" : "no");
- page.setAttribute("redirect", destination);
-
- Rakka.displayWaitingMessage("Submitting... please wait.");
-
- var url = Rakka.baseURI + encodeURI(givenPageName);
- $.ajax({
- type : "PUT",
- url : url,
- contentType: "text/xml",
- data : doc,
- processData: false,
- beforeSend : function (req) {
- Rakka.setAuthorization(req);
- },
- success : function () {
- window.location.replace(url);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
-
- var $area = Rakka.switchScreen();
- $area.text("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
- var deletePage = function (pageName) {
- var url = Rakka.baseURI + encodeURI(pageName);
- $.ajax({
- type : "DELETE",
- url : url,
- beforeSend : function (req) {
- Rakka.setAuthorization(req);
- },
- success : function () {
- window.location.replace(url);
- },
- error : function (req) {
- Rakka.hideWaitingMessage();
-
- var $area = Rakka.switchScreen();
- $area.text("Error: " + req.status + " " + req.statusText);
- }
- });
- };
-
-})();
+
rmfile ./js/editPage.js
hunk ./js/hashedParam.js 1
-$(document).ready(function () {
-
- /* Example of hashed params:
- *
- * /Foo/Bar.html#Redirect:Baz
- * /Foo/Bar.html#EditPage
- * /Foo/Bar.html#Redirect:Baz|EditPage
- */
-
- var cached_rawHash;
- var cached_map;
-
- /*
- var re_key = /^[^:|]+$/;
- var re_value = /^[^|]*$/;
- */
-
- var getRawHash = function () {
- /* Don't use window.location.hash as it isn't portable due to
- * an ambiguous specification.
- */
- var r = window.location.href;
- var i = r.indexOf("#");
- return (i >= 0
- ? r.substr(i + 1)
- : "");
- };
-
- /*
- var setRawHash = function (hash) {
- var r = window.location.href;
- var i = r.indexOf("#");
- var b = (i >= 0
- ? r.substr(0, i)
- : r);
- window.location.href = b + "#" + hash;
- };
- */
-
- var getHashedParamMap = function () {
- var raw = getRawHash();
-
- if (cached_rawHash != raw) {
- var src = decodeURIComponent(raw);
-
- // Split the source by '|' letters.
- cached_map = {};
- $.each(src.split("|"), function () {
- // tuple ::= key ':' value
- // | key (value is the same as key)
- var i = this.indexOf(":");
- if (i >= 0) {
- var key = this.substr(0, i);
- var val = this.substr(i + 1);
- cached_map[key] = val;
- }
- else {
- var key = this;
- cached_map[key] = key;
- }
- });
-
- cached_rawHash = raw;
- }
-
- return cached_map;
- };
-
- Rakka.getHashedParam = function (key) {
- return getHashedParamMap()[key];
- };
-
- /*
- var setHashedParamMap = function (map) {
- var tuples = "";
-
- $.each(map, function(key, val) {
- var tuple = (key == val
- ? key
- : key + ":" + val);
-
- tuples = (tuples == ""
- ? tuple
- : tuples + "|" + tuple);
- });
-
- cached_map = map;
- cached_raw = encodeURIComponent(tuples);
-
- setRawHash(cached_raw);
- };
-
- Rakka.setHashedParam = function (key, value) {
- var diff = {};
- diff[key] = value;
- Rakka.setHashedParams(diff);
- };
-
- Rakka.setHashedParams = function (diff) {
- var orig = getHashedParamMap();
- var next = {};
-
- // Copy 'orig' to 'next'.
- $.each(orig, function (key, val) {
- next[key] = val;
- });
-
- // Overwrite the content of 'next' with 'diff'.
- $.each(diff, function (key, val) {
-
- if (!key.match(re_key)) {
- throw new Error("Invalid key: " + key);
- }
- if (!val.match(re_value)) {
- throw new Error("Invalid value: " + val);
- }
-
- if (diff[key] == null) {
- delete next[key];
- }
- else {
- next[key] = val;
- }
- });
-
- setHashedParamMap(next);
- };
- */
-});
+
rmfile ./js/hashedParam.js
hunk ./js/hexDump.js 1
-(function () {
-
- var repeat = function (times, str) {
- var ret = "";
-
- for (var i = 0; i < times; i++) {
- ret += str;
- }
-
- return ret;
- };
-
- var printHex = function (width, num) {
- var ret = Number(num).toString(16);
-
- if (ret.length < width) {
- return repeat(width - ret.length, "0") + ret;
- }
- else {
- return ret;
- }
- };
-
- var isPrintableAscii = function (code) {
- return (code >= 0x20 && code <= 0x7e);
- };
-
- Rakka.hexDump = function (data, limit) {
- var offset = 0;
- var size = Math.min(data.length, limit);
- var ret = "";
-
- for (; offset < size; offset += 16) {
- ret += printHex(8, offset);
- ret += " ";
-
- var begin = offset;
- var end = Math.min(offset + 16, size);
-
- for (var i = begin; i < end; i++) {
- var c = data.charCodeAt(i);
-
- ret += printHex(2, c);
- ret += " ";
-
- if (end - i == 9) {
- ret += " ";
- }
- }
- for (var i = end; i < offset + 16; i++) {
- ret += " ";
- if (end - i == 9) {
- ret += " ";
- }
- }
-
- ret += " |";
-
- for (var i = begin; i < end; i++) {
- var c = data.charCodeAt(i);
-
- if (isPrintableAscii(c)) {
- ret += data.charAt(i);
- }
- else {
- ret += ".";
- }
- }
- ret += "|";
- for (var i = end; i < offset + 16; i++) {
- ret += " ";
- }
-
- ret += "\n";
- }
-
- if (data.length > limit) {
- ret += printHex(8, offset);
- ret += " ...\n";
- }
-
- return ret;
- };
-
- })();
+
rmfile ./js/hexDump.js
hunk ./js/jquery-1.2.6.js 1
-(function(){
-/*
- * jQuery 1.2.6 - New Wave Javascript
- *
- * Copyright (c) 2008 John Resig (jquery.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
- * $Rev: 5685 $
- */
-
-// Map over jQuery in case of overwrite
-var _jQuery = window.jQuery,
-// Map over the $ in case of overwrite
- _$ = window.$;
-
-var jQuery = window.jQuery = window.$ = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context );
-};
-
-// A simple way to check for HTML strings or ID strings
-// (both of which we optimize for)
-var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
-
-// Is it a simple selector
- isSimple = /^.[^:#\[\.]*$/,
-
-// Will speed up references to undefined, and allows munging its name.
- undefined;
-
-jQuery.fn = jQuery.prototype = {
- init: function( selector, context ) {
- // Make sure that a selection was provided
- selector = selector || document;
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this[0] = selector;
- this.length = 1;
- return this;
- }
- // Handle HTML strings
- if ( typeof selector == "string" ) {
- // Are we dealing with HTML string or an ID?
- var match = quickExpr.exec( selector );
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] )
- selector = jQuery.clean( [ match[1] ], context );
-
- // HANDLE: $("#id")
- else {
- var elem = document.getElementById( match[3] );
-
- // Make sure an element was located
- if ( elem ){
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id != match[3] )
- return jQuery().find( selector );
-
- // Otherwise, we inject the element directly into the jQuery object
- return jQuery( elem );
- }
- selector = [];
- }
-
- // HANDLE: $(expr, [context])
- // (which is just equivalent to: $(content).find(expr)
- } else
- return jQuery( context ).find( selector );
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) )
- return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
-
- return this.setArray(jQuery.makeArray(selector));
- },
-
- // The current version of jQuery being used
- jquery: "1.2.6",
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- // The number of elements contained in the matched element set
- length: 0,
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num == undefined ?
-
- // Return a 'clean' array
- jQuery.makeArray( this ) :
-
- // Return just the object
- this[ num ];
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
- // Build a new jQuery matched element set
- var ret = jQuery( elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Force the current matched set of elements to become
- // the specified array of elements (destroying the stack in the process)
- // You should use pushStack() in order to do this, but maintain the stack
- setArray: function( elems ) {
- // Resetting the length to 0, then using the native Array push
- // is a super-fast way to populate an object with array-like properties
- this.length = 0;
- Array.prototype.push.apply( this, elems );
-
- return this;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
- var ret = -1;
-
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem && elem.jquery ? elem[0] : elem
- , this );
- },
-
- attr: function( name, value, type ) {
- var options = name;
-
- // Look for the case where we're accessing a style value
- if ( name.constructor == String )
- if ( value === undefined )
- return this[0] && jQuery[ type || "attr" ]( this[0], name );
-
- else {
- options = {};
- options[ name ] = value;
- }
-
- // Check to see if we're setting style values
- return this.each(function(i){
- // Set all the styles
- for ( name in options )
- jQuery.attr(
- type ?
- this.style :
- this,
- name, jQuery.prop( this, options[ name ], type, i, name )
- );
- });
- },
-
- css: function( key, value ) {
- // ignore negative width and height values
- if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
- value = undefined;
- return this.attr( key, value, "curCSS" );
- },
-
- text: function( text ) {
- if ( typeof text != "object" && text != null )
- return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
-
- var ret = "";
-
- jQuery.each( text || this, function(){
- jQuery.each( this.childNodes, function(){
- if ( this.nodeType != 8 )
- ret += this.nodeType != 1 ?
- this.nodeValue :
- jQuery.fn.text( [ this ] );
- });
- });
-
- return ret;
- },
-
- wrapAll: function( html ) {
- if ( this[0] )
- // The elements to wrap the target around
- jQuery( html, this[0].ownerDocument )
- .clone()
- .insertBefore( this[0] )
- .map(function(){
- var elem = this;
-
- while ( elem.firstChild )
- elem = elem.firstChild;
-
- return elem;
- })
- .append(this);
-
- return this;
- },
-
- wrapInner: function( html ) {
- return this.each(function(){
- jQuery( this ).contents().wrapAll( html );
- });
- },
-
- wrap: function( html ) {
- return this.each(function(){
- jQuery( this ).wrapAll( html );
- });
- },
-
- append: function() {
- return this.domManip(arguments, true, false, function(elem){
- if (this.nodeType == 1)
- this.appendChild( elem );
- });
- },
-
- prepend: function() {
- return this.domManip(arguments, true, true, function(elem){
- if (this.nodeType == 1)
- this.insertBefore( elem, this.firstChild );
- });
- },
-
- before: function() {
- return this.domManip(arguments, false, false, function(elem){
- this.parentNode.insertBefore( elem, this );
- });
- },
-
- after: function() {
- return this.domManip(arguments, false, true, function(elem){
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- },
-
- end: function() {
- return this.prevObject || jQuery( [] );
- },
-
- find: function( selector ) {
- var elems = jQuery.map(this, function(elem){
- return jQuery.find( selector, elem );
- });
-
- return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
- jQuery.unique( elems ) :
- elems );
- },
-
- clone: function( events ) {
- // Do the clone
- var ret = this.map(function(){
- if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
- // IE copies events bound via attachEvent when
- // using cloneNode. Calling detachEvent on the
- // clone will also remove the events from the orignal
- // In order to get around this, we use innerHTML.
- // Unfortunately, this means some modifications to
- // attributes in IE that are actually only stored
- // as properties will not be copied (such as the
- // the name attribute on an input).
- var clone = this.cloneNode(true),
- container = document.createElement("div");
- container.appendChild(clone);
- return jQuery.clean([container.innerHTML])[0];
- } else
- return this.cloneNode(true);
- });
-
- // Need to set the expando to null on the cloned set if it exists
- // removeData doesn't work here, IE removes it from the original as well
- // this is primarily for IE but the data expando shouldn't be copied over in any browser
- var clone = ret.find("*").andSelf().each(function(){
- if ( this[ expando ] != undefined )
- this[ expando ] = null;
- });
-
- // Copy the events from the original to the clone
- if ( events === true )
- this.find("*").andSelf().each(function(i){
- if (this.nodeType == 3)
- return;
- var events = jQuery.data( this, "events" );
-
- for ( var type in events )
- for ( var handler in events[ type ] )
- jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
- });
-
- // Return the cloned set
- return ret;
- },
-
- filter: function( selector ) {
- return this.pushStack(
- jQuery.isFunction( selector ) &&
- jQuery.grep(this, function(elem, i){
- return selector.call( elem, i );
- }) ||
-
- jQuery.multiFilter( selector, this ) );
- },
-
- not: function( selector ) {
- if ( selector.constructor == String )
- // test special case where just one selector is passed in
- if ( isSimple.test( selector ) )
- return this.pushStack( jQuery.multiFilter( selector, this, true ) );
- else
- selector = jQuery.multiFilter( selector, this );
-
- var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
- return this.filter(function() {
- return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
- });
- },
-
- add: function( selector ) {
- return this.pushStack( jQuery.unique( jQuery.merge(
- this.get(),
- typeof selector == 'string' ?
- jQuery( selector ) :
- jQuery.makeArray( selector )
- )));
- },
-
- is: function( selector ) {
- return !!selector && jQuery.multiFilter( selector, this ).length > 0;
- },
-
- hasClass: function( selector ) {
- return this.is( "." + selector );
- },
-
- val: function( value ) {
- if ( value == undefined ) {
-
- if ( this.length ) {
- var elem = this[0];
-
- // We need to handle select boxes special
- if ( jQuery.nodeName( elem, "select" ) ) {
- var index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type == "select-one";
-
- // Nothing was selected
- if ( index < 0 )
- return null;
-
- // Loop through all the selected options
- for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
- var option = options[ i ];
-
- if ( option.selected ) {
- // Get the specifc value for the option
- value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
-
- // We don't need an array for one selects
- if ( one )
- return value;
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
-
- // Everything else, we just grab the value
- } else
- return (this[0].value || "").replace(/\r/g, "");
-
- }
-
- return undefined;
- }
-
- if( value.constructor == Number )
- value += '';
-
- return this.each(function(){
- if ( this.nodeType != 1 )
- return;
-
- if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
- this.checked = (jQuery.inArray(this.value, value) >= 0 ||
- jQuery.inArray(this.name, value) >= 0);
-
- else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(value);
-
- jQuery( "option", this ).each(function(){
- this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
- jQuery.inArray( this.text, values ) >= 0);
- });
-
- if ( !values.length )
- this.selectedIndex = -1;
-
- } else
- this.value = value;
- });
- },
-
- html: function( value ) {
- return value == undefined ?
- (this[0] ?
- this[0].innerHTML :
- null) :
- this.empty().append( value );
- },
-
- replaceWith: function( value ) {
- return this.after( value ).remove();
- },
-
- eq: function( i ) {
- return this.slice( i, i + 1 );
- },
-
- slice: function() {
- return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function(elem, i){
- return callback.call( elem, i, elem );
- }));
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- },
-
- data: function( key, value ){
- var parts = key.split(".");
- parts[1] = parts[1] ? "." + parts[1] : "";
-
- if ( value === undefined ) {
- var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
-
- if ( data === undefined && this.length )
- data = jQuery.data( this[0], key );
-
- return data === undefined && parts[1] ?
- this.data( parts[0] ) :
- data;
- } else
- return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
- jQuery.data( this, key, value );
- });
- },
-
- removeData: function( key ){
- return this.each(function(){
- jQuery.removeData( this, key );
- });
- },
-
- domManip: function( args, table, reverse, callback ) {
- var clone = this.length > 1, elems;
-
- return this.each(function(){
- if ( !elems ) {
- elems = jQuery.clean( args, this.ownerDocument );
-
- if ( reverse )
- elems.reverse();
- }
-
- var obj = this;
-
- if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
- obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
-
- var scripts = jQuery( [] );
-
- jQuery.each(elems, function(){
- var elem = clone ?
- jQuery( this ).clone( true )[0] :
- this;
-
- // execute all scripts after the elements have been injected
- if ( jQuery.nodeName( elem, "script" ) )
- scripts = scripts.add( elem );
- else {
- // Remove any inner scripts for later evaluation
- if ( elem.nodeType == 1 )
- scripts = scripts.add( jQuery( "script", elem ).remove() );
-
- // Inject the elements into the document
- callback.call( obj, elem );
- }
- });
-
- scripts.each( evalScript );
- });
- }
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-function evalScript( i, elem ) {
- if ( elem.src )
- jQuery.ajax({
- url: elem.src,
- async: false,
- dataType: "script"
- });
-
- else
- jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
-
- if ( elem.parentNode )
- elem.parentNode.removeChild( elem );
-}
-
-function now(){
- return +new Date;
-}
-
-jQuery.extend = jQuery.fn.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
-
- // Handle a deep copy situation
- if ( target.constructor == Boolean ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target != "object" && typeof target != "function" )
- target = {};
-
- // extend jQuery itself if only one argument is passed
- if ( length == i ) {
- target = this;
- --i;
- }
-
- for ( ; i < length; i++ )
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null )
- // Extend the base object
- for ( var name in options ) {
- var src = target[ name ], copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy )
- continue;
-
- // Recurse if we're merging object values
- if ( deep && copy && typeof copy == "object" && !copy.nodeType )
- target[ name ] = jQuery.extend( deep,
- // Never move original objects, clone them
- src || ( copy.length != null ? [ ] : { } )
- , copy );
-
- // Don't bring in undefined values
- else if ( copy !== undefined )
- target[ name ] = copy;
-
- }
-
- // Return the modified object
- return target;
-};
-
-var expando = "jQuery" + now(), uuid = 0, windowData = {},
- // exclude the following css properties to add px
- exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
- // cache defaultView
- defaultView = document.defaultView || {};
-
-jQuery.extend({
- noConflict: function( deep ) {
- window.$ = _$;
-
- if ( deep )
- window.jQuery = _jQuery;
-
- return jQuery;
- },
-
- // See test/unit/core.js for details concerning this function.
- isFunction: function( fn ) {
- return !!fn && typeof fn != "string" && !fn.nodeName &&
- fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
- },
-
- // check if an element is in a (or is an) XML document
- isXMLDoc: function( elem ) {
- return elem.documentElement && !elem.body ||
- elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
- },
-
- // Evalulates a script in a global context
- globalEval: function( data ) {
- data = jQuery.trim( data );
-
- if ( data ) {
- // Inspired by code by Andrea Giammarchi
- // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
- var head = document.getElementsByTagName("head")[0] || document.documentElement,
- script = document.createElement("script");
-
- script.type = "text/javascript";
- if ( jQuery.browser.msie )
- script.text = data;
- else
- script.appendChild( document.createTextNode( data ) );
-
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709).
- head.insertBefore( script, head.firstChild );
- head.removeChild( script );
- }
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
- },
-
- cache: {},
-
- data: function( elem, name, data ) {
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ];
-
- // Compute a unique ID for the element
- if ( !id )
- id = elem[ expando ] = ++uuid;
-
- // Only generate the data cache if we're
- // trying to access or manipulate it
- if ( name && !jQuery.cache[ id ] )
- jQuery.cache[ id ] = {};
-
- // Prevent overriding the named cache with undefined values
- if ( data !== undefined )
- jQuery.cache[ id ][ name ] = data;
-
- // Return the named cache data, or the ID for the element
- return name ?
- jQuery.cache[ id ][ name ] :
- id;
- },
-
- removeData: function( elem, name ) {
- elem = elem == window ?
- windowData :
- elem;
-
- var id = elem[ expando ];
-
- // If we want to remove a specific section of the element's data
- if ( name ) {
- if ( jQuery.cache[ id ] ) {
- // Remove the section of cache data
- delete jQuery.cache[ id ][ name ];
-
- // If we've removed all the data, remove the element's cache
- name = "";
-
- for ( name in jQuery.cache[ id ] )
- break;
-
- if ( !name )
- jQuery.removeData( elem );
- }
-
- // Otherwise, we want to remove all of the element's data
- } else {
- // Clean up the element expando
- try {
- delete elem[ expando ];
- } catch(e){
- // IE has trouble directly removing the expando
- // but it's ok with using removeAttribute
- if ( elem.removeAttribute )
- elem.removeAttribute( expando );
- }
-
- // Completely remove the data cache
- delete jQuery.cache[ id ];
- }
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- var name, i = 0, length = object.length;
-
- if ( args ) {
- if ( length == undefined ) {
- for ( name in object )
- if ( callback.apply( object[ name ], args ) === false )
- break;
- } else
- for ( ; i < length; )
- if ( callback.apply( object[ i++ ], args ) === false )
- break;
-
- // A special, fast, case for the most common use of each
- } else {
- if ( length == undefined ) {
- for ( name in object )
- if ( callback.call( object[ name ], name, object[ name ] ) === false )
- break;
- } else
- for ( var value = object[0];
- i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
- }
-
- return object;
- },
-
- prop: function( elem, value, type, i, name ) {
- // Handle executable functions
- if ( jQuery.isFunction( value ) )
- value = value.call( elem, i );
-
- // Handle passing in a number to a CSS property
- return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
- value + "px" :
- value;
- },
-
- className: {
- // internal only, use addClass("class")
- add: function( elem, classNames ) {
- jQuery.each((classNames || "").split(/\s+/), function(i, className){
- if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
- elem.className += (elem.className ? " " : "") + className;
- });
- },
-
- // internal only, use removeClass("class")
- remove: function( elem, classNames ) {
- if (elem.nodeType == 1)
- elem.className = classNames != undefined ?
- jQuery.grep(elem.className.split(/\s+/), function(className){
- return !jQuery.className.has( classNames, className );
- }).join(" ") :
- "";
- },
-
- // internal only, use hasClass("class")
- has: function( elem, className ) {
- return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {};
- // Remember the old values, and insert the new ones
- for ( var name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- callback.call( elem );
-
- // Revert the old values
- for ( var name in options )
- elem.style[ name ] = old[ name ];
- },
-
- css: function( elem, name, force ) {
- if ( name == "width" || name == "height" ) {
- var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
-
- function getWH() {
- val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
- var padding = 0, border = 0;
- jQuery.each( which, function() {
- padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
- border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
- });
- val -= Math.round(padding + border);
- }
-
- if ( jQuery(elem).is(":visible") )
- getWH();
- else
- jQuery.swap( elem, props, getWH );
-
- return Math.max(0, val);
- }
-
- return jQuery.curCSS( elem, name, force );
- },
-
- curCSS: function( elem, name, force ) {
- var ret, style = elem.style;
-
- // A helper method for determining if an element's values are broken
- function color( elem ) {
- if ( !jQuery.browser.safari )
- return false;
-
- // defaultView is cached
- var ret = defaultView.getComputedStyle( elem, null );
- return !ret || ret.getPropertyValue("color") == "";
- }
-
- // We need to handle opacity special in IE
- if ( name == "opacity" && jQuery.browser.msie ) {
- ret = jQuery.attr( style, "opacity" );
-
- return ret == "" ?
- "1" :
- ret;
- }
- // Opera sometimes will give the wrong display answer, this fixes it, see #2037
- if ( jQuery.browser.opera && name == "display" ) {
- var save = style.outline;
- style.outline = "0 solid black";
- style.outline = save;
- }
-
- // Make sure we're using the right name for getting the float value
- if ( name.match( /float/i ) )
- name = styleFloat;
-
- if ( !force && style && style[ name ] )
- ret = style[ name ];
-
- else if ( defaultView.getComputedStyle ) {
-
- // Only "float" is needed here
- if ( name.match( /float/i ) )
- name = "float";
-
- name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
-
- var computedStyle = defaultView.getComputedStyle( elem, null );
-
- if ( computedStyle && !color( elem ) )
- ret = computedStyle.getPropertyValue( name );
-
- // If the element isn't reporting its values properly in Safari
- // then some display: none elements are involved
- else {
- var swap = [], stack = [], a = elem, i = 0;
-
- // Locate all of the parent display: none elements
- for ( ; a && color(a); a = a.parentNode )
- stack.unshift(a);
-
- // Go through and make them visible, but in reverse
- // (It would be better if we knew the exact display type that they had)
- for ( ; i < stack.length; i++ )
- if ( color( stack[ i ] ) ) {
- swap[ i ] = stack[ i ].style.display;
- stack[ i ].style.display = "block";
- }
-
- // Since we flip the display style, we have to handle that
- // one special, otherwise get the value
- ret = name == "display" && swap[ stack.length - 1 ] != null ?
- "none" :
- ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
-
- // Finally, revert the display styles back
- for ( i = 0; i < swap.length; i++ )
- if ( swap[ i ] != null )
- stack[ i ].style.display = swap[ i ];
- }
-
- // We should always get a number back from opacity
- if ( name == "opacity" && ret == "" )
- ret = "1";
-
- } else if ( elem.currentStyle ) {
- var camelCase = name.replace(/\-(\w)/g, function(all, letter){
- return letter.toUpperCase();
- });
-
- ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
- // Remember the original values
- var left = style.left, rsLeft = elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- elem.runtimeStyle.left = elem.currentStyle.left;
- style.left = ret || 0;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- elem.runtimeStyle.left = rsLeft;
- }
- }
-
- return ret;
- },
-
- clean: function( elems, context ) {
- var ret = [];
- context = context || document;
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if (typeof context.createElement == 'undefined')
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
-
- jQuery.each(elems, function(i, elem){
- if ( !elem )
- return;
-
- if ( elem.constructor == Number )
- elem += '';
-
- // Convert html string into DOM nodes
- if ( typeof elem == "string" ) {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
- return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
- all :
- front + ">" + tag + ">";
- });
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
-
- var wrap =
- // option or optgroup
- !tags.indexOf("", "" ] ||
-
- !tags.indexOf("", "" ] ||
-
- tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
- [ 1, "" ] ||
-
- !tags.indexOf("
", "" ] ||
-
- // matched above
- (!tags.indexOf(" | ", "
" ] ||
-
- !tags.indexOf("", "" ] ||
-
- // IE can't serialize and