chat  library module
PRA

Summary

Simple WebSocket chat. RESTXQ functions.
Tags

Author: BaseX Team 2005-21, BSD License

__source : chat.xqm

Related documents
ViewDescriptionFormat
xqdocxqDoc xml file from the source modulexml
xqparsexqparse xml file from the source modulexml

Imports

This module is imported by 0 modules. It imports 1 modules.

(None)
imports
this
imports

Variables

None

Functions

4.1 chat:chat

Arities: chat:chat#0RA

Summary
Login or main page.
Signature
chat:chat ( )  as element()
Return
  • element()HTML page
Invokes 3 functions from 2 modules
Invoked by 0 functions from 0 modules
    Annotations
    %rest:path('/chat')
    %output:method('html')
    Source ( 7 lines)
    function chat:chat() as element() {
      if(session:get($chat-util:id)) then (
        chat:main()
      ) else (
        chat:login()
      )
    }

    4.2 chat:login

    Arities: chat:login#0P

    Summary
    Returns the HTML login page.
    Signature
    chat:login ( )  as element(html)
    Return
    • element(html)HTML page
    Invokes 1 functions from 1 modules
    Invoked by 1 functions from 1 modules
    Annotations
    %private()
    Source ( 23 lines)
    function chat:login() as element(html) {
      chat:wrap((
        <div class='warning'>Please enter your credentials:</div>,
        <form action='/chat/login-check' method='post'>
          <div class='small'/>
          <table>
            <tr>
              <td><b>Name:</b></td>
              <td>
                <input size='30' name='name' id='user' autofocus=''/>
              </td>
            </tr>
            <tr>
              <td><b>Password:</b></td>
              <td>{
                <input size='30' type='password' name='pass'/>,
                <button type='submit'>Login</button>
              }</td>
            </tr>
          </table>
        </form>
      ), ())
    }

    4.3 chat:login-check

    Arities: chat:login-check#2R

    Summary
    Checks the user input, registers the user and reloads the chat.
    Signature
    chat:login-check ( $name as xs:string, $pass as xs:string )  as element(rest:response)
    Parameters
    • name as xs:string user name
    • pass as xs:string password
    Return
    • element(rest:response)redirection
    Invokes 3 functions from 3 modules
    • {http://basex.org/modules/session}set#2
    • {http://basex.org/modules/user}check#2
    • {http://basex.org/modules/web}redirect#1
    Invoked by 0 functions from 0 modules
      Annotations
      %rest:POST()
      %rest:path('/chat/login-check')
      %rest:query-param('name','{$name}')
      %rest:query-param('pass','{$pass}')
      Source ( 12 lines)
      function chat:login-check(
        $name  as xs:string,
        $pass  as xs:string
      ) as element(rest:response) {
        try {
          user:check($name, $pass),
          session:set($chat-util:id, $name)
        } catch user:* {
          (: login fails: no session info is set :)
        },
        web:redirect('/chat')
      }

      4.4 chat:logout

      Arities: chat:logout#0R

      Summary
      Logs out the current user, notifies all WebSocket clients, and redirects to the login page.
      Signature
      chat:logout ( )  as element(rest:response)
      Return
      • element(rest:response)redirection
      Invokes 4 functions from 3 modules
      • chat-util:close#0
      • {http://basex.org/modules/session}delete#1
      • {http://basex.org/modules/session}get#1
      • {http://basex.org/modules/web}redirect#1
      Invoked by 0 functions from 0 modules
        Annotations
        %rest:path('/chat/logout')
        Source ( 5 lines)
        function chat:logout() as element(rest:response) {
          session:get($chat-util:id) ! chat-util:close(.),
          session:delete($chat-util:id),
          web:redirect('/chat')
        }

        4.5 chat:main

        Arities: chat:main#0P

        Summary
        Returns the HTML main page.
        Signature
        chat:main ( )  as element(html)
        Return
        • element(html)HTML page
        Invokes 1 functions from 1 modules
        Invoked by 1 functions from 1 modules
        Annotations
        %private()
        Source ( 21 lines)
        function chat:main() as element(html) {
          chat:wrap((
            <p>
              <input type='text' size='60' autofocus='true' placeholder='Message to all users…'
                     id='input' onkeydown='keyDown(event)' autocomplete='off'/>
            </p>,
            <table width='100%'>
              <tr>
                <td width='100'>
                  <div class='note'>USERS (<b>online</b>)</div>
                  <div id='users'/>
                </td>
                <td class='vertical'/>
                <td>
                  <div class='note'>CHAT MESSAGES</div>
                  <div id='messages'/>
                </td>
              </tr>
            </table>
          ), <script type='text/javascript' src='/static/chat.js'/>)
        }

        4.6 chat:wrap

        Arities: chat:wrap#2P

        Summary
        Returns an HTML page.
        Signature
        chat:wrap ( $contents as item()*, $headers as element()* )  as element(html)
        Parameters
        • contents as item()* page contents
        • headers as element()*
        Return
        • element(html)HTML page
        Invokes 1 functions from 1 modules
        • {http://basex.org/modules/session}get#1
        Invoked by 2 functions from 1 modules
        Annotations
        %private()
        Source ( 25 lines)
        function chat:wrap(
          $contents  as item()*,
          $headers   as element()*
        ) as element(html) {
          <html>
            <head>
              <meta charset='utf-8'/>
              <title>BaseX WebSocket Chat</title>
              <meta name='author' content='BaseX Team 2005-21, BSD License'/>
              <link rel='stylesheet' type='text/css' href='/static/style.css'/>
              { $headers }
            </head>
            <body>
              <span class='right'>
                {
                  for $id in session:get($chat-util:id)
                  return <span><b>{ $id }</b> (<a href='/chat/logout'>logout</a>)</span>
                }
                &#xa0; <a href='/'><img src='static/basex.svg' class='img'/></a>
              </span>
              <h1>BaseX WebSocket Chat</h1>
              { $contents }
            </body>
          </html>
        }

        Namespaces

        The following namespaces are defined:

        PrefixUri
        annhttp://www.w3.org/2012/xquery
        chatchat
        chat-utilchat/util
        outputhttp://www.w3.org/2010/xslt-xquery-serialization
        resthttp://exquery.org/ns/restxq

        6 RestXQ

        Paths defined 3.

        PathMethodFunction
        /chatchat:chat#0
        /chat/login-checkPOSTchat:login-check#2
        /chat/logoutchat:logout#0

        Source Code

        (:~
         : Simple WebSocket chat. RESTXQ functions.
         : @author BaseX Team 2005-21, BSD License
         :)
        module namespace chat = 'chat';
        
        import module namespace chat-util = 'chat/util' at 'chat-util.xqm';
        
        (:~
         : Login or main page.
         : @return HTML page
         :)  
        declare
          %rest:path('/chat')
          %output:method('html')
        function chat:chat() as element() {
          if(session:get($chat-util:id)) then (
            chat:main()
          ) else (
            chat:login()
          )
        };
        
        (:~
         : Checks the user input, registers the user and reloads the chat.
         : @param  $name  user name
         : @param  $pass  password
         : @return redirection
         :)  
        declare
          %rest:POST
          %rest:path('/chat/login-check')
          %rest:query-param('name', '{$name}')
          %rest:query-param('pass', '{$pass}')
        function chat:login-check(
          $name  as xs:string,
          $pass  as xs:string
        ) as element(rest:response) {
          try {
            user:check($name, $pass),
            session:set($chat-util:id, $name)
          } catch user:* {
            (: login fails: no session info is set :)
          },
          web:redirect('/chat')
        };
        
        (:~
         : Logs out the current user, notifies all WebSocket clients, and redirects to the login page.
         : @return redirection
         :)
        declare
          %rest:path('/chat/logout')
        function chat:logout() as element(rest:response) {
          session:get($chat-util:id) ! chat-util:close(.),
          session:delete($chat-util:id),
          web:redirect('/chat')
        };
        
        (:~
         : Returns the HTML login page.
         : @return HTML page
         :)
        declare %private function chat:login() as element(html) {
          chat:wrap((
            <div class='warning'>Please enter your credentials:</div>,
            <form action='/chat/login-check' method='post'>
              <div class='small'/>
              <table>
                <tr>
                  <td><b>Name:</b></td>
                  <td>
                    <input size='30' name='name' id='user' autofocus=''/>
                  </td>
                </tr>
                <tr>
                  <td><b>Password:</b></td>
                  <td>{
                    <input size='30' type='password' name='pass'/>,
                    <button type='submit'>Login</button>
                  }</td>
                </tr>
              </table>
            </form>
          ), ())
        };
        
        (:~
         : Returns the HTML main page.
         : @return HTML page
         :)
        declare %private function chat:main() as element(html) {
          chat:wrap((
            <p>
              <input type='text' size='60' autofocus='true' placeholder='Message to all users…'
                     id='input' onkeydown='keyDown(event)' autocomplete='off'/>
            </p>,
            <table width='100%'>
              <tr>
                <td width='100'>
                  <div class='note'>USERS (<b>online</b>)</div>
                  <div id='users'/>
                </td>
                <td class='vertical'/>
                <td>
                  <div class='note'>CHAT MESSAGES</div>
                  <div id='messages'/>
                </td>
              </tr>
            </table>
          ), <script type='text/javascript' src='/static/chat.js'/>)
        };
        
        (:~
         : Returns an HTML page.
         : @param $contents  page contents
         : @param $login     login page
         : @return HTML page
         :)
        declare %private function chat:wrap(
          $contents  as item()*,
          $headers   as element()*
        ) as element(html) {
          <html>
            <head>
              <meta charset='utf-8'/>
              <title>BaseX WebSocket Chat</title>
              <meta name='author' content='BaseX Team 2005-21, BSD License'/>
              <link rel='stylesheet' type='text/css' href='/static/style.css'/>
              { $headers }
            </head>
            <body>
              <span class='right'>
                {
                  for $id in session:get($chat-util:id)
                  return <span><b>{ $id }</b> (<a href='/chat/logout'>logout</a>)</span>
                }
                &#xa0; <a href='/'><img src='static/basex.svg' class='img'/></a>
              </span>
              <h1>BaseX WebSocket Chat</h1>
              { $contents }
            </body>
          </html>
        };