<commit_before>angular.module('mrlapp.nav')

.controller('NavCtrl', ['$scope',  '$log', '$location', '$anchorScroll', 'StateSvc', 'mrl', 'serviceSvc',
    function($scope, $log, $location, $anchorScroll, StateSvc, mrl, serviceSvc) {

        //START_green-/red-LED
        // TODO - green png if connected - if not re-connect button
        if (mrl.isConnected()) {
            $scope.connected = 'connected';
        } else {
            $scope.connected = 'disconnected';
        }

        var onOpen = function() {
            $scope.$apply(function() {
                $scope.connected = 'connected';
            });
        };

        var onClose = function() {
            $scope.$apply(function() {
                $scope.connected = 'disconnected';
            });
        };

        mrl.subscribeOnOpen(onOpen);
        mrl.subscribeOnClose(onClose);
        //END_green-/red-LED

        //START_Status
        $scope.statuslist = StateSvc.getStatuses();

        // FIXME change class not style here ! uniform danger/error/warn/info
        // FIXME -> if error pink background
//        $scope.statusStyle = "statusStyle={'background-color':'pink'}";

        var onStatus = function(statusMsg) {
                    var s = statusMsg.data[0];
                    log.info('status', s);
            $scope.$apply(function() {
                StateSvc.addStatus(s);
            });
        };

        mrl.subscribeToMethod(onStatus, "onStatus");
        //END_Status

        $scope.about = function() {
            // modal display of all contributors & link to myobotlab.org
            // & version & platform
                    $log.info('about');
        };

        $scope.help = function() {
            // modal display of no worky
                    $log.info('help');
        };

        $scope.hideAll = function() {
            $log.info('help');
            serviceSvc.hideAll();
        };

        $scope.showAll = function() {
            // show all panels
            $log.info('showAll');
            serviceSvc.showAll();
        };

                $scope.showminlist = false;
                $scope.toggleMinList = function () {
                    $log.info('toggling MinList');
                    $scope.showminlist = !$scope.showminlist;
                };

        //START_Search
        // $scope.searchPanels = mrl.getServices();
        $scope.searchPanels = serviceSvc.getPanelList();
        $log.info('searchPanels', $scope.searchPanels);

        $scope.searchOnSelect = function(item, model, label) {

            serviceSvc.setPosition(item.name, 0, 0);
            // FIXME - check if panel is hide or show - make hide
            // FIXME - change position to (0, 0) with highest z index
            //scroll to selected service
            // $location.hash(item.name);
            // $anchorScroll();
        };
    //END_Search
    }]);
<commit_msg>small updates to nav<commit_after>angular.module('mrlapp.nav')

        .controller('NavCtrl', ['$scope', '$log', '$filter', '$location', '$anchorScroll', 'mrl', 'StateSvc', 'serviceSvc',
            function ($scope, $log, $filter, $location, $anchorScroll, mrl, StateSvc, serviceSvc) {

    //START_green-/red-LED
    // TODO - green png if connected - if not re-connect button
    if (mrl.isConnected()) {
        $scope.connected = 'connected';
    } else {
        $scope.connected = 'disconnected';
    }

    var onOpen = function() {
        $scope.$apply(function() {
            $scope.connected = 'connected';
        }
        );
    }
    ;

    var onClose = function() {
        $scope.$apply(function() {
            $scope.connected = 'disconnected';
        }
        );
    }
    ;

    mrl.subscribeOnOpen(onOpen);
    mrl.subscribeOnClose(onClose);
    //END_green-/red-LED

    //START_Status
    $scope.statuslist = StateSvc.getStatuses();

    // FIXME change class not style here ! uniform danger/error/warn/info
    // FIXME -> if error pink background
    //        $scope.statusStyle = "statusStyle={'background-color':'pink'}";

    var onStatus = function(statusMsg) {
        var s = statusMsg.data[0];
        log.info('status', s);
        $scope.$apply(function() {
            StateSvc.addStatus(s);
        }
        );
    }
    ;

    mrl.subscribeToMethod(onStatus, "onStatus");
    //END_Status

    $scope.about = function() {
        // modal display of all contributors & link to myobotlab.org
        // & version & platform
        $log.info('about');
    }
    ;

    $scope.help = function() {
        // modal display of no worky
        $log.info('help');
    }
    ;

    $scope.hideAll = function() {
        $log.info('help');
        serviceSvc.hideAll();
    }
    ;

    $scope.showAll = function() {
        // show all panels
        $log.info('showAll');
        serviceSvc.showAll();
    }
    ;

    $scope.showminlist = false;
    $scope.toggleMinList = function() {
        $log.info('toggling MinList');
        $scope.showminlist = !$scope.showminlist;
    }
    ;

    //START_Search
    // $scope.searchPanels = mrl.getServices();
    $scope.searchPanels = serviceSvc.getPanelList();
    $log.info('searchPanels', $scope.searchPanels);

    $scope.searchOnSelect = function(item, model, label) {

        serviceSvc.setPosition(item.name, 0, 0);
        // FIXME - check if panel is hide or show - make hide
        // FIXME - change position to (0, 0) with highest z index
        //scroll to selected service
        // $location.hash(item.name);
        // $anchorScroll();
    }
    ;
    //END_Search
}
]);
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
var Utils = {};

function quote(postId, postNumber) {
	var callback = function (text) {
        $('#post').focus();
        console.log(text);
        var answer = $('#postBody');
        answer.focus();
        if (answer) {
            answer.val(answer.val() + text);
        }

    }

    $.ajax({
        url: baseUrl + '/posts/' + postId + '/quote',
        type: 'POST',
        data: {
            selection: getSelectedPostText(postNumber)
        },
        success: function (data) {
            callback(data.result);
        },
        error: function () {
            callback('');
        }
    });
}

function getSelectedPostText(postNumber) {
    var txt = '';
    if (window.getSelection.length > 0 && isRangeInPost(window.getSelection().getRangeAt(0)) && isSelectedPostQuoted(postNumber)) {
        txt = window.getSelection().toString();
    }
    else if (document.selection.length > 0 && isRangeInPost(document.selection.createRange()) && isSelectedPostQuoted(postNumber)) {
        txt = document.selection.createRange().text;
    }
    return txt;
}

/**
 * Checks if selected document fragment is a part of the post content.
 * @param {Range} range Range object which represent current selection.
 * @return {boolean} true if if selected document fragment is a part of the post content
 *                   false otherwise.
 */
function isRangeInPost(range) {
    return range.startContainer.parentNode.classList.contains("post-content-body");
}

/**
 * Checks if "quote" button pressed on the post which was selected.
 * @param {Number} postNumber number of the post on the page which "quote" button was pressed.
 * @return {boolean} true</> if selected text is a part of the post which will be quoted
 *                   false otherwise.
 */
function isSelectedPostQuoted(postNumber) {
    return $(window.getSelection().getRangeAt(0).startContainer).closest('.post').prevAll().length == postNumber;
}

/**
 * Encodes given string by escaping special HTML characters
 *
 * @param s string to be encoded
 */
