JSDoc: Source: jsxc.lib.xmpp.bookmarks.js

# Source: jsxc.lib.xmpp.bookmarks.js

    /**
     * Load and save bookmarks according to XEP-0048.
     *
     * @namespace jsxc.xmpp.bookmarks
     */
    jsxc.xmpp.bookmarks = {};

    /**
     * Determines if server is able to store bookmarks.
     *
     * @return {boolean} True: Server supports bookmark storage
     */
    jsxc.xmpp.bookmarks.remote = function() {
       return jsxc.xmpp.conn.caps && jsxc.xmpp.hasFeatureByJid(jsxc.xmpp.conn.domain, Strophe.NS.PUBSUB + "#publish");
    };

    /**
     * Load bookmarks from pubsub.
     *
     * @memberOf jsxc.xmpp.bookmarks
     */
    jsxc.xmpp.bookmarks.load = function() {
       var caps = jsxc.xmpp.conn.caps;
       var ver = caps._jidVerIndex[jsxc.xmpp.conn.domain];

       if (!ver || !caps._knownCapabilities[ver]) {
          // wait until we know server capabilities
          $(document).on('caps.strophe', function(ev, from) {
             if (from === jsxc.xmpp.conn.domain) {
                jsxc.xmpp.bookmarks.load();

                $(document).off(ev);
             }
          });
       }

       if (jsxc.xmpp.bookmarks.remote()) {
          jsxc.xmpp.bookmarks.loadFromRemote();
       } else {
          jsxc.xmpp.bookmarks.loadFromLocal();
       }
    };

    /**
     * Load bookmarks from local storage.
     *
     * @private
     */
    jsxc.xmpp.bookmarks.loadFromLocal = function() {
       jsxc.debug('Load bookmarks from local storage');

       var bookmarks = jsxc.storage.getUserItem('bookmarks') || [];
       var bl = jsxc.storage.getUserItem('buddylist') || [];

       $.each(bookmarks, function() {
          var room = this;
          var roomdata = jsxc.storage.getUserItem('buddy', room) || {};

          bl.push(room);
          jsxc.gui.roster.add(room);

          if (roomdata.autojoin) {
             jsxc.debug('auto join ' + room);
             jsxc.xmpp.conn.muc.join(room, roomdata.nickname);
          }
       });

       jsxc.storage.setUserItem('buddylist', bl);
    };

    /**
     * Load bookmarks from remote storage.
     *
     * @private
     */
    jsxc.xmpp.bookmarks.loadFromRemote = function() {
       jsxc.debug('Load bookmarks from pubsub');

       var bookmarks = jsxc.xmpp.conn.bookmarks;

       bookmarks.get(function(stanza) {
          var bl = jsxc.storage.getUserItem('buddylist');

          $(stanza).find('conference').each(function() {
             var conference = $(this);
             var room = conference.attr('jid');
             var roomName = conference.attr('name') || room;
             var autojoin = conference.attr('autojoin') || false;
             var nickname = conference.find('nick').text();
             nickname = (nickname.length > 0) ? nickname : Strophe.getNodeFromJid(jsxc.xmpp.conn.jid);

             if (autojoin === 'true') {
                autojoin = true;
             } else if (autojoin === 'false') {
                autojoin = false;
             }

             var data = jsxc.storage.getUserItem('buddy', room) || {};

             data = $.extend(data, {
                jid: room,
                name: roomName,
                sub: 'both',
                status: 0,
                type: 'groupchat',
                state: jsxc.muc.CONST.ROOMSTATE.INIT,
                subject: null,
                bookmarked: true,
                autojoin: autojoin,
                nickname: nickname
             });

             jsxc.storage.setUserItem('buddy', room, data);

             bl.push(room);
             jsxc.gui.roster.add(room);

             if (autojoin) {
                jsxc.debug('auto join ' + room);
                jsxc.xmpp.conn.muc.join(room, nickname);
             }
          });

          jsxc.storage.setUserItem('buddylist', bl);
       }, function(stanza) {
          var err = jsxc.xmpp.bookmarks.parseErr(stanza);

          if (err.reasons[0] === 'item-not-found') {
             jsxc.debug('create bookmark node');

             bookmarks.createBookmarksNode();
          } else {
             jsxc.debug('[XMPP] Could not create bookmark: ' + err.type, err.reasons);
          }
       });
    };

    /**
     * Parse received error.
     *
     * @param  {string} stanza
     * @return {object} err - The parsed error
     * @return {string} err.type - XMPP error type
     * @return {array} err.reasons - Array of error reasons
     */
    jsxc.xmpp.bookmarks.parseErr = function(stanza) {
       var error = $(stanza).find('error');
       var type = error.attr('type');
       var reasons = error.children().map(function() {
          return $(this).prop('tagName');
       });

       return {
          type: type,
          reasons: reasons
       };
    };

    /**
     * Deletes the bookmark for the given room and removes it from the roster if soft is false.
     *
     * @param  {string} room - room jid
     * @param  {boolean} [soft=false] - True: leave room in roster
     */
    jsxc.xmpp.bookmarks.delete = function(room, soft) {

       if (!soft) {
          jsxc.gui.roster.purge(room);
       }

       if (jsxc.xmpp.bookmarks.remote()) {
          jsxc.xmpp.bookmarks.deleteFromRemote(room, soft);
       } else {
          jsxc.xmpp.bookmarks.deleteFromLocal(room, soft);
       }
    };

    /**
     * Delete bookmark from remote storage.
     *
     * @private
     * @param  {string} room - room jid
     * @param  {boolean} [soft=false] - True: leave room in roster
     */
    jsxc.xmpp.bookmarks.deleteFromRemote = function(room, soft) {
       var bookmarks = jsxc.xmpp.conn.bookmarks;

       bookmarks.delete(room, function() {
          jsxc.debug('Bookmark deleted ' + room);

          if (soft) {
             jsxc.gui.roster.getItem(room).removeClass('jsxc_bookmarked');
             jsxc.storage.updateUserItem('buddy', room, 'bookmarked', false);
             jsxc.storage.updateUserItem('buddy', room, 'autojoin', false);
          }
       }, function(stanza) {
          var err = jsxc.xmpp.bookmarks.parseErr(stanza);

          jsxc.debug('[XMPP] Could not delete bookmark: ' + err.type, err.reasons);
       });
    };

    /**
     * Delete bookmark from local storage.
     *
     * @private
     * @param  {string} room - room jid
     * @param  {boolean} [soft=false] - True: leave room in roster
     */
    jsxc.xmpp.bookmarks.deleteFromLocal = function(room, soft) {
       var bookmarks = jsxc.storage.getUserItem('bookmarks');
       var index = bookmarks.indexOf(room);

       if (index > -1) {
          bookmarks.splice(index, 1);
       }

       jsxc.storage.setUserItem('bookmarks', bookmarks);

       if (soft) {
          jsxc.gui.roster.getItem(room).removeClass('jsxc_bookmarked');
          jsxc.storage.updateUserItem('buddy', room, 'bookmarked', false);
          jsxc.storage.updateUserItem('buddy', room, 'autojoin', false);
       }
    };

    /**
     * Adds or overwrites bookmark for given room.
     *
     * @param  {string} room - room jid
     * @param  {string} alias - room alias
     * @param  {string} nick - preferred user nickname
     * @param  {boolean} autojoin - should we join this room after login?
     */
    jsxc.xmpp.bookmarks.add = function(room, alias, nick, autojoin) {
       if (jsxc.xmpp.bookmarks.remote()) {
          jsxc.xmpp.bookmarks.addToRemote(room, alias, nick, autojoin);
       } else {
          jsxc.xmpp.bookmarks.addToLocal(room, alias, nick, autojoin);
       }
    };

    /**
     * Adds or overwrites bookmark for given room in remote storage.
     *
     * @private
     * @param  {string} room - room jid
     * @param  {string} alias - room alias
     * @param  {string} nick - preferred user nickname
     * @param  {boolean} autojoin - should we join this room after login?
     */
    jsxc.xmpp.bookmarks.addToRemote = function(room, alias, nick, autojoin) {
       var bookmarks = jsxc.xmpp.conn.bookmarks;

       var success = function() {
          jsxc.debug('New bookmark created', room);

          jsxc.gui.roster.getItem(room).addClass('jsxc_bookmarked');
          jsxc.storage.updateUserItem('buddy', room, 'bookmarked', true);
          jsxc.storage.updateUserItem('buddy', room, 'autojoin', autojoin);
          jsxc.storage.updateUserItem('buddy', room, 'nickname', nick);
       };
       var error = function() {
          jsxc.warn('Could not create bookmark', room);
       };

       bookmarks.add(room, alias, nick, autojoin, success, error);
    };

    /**
     * Adds or overwrites bookmark for given room in local storage.
     *
     * @private
     * @param  {string} room - room jid
     * @param  {string} alias - room alias
     * @param  {string} nick - preferred user nickname
     * @param  {boolean} autojoin - should we join this room after login?
     */
    jsxc.xmpp.bookmarks.addToLocal = function(room, alias, nick, autojoin) {
       jsxc.gui.roster.getItem(room).addClass('jsxc_bookmarked');
       jsxc.storage.updateUserItem('buddy', room, 'bookmarked', true);
       jsxc.storage.updateUserItem('buddy', room, 'autojoin', autojoin);
       jsxc.storage.updateUserItem('buddy', room, 'nickname', nick);

       var bookmarks = jsxc.storage.getUserItem('bookmarks') || [];

       if (bookmarks.indexOf(room) < 0) {
          bookmarks.push(room);

          jsxc.storage.setUserItem('bookmarks', bookmarks);
       }
    };

    /**
     * Show dialog to edit bookmark.
     *
     * @param  {string} room - room jid
     */
    jsxc.xmpp.bookmarks.showDialog = function(room) {
       var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('bookmarkDialog'));
       var data = jsxc.storage.getUserItem('buddy', room);

       $('#jsxc_room').val(room);
       $('#jsxc_nickname').val(data.nickname);

       $('#jsxc_bookmark').change(function() {
          if ($(this).prop('checked')) {
             $('#jsxc_nickname').prop('disabled', false);
             $('#jsxc_autojoin').prop('disabled', false);
             $('#jsxc_autojoin').parent('.checkbox').removeClass('disabled');
          } else {
             $('#jsxc_nickname').prop('disabled', true);
             $('#jsxc_autojoin').prop('disabled', true).prop('checked', false);
             $('#jsxc_autojoin').parent('.checkbox').addClass('disabled');
          }
       });

       $('#jsxc_bookmark').prop('checked', data.bookmarked);
       $('#jsxc_autojoin').prop('checked', data.autojoin);

       $('#jsxc_bookmark').change();

       dialog.find('form').submit(function(ev) {
          ev.preventDefault();

          var bookmarked = $('#jsxc_bookmark').prop('checked');
          var autojoin = $('#jsxc_autojoin').prop('checked');
          var nickname = $('#jsxc_nickname').val();

          if (bookmarked) {
             jsxc.xmpp.bookmarks.add(room, data.name, nickname, autojoin);
          } else if (data.bookmarked) {
             // bookmarked === false
             jsxc.xmpp.bookmarks.delete(room, true);
          }

          jsxc.gui.dialog.close();

          return false;
       });
    };