Utils.htmlEncode = function (s) {
    return $('
').text(s).html();
};

/**
 * Do focus to element
 *
 * @param target selector of element to focus
 */
Utils.focusFirstEl = function (target) {
    $(target).focus();
}

/**
 * Replaces all \n characters by
 tags. Used for review comments.
 *
 * @param s string where perform replacing
 */
Utils.lf2br = function (s) {
    return s.replace(/\n/g, "
");
}

/**
 * Replaces all \
 tags by \n characters. Used for review comments.
 *
 * @param s string where perform replacing
 */
Utils.br2lf = function (s) {
    return s.replace(/
/gi, "\n");
}

/**
 * Create form field with given label(placeholder), id, type
 */
Utils.createFormElement = function (label, id, type, cls) {
    var elementHtml = ' \

 \

 \
                <input type="' + type + '" id="' + id + '" name="' + id + '" placeholder="' + label + '" class="input-xlarge ' + cls + '" /> \

 \

 \
    ';

    return elementHtml;
}
<commit_msg>#JC-1853: Move focus to Create topic dialog on quoting:  * Corrected condition for partial quotation<commit_after>/*
 * Copyright (C) 2011  JTalks.org Team
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
var Utils = {};

function quote(postId, postNumber) {
	var callback = function (text) {
        $('#post').focus();
        console.log(text);
        var answer = $('#postBody');
        answer.focus();
        if (answer) {
            answer.val(answer.val() + text);
        }

    }

    $.ajax({
        url: baseUrl + '/posts/' + postId + '/quote',
        type: 'POST',
        data: {
            selection: getSelectedPostText(postNumber)
        },
        success: function (data) {
            callback(data.result);
        },
        error: function () {
            callback('');
        }
    });
}

function getSelectedPostText(postNumber) {
    var txt = '';
    if (window.getSelection) {
        if (window.getSelection().toString().length > 0 && isRangeInPost(window.getSelection().getRangeAt(0))
            && isSelectedPostQuoted(postNumber)) {
            txt = window.getSelection().toString();
        }
    }
    else if (document.selection) {
        if (isRangeInPost(document.selection.createRange()) && isSelectedPostQuoted(postNumber)) {
            txt = document.selection.createRange().text;
        }
    }
    return txt;
}

/**
 * Checks if selected document fragment is a part of the post content.
 * @param {Range} range Range object which represent current selection.
 * @return {boolean} true if if selected document fragment is a part of the post content
 *                   false otherwise.
 */
function isRangeInPost(range) {
    return range.startContainer.parentNode.classList.contains("post-content-body");
}

/**
 * Checks if "quote" button pressed on the post which was selected.
 * @param {Number} postNumber number of the post on the page which "quote" button was pressed.
 * @return {boolean} true</> if selected text is a part of the post which will be quoted
 *                   false otherwise.
 */
function isSelectedPostQuoted(postNumber) {
    return $(window.getSelection().getRangeAt(0).startContainer).closest('.post').prevAll().length == postNumber;
}

/**
 * Encodes given string by escaping special HTML characters
 *
 * @param s string to be encoded
 */
Utils.htmlEncode = function (s) {
    return $('
').text(s).html();
};

/**
 * Do focus to element
 *
 * @param target selector of element to focus
 */
Utils.focusFirstEl = function (target) {
    $(target).focus();
}

/**
 * Replaces all \n characters by
 tags. Used for review comments.
 *
 * @param s string where perform replacing
 */
Utils.lf2br = function (s) {
    return s.replace(/\n/g, "
");
}

/**
 * Replaces all \
 tags by \n characters. Used for review comments.
 *
 * @param s string where perform replacing
 */
Utils.br2lf = function (s) {
    return s.replace(/
/gi, "\n");
}

/**
 * Create form field with given label(placeholder), id, type
 */
Utils.createFormElement = function (label, id, type, cls) {
    var elementHtml = ' \

 \

 \
                <input type="' + type + '" id="' + id + '" name="' + id + '" placeholder="' + label + '" class="input-xlarge ' + cls + '" /> \

 \

 \
    ';

    return elementHtml;
}
<|endoftext|>


<commit_before>var cdb = require('cartodb-deep-insights.js');
var $ = require('jquery');
var WidgetsFormContentDataView = require('./widgets-form-content-data-view');
var WidgetsFormContentStyleView = require('./widgets-form-content-style-view');
var createTextLabelsTabPane = require('../../../components/tab-pane/create-text-labels-tab-pane');
var TabPaneTemplate = require('../../tab-pane-template.tpl');

/**
 * View to render all necessary for the widget form
 */

module.exports = cdb.core.View.extend({

  events: {
    'click .js-back': '_onClickBack'
  },

  initialize: function (opts) {
    if (!opts.widgetDefinitionModel) throw new Error('widgetDefinitionModel is required');
    if (!opts.layerDefinitionsCollection) throw new Error('layerDefinitionsCollection is required');
    if (!opts.stackLayoutModel) throw new Error('stackLayoutModel is required');

    this._widgetDefinitionModel = opts.widgetDefinitionModel;
    this._layerDefinitionsCollection = opts.layerDefinitionsCollection;
    this._stackLayoutModel = opts.stackLayoutModel;
  },

  render: function () {
    this.clearSubViews();
    this._initViews();
    return this;
  },

  _initViews: function () {
    var self = this;

    this.tabPaneItems = [{
      selected: true,
      label: _t('editor.widgets.widgets-form.data.title'),
      createContentView: function () {
        var layerId = self._widgetDefinitionModel.get('layer_id');
        var layerDefinitionModel = self._layerDefinitionsCollection.get(layerId);

        return new WidgetsFormContentDataView({
          widgetDefinitionModel: self._widgetDefinitionModel,
          layerTableModel: layerDefinitionModel.layerTableModel
        });
      }
    }, {
      selected: false,
      label: _t('editor.widgets.widgets-form.style.title'),
      createContentView: function () {
        return new WidgetsFormContentStyleView({
          widgetDefinitionModel: self._widgetDefinitionModel
        });
      }
    }];

    var options = {
      tabPaneOptions: {
        tagName: 'nav',
        className: 'CDB-NavMenu',
        template: TabPaneTemplate,
        title: self._widgetDefinitionModel.get('title'),
        canGoBack: true,
        tabPaneItemOptions: {
          tagName: 'li',
          className: 'CDB-NavMenu-Item'
        }
      },
      tabPaneItemLabelOptions: {
        tagName: 'button',
        className: 'CDB-NavMenu-Link'
      }
    };

    this.tabPaneView = createTextLabelsTabPane(this.tabPaneItems, options);
    this.$el.append(this.tabPaneView.render().$el);
  },

  _onClickBack: function () {
    this._stackLayoutModel.prevStep();
  }

});
<commit_msg>fixes warning<commit_after>var cdb = require('cartodb-deep-insights.js');
var WidgetsFormContentDataView = require('./widgets-form-content-data-view');
var WidgetsFormContentStyleView = require('./widgets-form-content-style-view');
var createTextLabelsTabPane = require('../../../components/tab-pane/create-text-labels-tab-pane');
var TabPaneTemplate = require('../../tab-pane-template.tpl');

/**
 * View to render all necessary for the widget form
 */

module.exports = cdb.core.View.extend({

  events: {
    'click .js-back': '_onClickBack'
  },

  initialize: function (opts) {
    if (!opts.widgetDefinitionModel) throw new Error('widgetDefinitionModel is required');
    if (!opts.layerDefinitionsCollection) throw new Error('layerDefinitionsCollection is required');
    if (!opts.stackLayoutModel) throw new Error('stackLayoutModel is required');

    this._widgetDefinitionModel = opts.widgetDefinitionModel;
    this._layerDefinitionsCollection = opts.layerDefinitionsCollection;
    this._stackLayoutModel = opts.stackLayoutModel;
  },

  render: function () {
    this.clearSubViews();
    this._initViews();
    return this;
  },

  _initViews: function () {
    var self = this;

    this.tabPaneItems = [{
      selected: true,
      label: _t('editor.widgets.widgets-form.data.title'),
      createContentView: function () {
        var layerId = self._widgetDefinitionModel.get('layer_id');
        var layerDefinitionModel = self._layerDefinitionsCollection.get(layerId);

        return new WidgetsFormContentDataView({
          widgetDefinitionModel: self._widgetDefinitionModel,
          layerTableModel: layerDefinitionModel.layerTableModel
        });
      }
    }, {
      selected: false,
      label: _t('editor.widgets.widgets-form.style.title'),
      createContentView: function () {
        return new WidgetsFormContentStyleView({
          widgetDefinitionModel: self._widgetDefinitionModel
        });
      }
    }];

    var options = {
      tabPaneOptions: {
        tagName: 'nav',
        className: 'CDB-NavMenu',
        template: TabPaneTemplate,
        title: self._widgetDefinitionModel.get('title'),
        canGoBack: true,
        tabPaneItemOptions: {
          tagName: 'li',
          className: 'CDB-NavMenu-Item'
        }
      },
      tabPaneItemLabelOptions: {
        tagName: 'button',
        className: 'CDB-NavMenu-Link'
      }
    };

    this.tabPaneView = createTextLabelsTabPane(this.tabPaneItems, options);
    this.$el.append(this.tabPaneView.render().$el);
  },

  _onClickBack: function () {
    this._stackLayoutModel.prevStep();
  }

});
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import {execSync} from 'child_process';
import Base from './base';

const PATH = path.join(think.RUNTIME_PATH, 'importMarkdownFileToFirekylin');
export default class extends Base {
  constructor(think) {
    super(think);
    this._think = think;
  }
  /**
   * 导入用户
   */
  async user() {
    return 0;
  }

  /**
   * 导入分类
   */
  async category() {
    return 0;
  }

  /**
   * 导入标签
   */
  async tag() {
    return 0;
  }

  /**
   * 导入文章
   */
  async post(posts = []) {
    if(!Array.isArray(posts)) {
      return 0;
    }

    const postsPromise = posts.map(async item => {
      try{
        //获取用户
        const user = await this._think.session('userInfo');

        let post = {
          title: item.title,
          pathname: item.pathname,
          markdown_content: item.markdown_content,
          create_time: this.formatDate(new Date(item.created_at)),
          update_time: this.formatDate(new Date(item.updated_at)),
          status: 3,
          user_id: user.id,
          comment_num: 0,
          allow_comment: 1,
          is_public: 1,
          type: 0
        };
        post = await think.model('post', null, 'admin').getContentAndSummary(post);
        await this.postModelInstance.addPost(post);
      } catch(e) {
        console.log(e);  // eslint-disable-line no-console
      }
    });
    Promise.all(postsPromise);

    return posts.length;
  }

  /**
   * 导入页面
   */
  async page() {
    return 0;
  }

  parseFile(file) {
    try {
      execSync(`rm -rf ${PATH}; mkdir ${PATH}; cd ${PATH}; tar zxvf ${file.path}`);
      let files = fs.readdirSync(PATH, {encoding: 'utf-8'});
      if(!files.length) { return []; }

      return files.map(function(file) {
        let tar = path.join(PATH, file);
        let title = file.split('.').slice(0, -1).join('');
        let content = fs.readFileSync(tar, {encoding: 'utf-8'});
        let stat = fs.statSync(tar);
        return {
          created_at: stat.birthtime.getTime(),
          updated_at: stat.mtime.getTime(),
          title,
          pathname: title,
          markdown_content: content
        };
      });
    } catch(e) {
      throw new Error(e);
    }
  }

  /**
   * 执行导入
   */
  async run(file) {
    return await this.importData(this.parseFile(file));
  }
}
<commit_msg>fix markdown upload inject<commit_after>import fs from 'fs';
import path from 'path';
import {execSync} from 'child_process';
import Base from './base';

const PATH = path.join(think.RUNTIME_PATH, 'importMarkdownFileToFirekylin');
export default class extends Base {
  constructor(think) {
    super(think);
    this._think = think;
  }
  /**
   * 导入用户
   */
  async user() {
    return 0;
  }

  /**
   * 导入分类
   */
  async category() {
    return 0;
  }

  /**
   * 导入标签
   */
  async tag() {
    return 0;
  }

  /**
   * 导入文章
   */
  async post(posts = []) {
    if(!Array.isArray(posts)) {
      return 0;
    }

    const postsPromise = posts.map(async item => {
      try{
        //获取用户
        const user = await this._think.session('userInfo');

        let post = {
          title: item.title,
          pathname: item.pathname,
          markdown_content: item.markdown_content,
          create_time: this.formatDate(new Date(item.created_at)),
          update_time: this.formatDate(new Date(item.updated_at)),
          status: 3,
          user_id: user.id,
          comment_num: 0,
          allow_comment: 1,
          is_public: 1,
          type: 0
        };
        post = await think.model('post', null, 'admin').getContentAndSummary(post);
        await this.postModelInstance.addPost(post);
      } catch(e) {
        console.log(e);  // eslint-disable-line no-console
      }
    });
    Promise.all(postsPromise);

    return posts.length;
  }

  /**
   * 导入页面
   */
  async page() {
    return 0;
  }

  parseFile(file) {
    try {
      const filePath = file.path.replace(/"/g, '');
      execSync(`rm -rf ${PATH}; mkdir ${PATH}; cd ${PATH}; tar zxvf "${filePath}"`);
      let files = fs.readdirSync(PATH, {encoding: 'utf-8'});
      if(!files.length) { return []; }

      return files.map(function(file) {
        let tar = path.join(PATH, file);
        let title = file.split('.').slice(0, -1).join('');
        let content = fs.readFileSync(tar, {encoding: 'utf-8'});
        let stat = fs.statSync(tar);
        return {
          created_at: stat.birthtime.getTime(),
          updated_at: stat.mtime.getTime(),
          title,
          pathname: title,
          markdown_content: content
        };
      });
    } catch(e) {
      throw new Error(e);
    }
  }

  /**
   * 执行导入
   */
  async run(file) {
    return await this.importData(this.parseFile(file));
  }
}
<|endoftext|>


<commit_before>/*jslint browser: true, indent: 2, todo: true, unparam: true */
/*global jQuery,Ornament */

(function (document, window, $) {

  "use strict";

  $(document).on("ornament:refresh", function () {

    // Global scope so we can call functions anywhere
    window.mobileNav = {

      // Classes
      layoutOpenClass:            "layout-open",
      layoutTransitionClass:      "layout-transitioning",
      paneClass:                  "pane", // all lists are panes
      firstPaneClass:             "pane__first", // unique class for the first pane
      nonPaneClass:               "non-pane", // lists that aren't a separate pane (eg. multiple list might makeup one "pane")
      hasChildren:                "has-children", // links that have children
      cmsActiveClass:             "selected", // active class given to items via the CMS
      menuSelectedClass:          "active", // selected class given to items via the menu to determine depth and pane visibility
      menuNavigationClass:        "pane--navigation-container", // class that contains our navigation list
      menuNavItemClass:           "navigation-item", // list items that are navigation triggers for styling purposes
      menuReadyClass:             "ready", // ready class, only used so that scaffolding won't happen more than once
      backContainerClass:         "back", // class used for back button containers
      backButtonClass:            "button", // class used for back buttons
      descriptionClass:           "description",
      descriptionTitleClass:      "description--title",
      descriptionBodyClass:       "description--body",
      descriptionOverviewClass:   "description--overview",

      // Settings
      simple:                     false, // simple accordion style menu instead of moving panes
      animationDuration:          500, // opening the menu transition time
      animationBuffer:            100, // buffer for good measure
      slideTransitionTime:        200, // transition between pane sliding
      jumpToCurrent:              true, // jump to current page in the menu rather than starting at top-level
      showOverviewLinks:          true, // will show overview links on secodary panes
      keepScrollPosition:         false, // keep scroll position when opening tabs, dangerous if button isn't fixed
      closeForAnchors:            true, // close menu when clicking on anchors

      // Customisable text strings
      viewOverviewText:           "View Overview",
      backText:                   "Back",

      // Selectors
      tray:                       $(".navigation-mobile"),
      anchor:                     $(".layout--switch"),
      contentElement:             $(".layout--content"),
      layoutElement:              $(".layout"),

      // Core Settings
      currentLevel: 1, // initial level
      timeout: null, // temporary variable for later, used for keeping track of timeouts
      scrollPosition: 0, // keeps track of the scroll position, used when keepScrollPosition:true

      startMenuTimeout: function(){
        mobileNav.timeout = setTimeout(function () {
          mobileNav.layoutElement.removeClass(mobileNav.layoutTransitionClass);
        }, mobileNav.animationDuration + mobileNav.animationBuffer);
      },

      clearMenuTimeout: function(){
        if (mobileNav.timeout !== undefined) {
          clearTimeout(mobileNav.timeout);
        }
      },

      // Return a true if the menu is open, false if closed
      isOpen: function() {
        if (mobileNav.layoutElement.hasClass(mobileNav.layoutOpenClass)) {
          return true;
        } else {
          return false;
        }
      },

      // Close menu
      closeMenu: function(){
        mobileNav.layoutElement.removeClass(mobileNav.layoutOpenClass).addClass(mobileNav.layoutTransitionClass);
        mobileNav.contentElement.off("click", "*");
        mobileNav.clearMenuTimeout();
        mobileNav.startMenuTimeout();

        if(mobileNav.keepScrollPosition) {
          setTimeout(function(){
            scrollTo(0,mobileNav.scrollPosition);
          }, mobileNav.animationDuration + mobileNav.animationBuffer);
        }
      },

      // Open menu
      openMenu: function(){
        if(!mobileNav.simple) {
          mobileNav.updateMenuHeight();
        }

        // get scroll position and update
        mobileNav.scrollPosition = $(window).scrollTop();

        // update classes on page
        mobileNav.layoutElement.addClass(mobileNav.layoutOpenClass + " " + mobileNav.layoutTransitionClass);

        // get scroll position

        // clicking on content wilgl close menu
        mobileNav.contentElement.on("click", "*", function (event) {
          mobileNav.toggleMenu();
          return false;
        });

        // start animation timings
        mobileNav.clearMenuTimeout();
        mobileNav.startMenuTimeout();
      },

      // Toggle menu. Open if closed, close if open.
      toggleMenu: function(){
        if( mobileNav.isOpen() ) {
          mobileNav.closeMenu();
        } else {
          mobileNav.openMenu();
        }
      },

      // Return the last selected element
      getCurrentTab: function(){
        return mobileNav.tray.find("."+ mobileNav.menuSelectedClass ).last();
      },

      // Get active page from CMS
      getCMSActivePage: function(){
        return mobileNav.tray.find("."+ mobileNav.cmsActiveClass ).last();
      },

      getNestedMenus: function(){
        return mobileNav.tray.find("ul ul");
      },

      // Update mobile menu height based on content
      updateMenuHeight: function(){

        var windowHeight = Ornament.windowHeight();
        var $currentTab = mobileNav.getCurrentTab();
        var paneHeight = 0;
        var navHeight = 0;

        // Get the height of the required elements
        if( mobileNav.currentLevel == 1 ) {
          paneHeight = mobileNav.tray.find("." + mobileNav.menuNavigationClass).outerHeight();
        } else if ( $currentTab.is("a") ) {
          paneHeight = $currentTab.parent("li").parent("ul").outerHeight();
        } else {
          paneHeight = $currentTab.children("div").children("ul").outerHeight();
        }

        // Check which is larger, window or pane?
        if( windowHeight > paneHeight ) {
          navHeight = windowHeight;
        } else {
          navHeight = paneHeight;
        }

        // Apply the height, yo.
        mobileNav.tray.height(navHeight);

      },

      // Update heights on a delay (eg. when moving between panes)
      updateMenuHeightWithDelay: function() {
        setTimeout(function(){
          mobileNav.updateMenuHeight();
        }, mobileNav.slideTransitionTime);
      },

      // Go back one level
      goBack: function(){
        // don't do anything if it's animating already
        if(mobileNav.tray.is(":animated")) {
          return false;
        }
        // Animate back to the previous pane
        mobileNav.currentLevel = mobileNav.currentLevel - 1;
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
        setTimeout(function(){
          // Remove selected class on the parent selected element
          // Do this after it has animated back to the previous pane via timeout
          mobileNav.getCurrentTab().removeClass(mobileNav.menuSelectedClass);
          mobileNav.updateMenuHeight();
        }, mobileNav.slideTransitionTime);
      },

      // Go to a particular item in the menu by passing in a tab
      goTo: function($tab) {
        // get the depth of this tab and update level
        mobileNav.currentLevel = $tab.parents("ul").length;
        // reset level to 1 if zero
        if(mobileNav.currentLevel == 0) {
          mobileNav.currentLevel = 1;
        }
        // apply current level
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
        mobileNav.tray.find("."+mobileNav.menuSelectedClass).removeClass(mobileNav.menuSelectedClass);
        $tab.parents("li").first().addClass(mobileNav.menuSelectedClass);
        mobileNav.markParentAsActive($tab);
        // update heights
        mobileNav.updateMenuHeightWithDelay();
      },

      // Match an ID and navigate to it
      // You can pass in an ID pre-hashed or not
      // ie. goToId("key1") or goToId("#key1")
      goToId: function(key) {
        // Add in a hash if one wasn't passed
        if(key.substr(0,1) != "#") {
          key = "#" + key;
        }
        var $keyNode = $(key);
        // Only go to it if it exists
        if($keyNode.length) {
          // Check if the node is a link or a list
          if($keyNode.is("a")) {
            mobileNav.goTo($keyNode);
          } else {
            mobileNav.goTo($keyNode.children("a"));
          }
        }
      },

      // Mark all pages as inactive and then go to root
      goToRoot: function(){
        mobileNav.tray.find("."+mobileNav.menuSelectedClass).removeClass(mobileNav.menuSelectedClass);
        mobileNav.currentLevel = 1;
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
      },

      // Mark a parent node as active
      markParentAsActive: function($node) {
        var $parent = $node.parent("li").parent("ul").parent(".pane").parent("li");
        if($parent.length) {
          $parent.addClass(mobileNav.menuSelectedClass);
          // Keep going up the tree until you can't go no mo.
          mobileNav.markParentAsActive($parent.children("a"));
        }
      },

      updateMenuBindingForAnchor: function(){

        // Binding clicks on anchor to toggle menu
        mobileNav.anchor.on("click", function(e) {
          e.preventDefault();
          mobileNav.toggleMenu();
          return false;
        });

      },

      // Apply bindings to all back, forward and anchor buttons
      updateMenuBindings: function(){

        mobileNav.updateMenuBindingForAnchor();

        if(mobileNav.simple) {

          // Clicking on parent links toggles the ones below it
          var $parentLinks = mobileNav.tray.find("[data-mobilenav-accordion] > a");
          $parentLinks.off("click").on("click", function(e){
            e.preventDefault();
            $(this).parent("li").toggleClass("visible");
          });

        } else {

          // Making forward buttons work
          mobileNav.tray.find("[data-mobilenav-forward]").children("a").off("click").on("click", function(e) {
            e.preventDefault();
            // abort if already animating
            if(mobileNav.tray.is(":animated")) {
              return false;
            }
            var $thisForward = $(this);
            $thisForward.parent("li").addClass(mobileNav.menuSelectedClass).siblings().removeClass(mobileNav.menuSelectedClass);
            mobileNav.currentLevel = mobileNav.currentLevel + 1;
            mobileNav.tray.attr("data-level", mobileNav.currentLevel);
            mobileNav.updateMenuHeightWithDelay();
          });

          // Making back buttons work
          mobileNav.tray.find("[data-mobilenav-back]").off("click").on("click", function(e){
            e.preventDefault();
            mobileNav.goBack();
          });

        }

        if(mobileNav.closeForAnchors) {

          // Make anchor links close the menu
          mobileNav.tray.on("click", "a[href*=#]:not([href=#])", function(e){

            var $anchor = $(e.originalEvent.target);
            var shouldOverride = true;

            // Don't override for forward links
            if( $anchor.parent("li").is("[data-mobilenav-forward]") ) {
              shouldOverride = false;
            }

            // Don't override for back buttons
            if( $anchor.is("[data-mobilenav-back]") ) {
              shouldOverride = false;
            }

            // Close menu when clicking on anchor links if not matched above
            if( shouldOverride ) {
              mobileNav.closeMenu();
            }

          });

        }

      },

      // Scaffold the complex mobile menu
      scaffoldMobileMenu: function(){

        var $tray = mobileNav.tray;

        // Abort if already scaffolded
        if( $tray.hasClass(mobileNav.menuReadyClass) ) {
          return false;
        }

        $tray.addClass("complex");

        // Add class to current tab
        var $currentTab = mobileNav.getCMSActivePage();
        $currentTab.parent("li").addClass(mobileNav.menuSelectedClass);

        // Wrap each list in a pane div to assist in animation and sizing
        $tray.find("ul").not("."+mobileNav.nonPaneClass).wrap("
");

        // Add helper class to first pane
        var $firstPane = $tray.find("."+mobileNav.paneClass).first();
        $firstPane.addClass(mobileNav.firstPaneClass);

        // Adding classes to pre-existing nav elements for styling purposes
        $tray.find("."+mobileNav.menuNavigationClass).find("li").addClass(mobileNav.menuNavItemClass);

        // Jump to current pane if required
        if(mobileNav.jumpToCurrent) {
          mobileNav.goTo( mobileNav.getCurrentTab().children("a") );
        }

        // Update menu heights for first time
        mobileNav.updateMenuHeight();

        // Add forward buttons
        mobileNav.tray.find("li").not(mobileNav.menuDescriptionClass).each(function(){
          var $parentNode = $(this);
          if($parentNode.children("div").length > 0) {
            $parentNode.addClass(mobileNav.hasChildren).attr("data-mobilenav-forward","");
          }
        });

        // Add back button and description blocks
        mobileNav.getNestedMenus().each(function(){
          var $nestedNode = $(this);
          var $parentPane = $nestedNode.parent("."+mobileNav.paneClass);
          var nodeTitle = $parentPane.prev().text();
          var nodeDescription = $parentPane.parent("li").attr("data-description");
          var $nodeLink = $parentPane.parent("li").children("a");

          // build description block
          var $descriptionBlock = $("
");
          $descriptionBlock.append("
" + nodeTitle + "
");

          // only add description if available
          if(nodeDescription) {
            $descriptionBlock.append("
" + nodeDescription + "
");
          }

          // only add overview link if there's a link to be overviewed
          if ( mobileNav.showOverviewLinks ) {
            $descriptionBlock.append("
" + mobileNav.viewOverviewText + "
");
          }
          $nestedNode.prepend($descriptionBlock);

          // add the back button
          $nestedNode.prepend("
" + mobileNav.backText + "
");
        });

        // Run bindings
        mobileNav.updateMenuBindings();

        // Add ready class to prevent re-scaffolding
        $tray.addClass(mobileNav.menuReadyClass);

      },

      // Scaffolind the simple version of the menu
      scaffoldSimpleMenu: function(){

        // Abort if already ready
        if(mobileNav.tray.hasClass(mobileNav.menuReadyClass)) {
          return false;
        }

        // Add simple class for styling purposes
        mobileNav.tray.addClass("simple");

        // Add data attributes to parent links
        var $parentLinks = mobileNav.tray.find("ul ul").parent("li");
        $parentLinks.attr("data-mobilenav-accordion","");

        // Update key bindings
        mobileNav.updateMenuBindings();

        // Add ready class
        mobileNav.tray.addClass(mobileNav.menuReadyClass);

      }
    };

    // Create menu on page load
    if(mobileNav.simple) {

      mobileNav.scaffoldSimpleMenu();

    } else {

      // Scaffold the complex menu and apply bindings
      mobileNav.scaffoldMobileMenu();

      // Update heights on resize
      $(window).on("resize", function(){
        mobileNav.updateMenuHeightWithDelay();
      });

    }

  });

}(document, window, jQuery));
<commit_msg>Added highlighting to overview links if the parent node is the current page<commit_after>/*jslint browser: true, indent: 2, todo: true, unparam: true */
/*global jQuery,Ornament */

(function (document, window, $) {

  "use strict";

  $(document).on("ornament:refresh", function () {

    // Global scope so we can call functions anywhere
    window.mobileNav = {

      // Classes
      layoutOpenClass:            "layout-open",
      layoutTransitionClass:      "layout-transitioning",
      paneClass:                  "pane", // all lists are panes
      firstPaneClass:             "pane__first", // unique class for the first pane
      nonPaneClass:               "non-pane", // lists that aren't a separate pane (eg. multiple list might makeup one "pane")
      hasChildren:                "has-children", // links that have children
      cmsActiveClass:             "selected", // active class given to items via the CMS
      menuSelectedClass:          "active", // selected class given to items via the menu to determine depth and pane visibility
      menuNavigationClass:        "pane--navigation-container", // class that contains our navigation list
      menuNavItemClass:           "navigation-item", // list items that are navigation triggers for styling purposes
      menuReadyClass:             "ready", // ready class, only used so that scaffolding won't happen more than once
      backContainerClass:         "back", // class used for back button containers
      backButtonClass:            "button", // class used for back buttons
      descriptionClass:           "description",
      descriptionTitleClass:      "description--title",
      descriptionBodyClass:       "description--body",
      descriptionOverviewClass:   "description--overview",

      // Settings
      simple:                     false, // simple accordion style menu instead of moving panes
      animationDuration:          500, // opening the menu transition time
      animationBuffer:            100, // buffer for good measure
      slideTransitionTime:        200, // transition between pane sliding
      jumpToCurrent:              true, // jump to current page in the menu rather than starting at top-level
      showOverviewLinks:          true, // will show overview links on secodary panes
      keepScrollPosition:         false, // keep scroll position when opening tabs, dangerous if button isn't fixed
      closeForAnchors:            true, // close menu when clicking on anchors

      // Customisable text strings
      viewOverviewText:           "View Overview",
      backText:                   "Back",

      // Selectors
      tray:                       $(".navigation-mobile"),
      anchor:                     $(".layout--switch"),
      contentElement:             $(".layout--content"),
      layoutElement:              $(".layout"),

      // Core Settings
      currentLevel: 1, // initial level
      timeout: null, // temporary variable for later, used for keeping track of timeouts
      scrollPosition: 0, // keeps track of the scroll position, used when keepScrollPosition:true

      startMenuTimeout: function(){
        mobileNav.timeout = setTimeout(function () {
          mobileNav.layoutElement.removeClass(mobileNav.layoutTransitionClass);
        }, mobileNav.animationDuration + mobileNav.animationBuffer);
      },

      clearMenuTimeout: function(){
        if (mobileNav.timeout !== undefined) {
          clearTimeout(mobileNav.timeout);
        }
      },

      // Return a true if the menu is open, false if closed
      isOpen: function() {
        if (mobileNav.layoutElement.hasClass(mobileNav.layoutOpenClass)) {
          return true;
        } else {
          return false;
        }
      },

      // Close menu
      closeMenu: function(){
        mobileNav.layoutElement.removeClass(mobileNav.layoutOpenClass).addClass(mobileNav.layoutTransitionClass);
        mobileNav.contentElement.off("click", "*");
        mobileNav.clearMenuTimeout();
        mobileNav.startMenuTimeout();

        if(mobileNav.keepScrollPosition) {
          setTimeout(function(){
            scrollTo(0,mobileNav.scrollPosition);
          }, mobileNav.animationDuration + mobileNav.animationBuffer);
        }
      },

      // Open menu
      openMenu: function(){
        if(!mobileNav.simple) {
          mobileNav.updateMenuHeight();
        }

        // get scroll position and update
        mobileNav.scrollPosition = $(window).scrollTop();

        // update classes on page
        mobileNav.layoutElement.addClass(mobileNav.layoutOpenClass + " " + mobileNav.layoutTransitionClass);

        // get scroll position

        // clicking on content wilgl close menu
        mobileNav.contentElement.on("click", "*", function (event) {
          mobileNav.toggleMenu();
          return false;
        });

        // start animation timings
        mobileNav.clearMenuTimeout();
        mobileNav.startMenuTimeout();

        if(!mobileNav.simple) {
          mobileNav.updateMenuHeight();
        }
      },

      // Toggle menu. Open if closed, close if open.
      toggleMenu: function(){
        if( mobileNav.isOpen() ) {
          mobileNav.closeMenu();
        } else {
          mobileNav.openMenu();
        }
      },

      // Return the last selected element
      getCurrentTab: function(){
        return mobileNav.tray.find("."+ mobileNav.menuSelectedClass ).last();
      },

      // Get active page from CMS
      getCMSActivePage: function(){
        return mobileNav.tray.find("."+ mobileNav.cmsActiveClass ).last();
      },

      getNestedMenus: function(){
        return mobileNav.tray.find("ul ul");
      },

      // Update mobile menu height based on content
      updateMenuHeight: function(){

        var windowHeight = Ornament.windowHeight();
        var $currentTab = mobileNav.getCurrentTab();
        var paneHeight = 0;
        var navHeight = 0;

        // Get the height of the required elements
        if( mobileNav.currentLevel == 1 ) {
          paneHeight = mobileNav.tray.find("." + mobileNav.menuNavigationClass).outerHeight();
        } else if ( $currentTab.is("a") ) {
          paneHeight = $currentTab.parent("li").parent("ul").outerHeight();
        } else if ( $currentTab.children("div").length ) {
          paneHeight = $currentTab.children("div").children("ul").outerHeight();
        } else {
          paneHeight = $currentTab.parent("ul").outerHeight();
        }

        // Check which is larger, window or pane?
        if( windowHeight > paneHeight ) {
          navHeight = windowHeight;
        } else {
          navHeight = paneHeight;
        }

        // Apply the height, yo.
        mobileNav.tray.height(navHeight);

      },

      // Update heights on a delay (eg. when moving between panes)
      updateMenuHeightWithDelay: function() {
        setTimeout(function(){
          mobileNav.updateMenuHeight();
        }, mobileNav.slideTransitionTime);
      },

      // Go back one level
      goBack: function(){
        // don't do anything if it's animating already
        if(mobileNav.tray.is(":animated")) {
          return false;
        }
        // Animate back to the previous pane
        mobileNav.currentLevel = mobileNav.currentLevel - 1;
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
        setTimeout(function(){
          // Remove selected class on the parent selected element
          // Do this after it has animated back to the previous pane via timeout
          mobileNav.getCurrentTab().removeClass(mobileNav.menuSelectedClass);
          mobileNav.updateMenuHeight();
        }, mobileNav.slideTransitionTime);
      },

      // Go to a particular item in the menu by passing in a tab
      goTo: function($tab) {
        // get the depth of this tab and update level
        mobileNav.currentLevel = $tab.parents("ul").length;
        // reset level to 1 if zero
        if(mobileNav.currentLevel == 0) {
          mobileNav.currentLevel = 1;
        }
        // apply current level
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
        mobileNav.tray.find("."+mobileNav.menuSelectedClass).removeClass(mobileNav.menuSelectedClass);
        $tab.parents("li").first().addClass(mobileNav.menuSelectedClass);
        mobileNav.markParentAsActive($tab);
        // update heights
        mobileNav.updateMenuHeightWithDelay();
      },

      // Match an ID and navigate to it
      // You can pass in an ID pre-hashed or not
      // ie. goToId("key1") or goToId("#key1")
      goToId: function(key) {
        // Add in a hash if one wasn't passed
        if(key.substr(0,1) != "#") {
          key = "#" + key;
        }
        var $keyNode = $(key);
        // Only go to it if it exists
        if($keyNode.length) {
          // Check if the node is a link or a list
          if($keyNode.is("a")) {
            mobileNav.goTo($keyNode);
          } else {
            mobileNav.goTo($keyNode.children("a"));
          }
        }
      },

      // Mark all pages as inactive and then go to root
      goToRoot: function(){
        mobileNav.tray.find("."+mobileNav.menuSelectedClass).removeClass(mobileNav.menuSelectedClass);
        mobileNav.currentLevel = 1;
        mobileNav.tray.attr("data-level", mobileNav.currentLevel);
      },

      // Mark a parent node as active
      markParentAsActive: function($node) {
        var $parent = $node.parent("li").parent("ul").parent(".pane").parent("li");
        if($parent.length) {
          $parent.addClass(mobileNav.menuSelectedClass);
          // Keep going up the tree until you can't go no mo.
          mobileNav.markParentAsActive($parent.children("a"));
        }
      },

      updateMenuBindingForAnchor: function(){

        // Binding clicks on anchor to toggle menu
        mobileNav.anchor.on("click", function(e) {
          e.preventDefault();
          mobileNav.toggleMenu();
          return false;
        });

      },

      // Apply bindings to all back, forward and anchor buttons
      updateMenuBindings: function(){

        mobileNav.updateMenuBindingForAnchor();

        if(mobileNav.simple) {

          // Clicking on parent links toggles the ones below it
          var $parentLinks = mobileNav.tray.find("[data-mobilenav-accordion] > a");
          $parentLinks.off("click").on("click", function(e){
            e.preventDefault();
            $(this).parent("li").toggleClass("visible");
          });

        } else {

          // Making forward buttons work
          mobileNav.tray.find("[data-mobilenav-forward]").children("a").off("click").on("click", function(e) {
            e.preventDefault();
            // abort if already animating
            if(mobileNav.tray.is(":animated")) {
              return false;
            }
            var $thisForward = $(this);
            $thisForward.parent("li").addClass(mobileNav.menuSelectedClass).siblings().removeClass(mobileNav.menuSelectedClass);
            mobileNav.currentLevel = mobileNav.currentLevel + 1;
            mobileNav.tray.attr("data-level", mobileNav.currentLevel);
            mobileNav.updateMenuHeightWithDelay();
          });

          // Making back buttons work
          mobileNav.tray.find("[data-mobilenav-back]").off("click").on("click", function(e){
            e.preventDefault();
            mobileNav.goBack();
          });

        }

        if(mobileNav.closeForAnchors) {

          // Make anchor links close the menu
          mobileNav.tray.on("click", "a[href*=#]:not([href=#])", function(e){

            var $anchor = $(e.originalEvent.target);
            var shouldOverride = true;

            // Don't override for forward links
            if( $anchor.parent("li").is("[data-mobilenav-forward]") ) {
              shouldOverride = false;
            }

            // Don't override for back buttons
            if( $anchor.is("[data-mobilenav-back]") ) {
              shouldOverride = false;
            }

            // Close menu when clicking on anchor links if not matched above
            if( shouldOverride ) {
              mobileNav.closeMenu();
            }

          });

        }

      },

      // Scaffold the complex mobile menu
      scaffoldMobileMenu: function(){

        var $tray = mobileNav.tray;

        // Abort if already scaffolded
        if( $tray.hasClass(mobileNav.menuReadyClass) ) {
          return false;
        }

        $tray.addClass("complex");

        // Add class to current tab
        var $currentTab = mobileNav.getCMSActivePage();
        $currentTab.parent("li").addClass(mobileNav.menuSelectedClass);

        // Wrap each list in a pane div to assist in animation and sizing
        $tray.find("ul").not("."+mobileNav.nonPaneClass).wrap("
");

        // Add helper class to first pane
        var $firstPane = $tray.find("."+mobileNav.paneClass).first();
        $firstPane.addClass(mobileNav.firstPaneClass);

        // Adding classes to pre-existing nav elements for styling purposes
        $tray.find("."+mobileNav.menuNavigationClass).find("li").addClass(mobileNav.menuNavItemClass);

        // Jump to current pane if required
        if(mobileNav.jumpToCurrent) {
          mobileNav.goTo( mobileNav.getCurrentTab().children("a") );
        }

        // Update menu heights for first time
        mobileNav.updateMenuHeight();

        // Add forward buttons
        mobileNav.tray.find("li").not(mobileNav.menuDescriptionClass).each(function(){
          var $parentNode = $(this);
          if($parentNode.children("div").length > 0) {
            $parentNode.addClass(mobileNav.hasChildren).attr("data-mobilenav-forward","");
          }
        });

        // Add back button and description blocks
        mobileNav.getNestedMenus().each(function(){
          var $nestedNode = $(this);
          var $parentPane = $nestedNode.parent("."+mobileNav.paneClass);
          var nodeTitle = $parentPane.prev().text();
          var nodeDescription = $parentPane.parent("li").attr("data-description");
          var $nodeLink = $parentPane.parent("li").children("a");

          // build description block
          var $descriptionBlock = $("
");
          $descriptionBlock.append("
" + nodeTitle + "
");

          // only add description if available
          if(nodeDescription) {
            $descriptionBlock.append("
" + nodeDescription + "
");
          }

          // only add overview link if there's a link to be overviewed
          if ( mobileNav.showOverviewLinks && $nodeLink.attr("href") ) {
            var $overviewLink = $("
" + mobileNav.viewOverviewText + "
");
            $descriptionBlock.append($overviewLink);
          }
          $nestedNode.prepend($descriptionBlock);

          // add the back button
          $nestedNode.prepend("
" + mobileNav.backText + "
");

          // Make active if parent is selected
          // NOTE: Not very flexible in it's current state, could potentially
          // use some refactoring
          if ( mobileNav.showOverviewLinks && $nodeLink.attr("href") && $nodeLink.attr("href") == location.pathname ) {
            $overviewLink.addClass(mobileNav.cmsActiveClass).addClass(mobileNav.menuSelectedClass);
          }
        });

        // Run bindings
        mobileNav.updateMenuBindings();

        // Add ready class to prevent re-scaffolding
        $tray.addClass(mobileNav.menuReadyClass);

      },

      // Scaffolind the simple version of the menu
      scaffoldSimpleMenu: function(){

        // Abort if already ready
        if(mobileNav.tray.hasClass(mobileNav.menuReadyClass)) {
          return false;
        }

        // Add simple class for styling purposes
        mobileNav.tray.addClass("simple");

        // Add data attributes to parent links
        var $parentLinks = mobileNav.tray.find("ul ul").parent("li");
        $parentLinks.attr("data-mobilenav-accordion","");

        // Update key bindings
        mobileNav.updateMenuBindings();

        // Add ready class
        mobileNav.tray.addClass(mobileNav.menuReadyClass);

      }
    };

    // Create menu on page load
    if(mobileNav.simple) {

      mobileNav.scaffoldSimpleMenu();

    } else {

      // Scaffold the complex menu and apply bindings
      mobileNav.scaffoldMobileMenu();

      // Update heights on resize
      $(window).on("resize", function(){
        mobileNav.updateMenuHeightWithDelay();
      });

    }

  });

}(document, window, jQuery));
<|endoftext|>


<commit_before>const optional = true,
      required = true

module.exports = [
  {
    name: "Bloom",
    prototype: "postprocessing",
    doc: "The Bloom effect creates blurred glow effects in areas of the scene that are brighter than a specific *threshold* property.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: 0,
        doc: "Pixels with a brightness value above the threshold property will be spread their brightness to adjacent pixels, creating a glow effect."
      },
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "The amount to boost the brightness of pixels that this effect operates on. High values (above 2) will result in blurred offsets that create duplicate images."
      }
    }
  },
  {
    name: "Blur",
    prototype: "postprocessing",
    doc: "The Blur effect... blurs the final image on both axes. This operation can be repeated multiple times via the `.repetitions` argument to the constructor, and the number of samples used in the blur can also be increased in the constructor. Increasing these values will create a higher quality blur at an increased computational expense. The blur can cheaply be expanded by simply using the `.amount` property, which can be freely modified at runtime.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "The amount to boost the brightness of pixels that this effect operates on. High values (above 2) will result in blurred offsets that create duplicate images."
      },
      repetitions: {
        type: "int",
        default: 2,
        doc: "How many times to apply the blur effect. This property can *only be set in the constructor; it is not runtime editable.*",
      },
      taps: {
        type: "int",
        default: 5,
        doc: "The number of neighboring pixels that are sampled to genereate the blur. The available options are 5,9, and 13. This property can *only be set in the constructor; it is not runtime editable.*"
      },
    }
  },
  {
    name: "Brightness",
    prototype: "postprocessing",
    doc: "The `Brightness` effect increases/decreases the overall brightness of the scene based on the `.amount` property.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .25,
        doc: "Values above 0 increase the original brightness of the scene, values below 0 decrease it."
      },
    }
  },
  {
    name: "Contast",
    prototype: "postprocessing",
    doc: "The `Brightness` effect increases/decreases the overall contrast of the scene based on the `.amount` property.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .5,
        doc: "Values below 1 decrease the original contrast of the scene."
      },
    }
  },
  {
    name: "Edge",
    prototype: "postprocessing",
    doc: "The `Edge` effect finds the edges of images using the [sobel operator](https://en.wikipedia.org/wiki/Sobel_operator), potentially resulting in a stylized, cartoonish effect result.",
    properties: {
       mode: {
        type: "int",
        default: 0,
        doc: "The mode property sets what algorithm is used by the Edge filter, with one of three possibilities: 0 - Classic Sobel edge detection; 1 "
      }
    }
  },
  {
    name: "Focus",
    prototype: "postprocessing",
    doc: "`Focus` is used to create a depth-of-field effect, where parts of the image that are currently in focus (according to the value of the `.depth` property) will appear crisp, while the rest of the image is blurred.",
    properties: {
      depth: {
        isa: "number(sequencable)",
        type: "float",
        default: 0,
        doc: "Given a value of 0, objects far from the camera will be blurred. Given a value of 1, objects close to the camera will be blurred.",
      },
      radius: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "How much of the image is in focus. Larger areas will result in mmore of the image being crisp at the specified depth level."
      }
    }
  },
  {
    name: "Godrays",
    prototype: "postprocessing",
    doc: "`Focus` is used to create a depth-of-field effect, where parts of the image that are currently in focus (according to the value of the `.depth` property) will appear crisp, while the rest of the image is blurred.",
    properties: {
      decay: {
        isa: "number(sequencable)",
        type: "float",
        default: 1,
        doc: "How fast the rays fade as they travel from their source. Values higher than `1` will create feedback that can quickly overwhelm a scene."
      },
      weight: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "Multiplies the original background colors; higher values lead to brighter rays. This property expects very low values, typically between 0-.02.",
      },
      density: {
        isa: "number(sequencable)",
        type: "float",
        default: 1,
        doc: "How close samples are together."
      },
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .9,
        doc: "Controls at what depth (where 1 is the farthest visible depth) the rays begin."
      },
    }
  },
  {
    name: "Hue",
    prototype: "postprocessing",
    doc: "The `Hue` effect shifts the hue of objects below a provided depth threshold. Using the default threshold value of .99 the scene will be inverted while the background retains its original color. With a threshold value of 1 the background color will also be changed.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .99,
        doc: "Object fragments with a depth below this number (where depth is normalized to be between 0–1) will have their color shifted, other parts of the scene will be unaffected. A depth of .99 should usually keep the background color the same while changing the rest of the scene."
      },
      shift : {
        isa: "number(sequencable)",
        type: "float",
        default: .5,
        doc: "The amount to shift the hue in the HSV color space."
      }
    }
  },
  {
    name: "Invert",
    prototype: "postprocessing",
    doc: "The `Invert` effect inverts the color of objects below a provided depth threshold. Using the default threshold value of .99 (really, any value lower than 1) the scene will be inverted while the background retains its original color. With a threshold value of 1 the background color will also be changed.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .99,
        doc: "Object fragments with a depth below this number (where depth is normalized to be between 0–1) will have their color inverted, other parts of the scene will be unaffected. A depth of .99 should usually keep the background color the same while changing the rest of the scene."
      }
    }
  },
  {
    name: "MotionBlur",
    prototype: "postprocessing",
    doc: "The `MotionBlur` effect can be used to create everything from subtle blurring based on movement in the scene (similiar to the blurring created by 'real-life' movement) to trippy feedback fun.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .7,
        doc: "The amount of feedback used to create the blur effect. Values above `.9` can be quite fun and experimental, while lower values can be used to create pseudo-realistic blurring around moving objects."
      }
    }
  },
]
<commit_msg>adding antialising docs<commit_after>const optional = true,
      required = true

module.exports = [
  {
    name: "Antialias",
    prototype: "postprocessing",
    doc: "The Antialias effect smooths jagged edges in images using the Fast Approximate Anti-Aliasing (FXAA) algortihm. The construtor accepts a numerical argument which determines the number of times the algorithm will be applied; each application requires a complete render stage so it's best to use values < 10, or even < 5.",
    properties: {
      repetitions: {
        type: "int",
        default: 1,
        doc: "How many times to apply the antialias effect. This property can *only be set in the constructor; it is not runtime editable.*",
      }
    }
  },

  {
    name: "Bloom",
    prototype: "postprocessing",
    doc: "The Bloom effect creates blurred glow effects in areas of the scene that are brighter than a specific *threshold* property.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: 0,
        doc: "Pixels with a brightness value above the threshold property will be spread their brightness to adjacent pixels, creating a glow effect."
      },
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "The amount to boost the brightness of pixels that this effect operates on. High values (above 2) will result in blurred offsets that create duplicate images."
      }
    }
  },
  {
    name: "Blur",
    prototype: "postprocessing",
    doc: "The Blur effect... blurs the final image on both axes. This operation can be repeated multiple times via the `.repetitions` argument to the constructor, and the number of samples used in the blur can also be increased in the constructor. Increasing these values will create a higher quality blur at an increased computational expense. The blur can cheaply be expanded by simply using the `.amount` property, which can be freely modified at runtime.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "The amount to boost the brightness of pixels that this effect operates on. High values (above 2) will result in blurred offsets that create duplicate images."
      },
      repetitions: {
        type: "int",
        default: 2,
        doc: "How many times to apply the blur effect. This property can *only be set in the constructor; it is not runtime editable.*",
      },
      taps: {
        type: "int",
        default: 5,
        doc: "The number of neighboring pixels that are sampled to genereate the blur. The available options are 5,9, and 13. This property can *only be set in the constructor; it is not runtime editable.*"
      },
    }
  },
  {
    name: "Brightness",
    prototype: "postprocessing",
    doc: "The `Brightness` effect increases/decreases the overall brightness of the scene based on the `.amount` property.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .25,
        doc: "Values above 0 increase the original brightness of the scene, values below 0 decrease it."
      },
    }
  },
  {
    name: "Contast",
    prototype: "postprocessing",
    doc: "The `Brightness` effect increases/decreases the overall contrast of the scene based on the `.amount` property.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .5,
        doc: "Values below 1 decrease the original contrast of the scene."
      },
    }
  },
  {
    name: "Edge",
    prototype: "postprocessing",
    doc: "The `Edge` effect finds the edges of images using the [sobel operator](https://en.wikipedia.org/wiki/Sobel_operator), potentially resulting in a stylized, cartoonish effect result.",
    properties: {
       mode: {
        type: "int",
        default: 0,
        doc: "The mode property sets what algorithm is used by the Edge filter, with one of three possibilities: 0 - Classic Sobel edge detection; 1 "
      }
    }
  },
  {
    name: "Focus",
    prototype: "postprocessing",
    doc: "`Focus` is used to create a depth-of-field effect, where parts of the image that are currently in focus (according to the value of the `.depth` property) will appear crisp, while the rest of the image is blurred.",
    properties: {
      depth: {
        isa: "number(sequencable)",
        type: "float",
        default: 0,
        doc: "Given a value of 0, objects far from the camera will be blurred. Given a value of 1, objects close to the camera will be blurred.",
      },
      radius: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "How much of the image is in focus. Larger areas will result in mmore of the image being crisp at the specified depth level."
      }
    }
  },
  {
    name: "Godrays",
    prototype: "postprocessing",
    doc: "`Focus` is used to create a depth-of-field effect, where parts of the image that are currently in focus (according to the value of the `.depth` property) will appear crisp, while the rest of the image is blurred.",
    properties: {
      decay: {
        isa: "number(sequencable)",
        type: "float",
        default: 1,
        doc: "How fast the rays fade as they travel from their source. Values higher than `1` will create feedback that can quickly overwhelm a scene."
      },
      weight: {
        isa: "number(sequencable)",
        type: "float",
        default: .01,
        doc: "Multiplies the original background colors; higher values lead to brighter rays. This property expects very low values, typically between 0-.02.",
      },
      density: {
        isa: "number(sequencable)",
        type: "float",
        default: 1,
        doc: "How close samples are together."
      },
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .9,
        doc: "Controls at what depth (where 1 is the farthest visible depth) the rays begin."
      },
    }
  },
  {
    name: "Hue",
    prototype: "postprocessing",
    doc: "The `Hue` effect shifts the hue of objects below a provided depth threshold. Using the default threshold value of .99 the scene will be inverted while the background retains its original color. With a threshold value of 1 the background color will also be changed.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .99,
        doc: "Object fragments with a depth below this number (where depth is normalized to be between 0–1) will have their color shifted, other parts of the scene will be unaffected. A depth of .99 should usually keep the background color the same while changing the rest of the scene."
      },
      shift : {
        isa: "number(sequencable)",
        type: "float",
        default: .5,
        doc: "The amount to shift the hue in the HSV color space."
      }
    }
  },
  {
    name: "Invert",
    prototype: "postprocessing",
    doc: "The `Invert` effect inverts the color of objects below a provided depth threshold. Using the default threshold value of .99 (really, any value lower than 1) the scene will be inverted while the background retains its original color. With a threshold value of 1 the background color will also be changed.",
    properties: {
      threshold: {
        isa: "number(sequencable)",
        type: "float",
        default: .99,
        doc: "Object fragments with a depth below this number (where depth is normalized to be between 0–1) will have their color inverted, other parts of the scene will be unaffected. A depth of .99 should usually keep the background color the same while changing the rest of the scene."
      }
    }
  },
  {
    name: "MotionBlur",
    prototype: "postprocessing",
    doc: "The `MotionBlur` effect can be used to create everything from subtle blurring based on movement in the scene (similiar to the blurring created by 'real-life' movement) to trippy feedback fun.",
    properties: {
      amount: {
        isa: "number(sequencable)",
        type: "float",
        default: .7,
        doc: "The amount of feedback used to create the blur effect. Values above `.9` can be quite fun and experimental, while lower values can be used to create pseudo-realistic blurring around moving objects."
      }
    }
  },
]
<|endoftext|>


<commit_before>(function () {
    "use strict";

    window.App.videos = [
        {
            title: 'Silicon Valley S02E08',
            url: 'http://fs.to/get/dl/6jw62sy7o95w31o0hoe2yr75y.0.521872670.974127405.1433155559/Silicon.Valley.S02E08.1080i.HDTV.DD5.1.H.264.Amedia.ts',
            type: 'vod'
        },
        {
            title: 'Redbull',
            url: 'http://live.iphone.redbull.de.edgesuite.net/webtvHD.m3u8',
            type: 'hls'
        }
    ];
})();
<commit_msg>Update videos.js<commit_after>(function () {
    "use strict";

    window.App.videos = [
        {
            title: 'The.Making.of.the.Mob.New.York.S01E01',
            url: 'http://fs.to/get/dl/6jw62sy7o8hbx03a3gvqxt87a.0.521872670.974127405.1435400589/The.Making.of.the.Mob.New.York.S01E01.1080p.rus.LostFilm.mkv',
            type: 'vod'
        },
        {
            title: 'Redbull',
            url: 'http://live.iphone.redbull.de.edgesuite.net/webtvHD.m3u8',
            type: 'hls'
        }
    ];
})();
<|endoftext|>


<commit_before>const user = (state = [], action) => {
  switch (action.type) {
  case "ADD_USERS":
    return action.users
  case "UPDATE_USER":
    const { userToken, newAttributes } = action
    return state.map(user => {
      return (user.token === userToken) ? { ...user, ...newAttributes } : user
    })
  default:
    return state
  }
}

export default user
<commit_msg>Fix indentation in user reducer<commit_after>const user = (state = [], action) => {
  switch (action.type) {
    case "ADD_USERS":
      return action.users
    case "UPDATE_USER":
      const { userToken, newAttributes } = action
      return state.map(user => {
        return (user.token === userToken) ? { ...user, ...newAttributes } : user
      })
    default:
      return state
  }
}

export default user
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

// Provides control sap.m.MessagePage.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/IconPool'],
	function(jQuery, library, Control, IconPool) {
		"use strict";

		/**
		 * Constructor for a new MessagePage.
		 *
		 * @param {string} [sId] id for the new control, generated automatically if no id is given
		 * @param {object} [mSettings] initial settings for the new control
		 *
		 * @class
		 * MessagePage is displayed when there is no data or matching content. There are different use cases where a MessagePage might be visualized, for example:
		 *		- The search query returned no results
		 *		- The app contains no items
		 *		- There are too many items
		 *		- The application is loading
		 *	The layout is unchanged but the text varies depending on the use case.
		 * @extends sap.ui.core.Control
		 * @version ${version}
		 *
		 * @constructor
		 * @public
		 * @since 1.28
		 * @alias sap.m.MessagePage
		 */
		var MessagePage = Control.extend("sap.m.MessagePage", /** @lends sap.m.MessagePage.prototype */ { metadata : {

			library : "sap.m",
			properties : {
				/**
				 * MessagePage text
				 */
				text : {type : "string", group : "Misc", defaultValue : "No matching items found."},
				/**
				 * MessagePage description
				 */
				description : {type : "string", group : "Misc", defaultValue : "Check the filter settings."},
				/**
				 * MessagePage title
				 */
				title : { type : "string", group : "Misc", defaultValue : null },
				/**
				 * Determines whether the header of the MessagePage is rendered when it's embedded in another page.
				 */
				showHeader : { type : "boolean", group : "Appearance", defaultValue : true },
				/**
				 * A nav button will be rendered in the header if this property is set to true.
				 */
				showNavButton : {type : "boolean", group : "Appearance", defaultValue : false},
				/**
				 * MessagePage main icon
				 */
				icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : "sap-icon://documents" },
				/**
				 * This property specifies the element's text directionality with enumerated options. By default, the control inherits text direction from the DOM.
				 */
				textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : sap.ui.core.TextDirection.Inherit}
			},
			aggregations : {
				/**
				 * The (optional) custom Text control of this page.
				 * Use this aggregation when the "text" (sap.m.Text) control needs to be replaced with a sap.m.Link control.
				 * "text" and "textDirection" setters can be used for this aggregation.
				 */
				customText : {type : "sap.m.Link", multiple : false},
				/**
				 * The (optional) custom description control of this page.
				 * Use this aggregation when the "description" (sap.m.Text) control needs to be replaced with a sap.m.Link control.
				 * "description" and "textDirection" setters can be used for this aggregation.
				 */
				customDescription : {type : "sap.m.Link", multiple : false},
				/**
				 * A Page control which is managed internally by the MessagePage control
				 */
				_page : {type : "sap.m.Page", multiple : false/*, visibility : "hidden"*/}
			},
			associations : {

				/**
				 * Association to controls / ids which describe this control (see WAI-ARIA attribute aria-describedby).
				 */
				ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"},

				/**
				 * Association to controls / ids which label this control (see WAI-ARIA attribute aria-labelledby).
				 */
				ariaLabelledBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaLabelledBy"}
			},
			events : {
				/**
				 * this event is fired when Nav Button is pressed
				 * @since 1.28.1
				 */
				navButtonPress : {}
			}
		}});

		MessagePage.prototype.init = function() {
			var oBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

			this.setAggregation("_page", new sap.m.Page({
				showHeader : this.getShowHeader(),
				navButtonPress : jQuery.proxy(function() {
					this.fireNavButtonPress();
				}, this)
			}));
			this.setProperty("text", oBundle.getText("MESSAGE_PAGE_TEXT"), true);
			this.setProperty("description", oBundle.getText("MESSAGE_PAGE_DESCRIPTION"), true);
		};

		MessagePage.prototype.onBeforeRendering = function() {
			// Don't want controls to be added again on re-rendering
			if (!(this._oText && this._oDescription)) {
				this._addPageContent();
			}
		};

		MessagePage.prototype.exit = function() {
			var oPage = this.getAggregation("_page");

			if (oPage) {
				oPage.destroy();
				oPage = null;
			}

			if (this._oText) {
				this._oText = null;
			}

			if (this._oDescription) {
				this._oDescription = null;
			}

			if (this._oIconControl) {
				this._oIconControl = null;
			}
		};

		MessagePage.prototype.setTitle = function(sTitle) {
			this.setProperty("title", sTitle, true); // no re-rendering
			this.getAggregation("_page").setTitle(sTitle);
		};

		MessagePage.prototype.setText = function(sText) {
			this.setProperty("text", sText, true); // no re-rendering
			this._oText && this._oText.setText(sText);
		};

		MessagePage.prototype.setDescription = function(sDescription) {
			this.setProperty("description", sDescription, true); // no re-rendering
			this._oDescription && this._oDescription.setText(sDescription);
		};

		MessagePage.prototype.setShowHeader = function(bShowHeader) {
			this.setProperty("showHeader", bShowHeader, true); // no re-rendering
			this.getAggregation("_page").setShowHeader(bShowHeader);
		};

		MessagePage.prototype.setShowNavButton = function(bShowNavButton) {
			this.setProperty("showNavButton", bShowNavButton, true); // no re-rendering
			this.getAggregation("_page").setShowNavButton(bShowNavButton);
		};

		MessagePage.prototype.setTextDirection = function(sTextDirection) {
			this.setProperty("textDirection", sTextDirection, true); // no re-rendering
			this._oText && this._oText.setTextDirection(sTextDirection);
			this._oDescription && this._oDescription.setTextDirection(sTextDirection);
		};

		MessagePage.prototype.setIcon = function(sIconUri) {
			var sOldIconUri = this.getIcon();
			this.setProperty("icon", sIconUri, true); // no re-rendering

			if (this._oIconControl) {
				// check if the value is changed and if URIs are from different type(icon or image) in order to avoid destroying and creating of icon control
				if (sOldIconUri !== sIconUri && IconPool.isIconURI(sOldIconUri) != IconPool.isIconURI(sIconUri)) {
					var oPage = this.getAggregation("_page");

					oPage.removeContent(this._oIconControl);
					this._oIconControl.destroy();
					oPage.insertContent(this._getIconControl(), 0);
				} else {
					this._oIconControl.setSrc(sIconUri);
				}
			}
		};

		MessagePage.prototype._addPageContent = function() {
			var oPage = this.getAggregation("_page");

			if (this.getAggregation("customText")) {
				this._oText = this.getAggregation("customText");
			} else {
				this._oText = new sap.m.Text({
					text: this.getText(),
					textAlign: sap.ui.core.TextAlign.Center,
					textDirection: this.getTextDirection()
				});
			}

			if (this.getAggregation("customDescription")) {
				this._oDescription = this.getAggregation("customDescription");
			} else {
				this._oDescription = new sap.m.Text({
					text: this.getDescription(),
					textAlign: sap.ui.core.TextAlign.Center,
					textDirection: this.getTextDirection()
				});
			}

			oPage.addContent(this._getIconControl());
			oPage.addContent(this._oText.addStyleClass("sapMMessagePageMainText"));
			oPage.addContent(this._oDescription.addStyleClass("sapMMessagePageDescription"));
		};

		MessagePage.prototype._getIconControl = function() {
			this._oIconControl = IconPool.createControlByURI({
				id: this.getId() + "-pageIcon",
				src: this.getIcon(),
				height: "8rem"
			}, sap.m.Image).addStyleClass("sapMMessagePageIcon");

			return this._oIconControl;
		};

		/**
		 * Returns the internal header
		 * Adding this functions because they are needed by the SplitContainer logic to show the "hamburger" button.
		 * @private
		 * @returns {sap.m.IBar}
		 */
		MessagePage.prototype._getAnyHeader = function() {
			return this._getInternalHeader();
		};

		/**
		 * Adding this functions because they are needed by the SplitContainer logic to show the "hamburger" button.
		 * @returns {sap.m.IBar}
		 * @private
		 */

		MessagePage.prototype._getInternalHeader = function() {
			return this.getAggregation("_page").getAggregation("_internalHeader");
		};

		return MessagePage;
	}, /* bExport= */ true);
<commit_msg>[INTERNAL][FIX] sap.m.MessagePage: changed showNavButton description<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.MessagePage.
sap.ui.define(['jquery.sap.global', './library', 'sap/ui/core/Control', 'sap/ui/core/IconPool'],
	function(jQuery, library, Control, IconPool) {
		"use strict";

		/**
		 * Constructor for a new MessagePage.
		 *
		 * @param {string} [sId] id for the new control, generated automatically if no id is given
		 * @param {object} [mSettings] initial settings for the new control
		 *
		 * @class
		 * MessagePage is displayed when there is no data or matching content. There are different use cases where a MessagePage might be visualized, for example:
		 *		- The search query returned no results
		 *		- The app contains no items
		 *		- There are too many items
		 *		- The application is loading
		 *	The layout is unchanged but the text varies depending on the use case.
		 * @extends sap.ui.core.Control
		 * @version ${version}
		 *
		 * @constructor
		 * @public
		 * @since 1.28
		 * @alias sap.m.MessagePage
		 */
		var MessagePage = Control.extend("sap.m.MessagePage", /** @lends sap.m.MessagePage.prototype */ { metadata : {

			library : "sap.m",
			properties : {
				/**
				 * MessagePage text
				 */
				text : {type : "string", group : "Misc", defaultValue : "No matching items found."},
				/**
				 * MessagePage description
				 */
				description : {type : "string", group : "Misc", defaultValue : "Check the filter settings."},
				/**
				 * MessagePage title
				 */
				title : { type : "string", group : "Misc", defaultValue : null },
				/**
				 * Determines whether the header of the MessagePage is rendered when it's embedded in another page.
				 */
				showHeader : { type : "boolean", group : "Appearance", defaultValue : true },
				/**
				 * If this property is set to true, a navigation button will be rendered in the header.
				 */
				showNavButton : {type : "boolean", group : "Appearance", defaultValue : false},
				/**
				 * MessagePage main icon
				 */
				icon : {type : "sap.ui.core.URI", group : "Misc", defaultValue : "sap-icon://documents" },
				/**
				 * This property specifies the element's text directionality with enumerated options. By default, the control inherits text direction from the DOM.
				 */
				textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : sap.ui.core.TextDirection.Inherit}
			},
			aggregations : {
				/**
				 * The (optional) custom Text control of this page.
				 * Use this aggregation when the "text" (sap.m.Text) control needs to be replaced with a sap.m.Link control.
				 * "text" and "textDirection" setters can be used for this aggregation.
				 */
				customText : {type : "sap.m.Link", multiple : false},
				/**
				 * The (optional) custom description control of this page.
				 * Use this aggregation when the "description" (sap.m.Text) control needs to be replaced with a sap.m.Link control.
				 * "description" and "textDirection" setters can be used for this aggregation.
				 */
				customDescription : {type : "sap.m.Link", multiple : false},
				/**
				 * A Page control which is managed internally by the MessagePage control
				 */
				_page : {type : "sap.m.Page", multiple : false/*, visibility : "hidden"*/}
			},
			associations : {

				/**
				 * Association to controls / ids which describe this control (see WAI-ARIA attribute aria-describedby).
				 */
				ariaDescribedBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaDescribedBy"},

				/**
				 * Association to controls / ids which label this control (see WAI-ARIA attribute aria-labelledby).
				 */
				ariaLabelledBy : {type : "sap.ui.core.Control", multiple : true, singularName : "ariaLabelledBy"}
			},
			events : {
				/**
				 * this event is fired when Nav Button is pressed
				 * @since 1.28.1
				 */
				navButtonPress : {}
			}
		}});

		MessagePage.prototype.init = function() {
			var oBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

			this.setAggregation("_page", new sap.m.Page({
				showHeader : this.getShowHeader(),
				navButtonPress : jQuery.proxy(function() {
					this.fireNavButtonPress();
				}, this)
			}));
			this.setProperty("text", oBundle.getText("MESSAGE_PAGE_TEXT"), true);
			this.setProperty("description", oBundle.getText("MESSAGE_PAGE_DESCRIPTION"), true);
		};

		MessagePage.prototype.onBeforeRendering = function() {
			// Don't want controls to be added again on re-rendering
			if (!(this._oText && this._oDescription)) {
				this._addPageContent();
			}
		};

		MessagePage.prototype.exit = function() {
			var oPage = this.getAggregation("_page");

			if (oPage) {
				oPage.destroy();
				oPage = null;
			}

			if (this._oText) {
				this._oText = null;
			}

			if (this._oDescription) {
				this._oDescription = null;
			}

			if (this._oIconControl) {
				this._oIconControl = null;
			}
		};

		MessagePage.prototype.setTitle = function(sTitle) {
			this.setProperty("title", sTitle, true); // no re-rendering
			this.getAggregation("_page").setTitle(sTitle);
		};

		MessagePage.prototype.setText = function(sText) {
			this.setProperty("text", sText, true); // no re-rendering
			this._oText && this._oText.setText(sText);
		};

		MessagePage.prototype.setDescription = function(sDescription) {
			this.setProperty("description", sDescription, true); // no re-rendering
			this._oDescription && this._oDescription.setText(sDescription);
		};

		MessagePage.prototype.setShowHeader = function(bShowHeader) {
			this.setProperty("showHeader", bShowHeader, true); // no re-rendering
			this.getAggregation("_page").setShowHeader(bShowHeader);
		};

		MessagePage.prototype.setShowNavButton = function(bShowNavButton) {
			this.setProperty("showNavButton", bShowNavButton, true); // no re-rendering
			this.getAggregation("_page").setShowNavButton(bShowNavButton);
		};

		MessagePage.prototype.setTextDirection = function(sTextDirection) {
			this.setProperty("textDirection", sTextDirection, true); // no re-rendering
			this._oText && this._oText.setTextDirection(sTextDirection);
			this._oDescription && this._oDescription.setTextDirection(sTextDirection);
		};

		MessagePage.prototype.setIcon = function(sIconUri) {
			var sOldIconUri = this.getIcon();
			this.setProperty("icon", sIconUri, true); // no re-rendering

			if (this._oIconControl) {
				// check if the value is changed and if URIs are from different type(icon or image) in order to avoid destroying and creating of icon control
				if (sOldIconUri !== sIconUri && IconPool.isIconURI(sOldIconUri) != IconPool.isIconURI(sIconUri)) {
					var oPage = this.getAggregation("_page");

					oPage.removeContent(this._oIconControl);
					this._oIconControl.destroy();
					oPage.insertContent(this._getIconControl(), 0);
				} else {
					this._oIconControl.setSrc(sIconUri);
				}
			}
		};

		MessagePage.prototype._addPageContent = function() {
			var oPage = this.getAggregation("_page");

			if (this.getAggregation("customText")) {
				this._oText = this.getAggregation("customText");
			} else {
				this._oText = new sap.m.Text({
					text: this.getText(),
					textAlign: sap.ui.core.TextAlign.Center,
					textDirection: this.getTextDirection()
				});
			}

			if (this.getAggregation("customDescription")) {
				this._oDescription = this.getAggregation("customDescription");
			} else {
				this._oDescription = new sap.m.Text({
					text: this.getDescription(),
					textAlign: sap.ui.core.TextAlign.Center,
					textDirection: this.getTextDirection()
				});
			}

			oPage.addContent(this._getIconControl());
			oPage.addContent(this._oText.addStyleClass("sapMMessagePageMainText"));
			oPage.addContent(this._oDescription.addStyleClass("sapMMessagePageDescription"));
		};

		MessagePage.prototype._getIconControl = function() {
			this._oIconControl = IconPool.createControlByURI({
				id: this.getId() + "-pageIcon",
				src: this.getIcon(),
				height: "8rem"
			}, sap.m.Image).addStyleClass("sapMMessagePageIcon");

			return this._oIconControl;
		};

		/**
		 * Returns the internal header
		 * Adding this functions because they are needed by the SplitContainer logic to show the "hamburger" button.
		 * @private
		 * @returns {sap.m.IBar}
		 */
		MessagePage.prototype._getAnyHeader = function() {
			return this._getInternalHeader();
		};

		/**
		 * Adding this functions because they are needed by the SplitContainer logic to show the "hamburger" button.
		 * @returns {sap.m.IBar}
		 * @private
		 */

		MessagePage.prototype._getInternalHeader = function() {
			return this.getAggregation("_page").getAggregation("_internalHeader");
		};

		return MessagePage;
	}, /* bExport= */ true);
<|endoftext|>