<commit_before>/*eslint global-require: "off"*/
/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

function populateJoynrApi(joynr, api) {
    let key;
    for (key in api) {
        if (api.hasOwnProperty(key)) {
            joynr[key] = api[key];
        }
    }
}

function freeze(joynr, capabilitiesWritable) {
    Object.defineProperties(joynr, {
        messaging: {
            writable: false
        },
        types: {
            writable: false
        },
        start: {
            writable: false
        },
        shutdown: {
            writable: true
        },
        typeRegistry: {
            writable: false
        },
        capabilities: {
            writable: capabilitiesWritable === true
        },
        proxy: {
            writable: false
        },
        proxyBuilder: {
            writable: true
        },
        providerBuilder: {
            writable: false
        }
    });
}

const GenerationUtil = require("./joynr/util/GenerationUtil");

/**
 * @name joynr
 * @class
 */
const joynr = {
    loaded: false,
    /**
     * @name joynr#load
     * @function
     * @param provisioning
     * @param capabilitiesWriteable
     * @return Promise object being resolved in case all libjoynr dependencies are loaded
     */
    load: function load(provisioning, capabilitiesWritable) {
        joynr.loaded = true;
        const joynrapi = require("./libjoynr-deps");
        const runtime = new joynrapi.Runtime();
        return runtime
            .start(provisioning)
            .then(() => {
                populateJoynrApi(joynr, joynrapi);
                //remove Runtime, as it is not required for the end user
                delete joynr.Runtime;
                populateJoynrApi(joynr, runtime);
                freeze(joynr, capabilitiesWritable);

                // make sure the runtime is shutdown when process.exit(...)
                // gets called since otherwise the process might not
                // terminate. Ignore any exception thrown in case shutdown
                // had already been invoked manually before reaching this
                // point.
                if (typeof process === "object" && typeof process.on === "function") {
                    process.on("exit", () => {
                        try {
                            joynr.shutdown();
                        } catch (error) {
                            // ignore
                        }
                    });
                }
                return joynr;
            })
            .catch(error => {
                return Promise.reject(error);
            });
    },
    /**
     * Adds a typeName to constructor entry in the type registry.
     *
     * @name joynr#addType
     * @function
     * @see TypeRegistry#addType
     *
     * @param {String}
     *            joynrTypeName - the joynr type name that is sent on the wire.
     * @param {Function}
     *            typeConstructor - the corresponding JavaScript constructor for this type.
     * @param {boolean}
     *            isEnum - optional flag if the added type is an enumeration type
     */
    addType: function registerType(name, type, isEnum) {
        const TypeRegistrySingleton = require("./joynr/types/TypeRegistrySingleton");
        TypeRegistrySingleton.getInstance().addType(name, type, isEnum);
    },
    JoynrObject: function JoynrObject() {},
    util: { GenerationUtil }
};

if (typeof window === "object") {
    // export namespace fragment or module read-only to the parent namespace
    Object.defineProperty(window, "joynr", {
        enumerable: true,
        configurable: false,
        writable: false,
        value: joynr
    });
}

joynr.selectRuntime = function selectRuntime(runtime) {
    if (joynr.loaded) {
        throw new Error("joynr.selectRuntime: this method must be invoked before calling joynr.load()");
    }
    joynr._selectedRuntime = runtime;
};
joynr.selectRuntime("websocket.libjoynr");

if (module !== undefined && module.exports) {
    exports.joynr = module.exports = joynr;
} else {
    // support CommonJS module 1.1.1 spec (`exports` cannot be a function)
    exports.joynr = joynr;
}

/* jslint nomen: false */
<commit_msg>[JS] joynr.js wraps public Runtime methods only<commit_after>/*eslint global-require: "off"*/
/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

function populateJoynrApi(joynr, api) {
    let key;
    for (key in api) {
        if (api.hasOwnProperty(key)) {
            joynr[key] = api[key];
        }
    }
}

function freeze(joynr, capabilitiesWritable) {
    Object.defineProperties(joynr, {
        messaging: {
            writable: false
        },
        types: {
            writable: false
        },
        start: {
            writable: false
        },
        shutdown: {
            writable: true
        },
        typeRegistry: {
            writable: false
        },
        capabilities: {
            writable: capabilitiesWritable === true
        },
        proxy: {
            writable: false
        },
        proxyBuilder: {
            writable: true
        },
        providerBuilder: {
            writable: false
        }
    });
}

function wrapRuntime(joynr, runtime) {
    Object.keys(runtime).forEach(key => {
        if (!key.startsWith("_")) {
            if (typeof runtime[key] === "function") {
                joynr[key] = (...args) => runtime[key](...args);
            } else {
                joynr[key] = runtime[key];
            }
        }
    });
}

const GenerationUtil = require("./joynr/util/GenerationUtil");

/**
 * @name joynr
 * @class
 */
const joynr = {
    loaded: false,
    /**
     * @name joynr#load
     * @function
     * @param provisioning
     * @param capabilitiesWriteable
     * @return Promise object being resolved in case all libjoynr dependencies are loaded
     */
    load: function load(provisioning, capabilitiesWritable) {
        joynr.loaded = true;
        const joynrapi = require("./libjoynr-deps");
        const runtime = new joynrapi.Runtime();
        return runtime
            .start(provisioning)
            .then(() => {
                populateJoynrApi(joynr, joynrapi);
                //remove Runtime, as it is not required for the end user
                delete joynr.Runtime;
                wrapRuntime(joynr, runtime);
                freeze(joynr, capabilitiesWritable);

                // make sure the runtime is shutdown when process.exit(...)
                // gets called since otherwise the process might not
                // terminate. Ignore any exception thrown in case shutdown
                // had already been invoked manually before reaching this
                // point.
                if (typeof process === "object" && typeof process.on === "function") {
                    process.on("exit", () => {
                        try {
                            joynr.shutdown();
                        } catch (error) {
                            // ignore
                        }
                    });
                }
                return joynr;
            })
            .catch(error => {
                return Promise.reject(error);
            });
    },
    /**
     * Adds a typeName to constructor entry in the type registry.
     *
     * @name joynr#addType
     * @function
     * @see TypeRegistry#addType
     *
     * @param {String}
     *            joynrTypeName - the joynr type name that is sent on the wire.
     * @param {Function}
     *            typeConstructor - the corresponding JavaScript constructor for this type.
     * @param {boolean}
     *            isEnum - optional flag if the added type is an enumeration type
     */
    addType: function registerType(name, type, isEnum) {
        const TypeRegistrySingleton = require("./joynr/types/TypeRegistrySingleton");
        TypeRegistrySingleton.getInstance().addType(name, type, isEnum);
    },
    JoynrObject: function JoynrObject() {},
    util: { GenerationUtil }
};

if (typeof window === "object") {
    // export namespace fragment or module read-only to the parent namespace
    Object.defineProperty(window, "joynr", {
        enumerable: true,
        configurable: false,
        writable: false,
        value: joynr
    });
}

joynr.selectRuntime = function selectRuntime(runtime) {
    if (joynr.loaded) {
        throw new Error("joynr.selectRuntime: this method must be invoked before calling joynr.load()");
    }
    joynr._selectedRuntime = runtime;
};
joynr.selectRuntime("websocket.libjoynr");

if (module !== undefined && module.exports) {
    exports.joynr = module.exports = joynr;
} else {
    // support CommonJS module 1.1.1 spec (`exports` cannot be a function)
    exports.joynr = joynr;
}

/* jslint nomen: false */
<|endoftext|>


<commit_before>IonicModule
.controller('$ionSlideBox', [
  '$scope',
  '$element',
  '$$ionicAttachDrag',
  '$interval',
  '$rootScope',
  '$timeout',
function(scope, element, $$ionicAttachDrag, $interval, $rootScope, $timeout) {
  var self = this;

  var relevantSlides = {
    previous: null,
    selected: null,
    next: null
  };
  var oldRelevantSlides = relevantSlides;

  // This is a live nodeList that is updated whenever child ion-slides
  // are added or removed
  var slideNodes = element[0].getElementsByTagName('ion-slide');
  var slideList = ionic.Utils.list(slideNodes);

  var slidesParent = angular.element(element[0].querySelector('.slider-slides'));

  // Successful slide requires velocity to be greater than this amount
  var SLIDE_SUCCESS_VELOCITY = (1 / 4); // pixels / ms
  var SLIDE_TRANSITION_DURATION = 250; //ms

  $$ionicAttachDrag(scope, element, {
    getDistance: function() { return slidesParent.prop('offsetWidth'); },
    onDragStart: onDragStart,
    onDrag: onDrag,
    onDragEnd: onDragEnd
  });

  // At the very end of every digest, check if slides changed
  // This is because our nodes won't be added until after data has been processed
  // (eg you add a slide to data with ng-if, then the ng-if processes and the element
  // now exists)
  $rootScope.$watch(function() {
    if (!checkSlidesChanged.queued) {
      $rootScope.$$postDigest(checkSlidesChanged);
    }
    return true;
  });

  self.element = element;
  self.isRelevant = isRelevant;
  self.previous = previous;
  self.next = next;

  // Methods calling straight back to Utils.list
  self.at = at;
  self.count = slideList.count;
  self.indexOf = indexOf;
  self.isInRange = slideList.isInRange;
  self.loop = slideList.loop;
  self.delta = slideList.delta;

  self.enableSlide = enableSlide;
  self.autoPlay = autoPlay;
  self.selected = selected;
  self.select = select;
  self.onDragStart = onDragStart;
  self.onDrag = onDrag;
  self.onDragEnd = onDragEnd;

  /** DEPRECATED METHODS **/
  self.update = deprecated.method(
    '$ionicSlideBoxDelegate.update() has been deprecated! Slidebox updates on its own now.',
    console.warn,
    angular.noop
  );
  self.currentIndex = deprecated.method(
     '$ionicSlideBoxDelegate.currentIndex() has been deprecated! Use self.selected() instead.',
     console.warn,
     self.selected
  );
  self.slide = deprecated.method(
     '$ionicSlideBoxDelegate.slide(newIndex[, speed]) has been deprecated! Use self.select(newIndex[, speed]) instead.',
     console.warn,
     self.select
  );
  self.slidesCount = deprecated.method(
     '$ionicSlideBoxDelegate.slidesCount has been deprecated! Use self.slidesCount() instead.',
     console.warn,
     self.count
  );
  self.slidesCount =
  self.stop = deprecated.method(
    '$ionicSlideBoxDelegate.stop() has been deprecated! Use $ionicSlideBoxDelegate.autoPlay(0) to stop instead.',
    console.warn,
    function() {
      self._stoppedInterval = self.autoPlayInterval;
      self.autoPlay(0);
    }
  );
  self.start = deprecated.method(
    '$ionicSlideBoxDelegate.start() has been deprecated! Use $ionicSlideBoxDelegate.autoPlay(newInterval) to start instead.',
    console.warn,
    function() {
      self.autoPlay(self._stoppedInterval);
    }
  );

  // ***
  // Public Methods
  // ***
  function at(index) {
    return jqLite( slideList.at(index) ).controller('ionSlide');
  }

  function indexOf(slide) {
    return slide && slideList.indexOf(slide.node) || -1;
  }

  // Gets whether the given index is relevant to selected
  // That is, whether the given index is previous, selected, or next
  function isRelevant(index) {
    return slideList.isRelevant(index, scope.selectedIndex);
  }

  // Gets the index to the previous of the given slide, default scope.selectedIndex
  function previous(index) {
    index = arguments.length ? index : scope.selectedIndex;
    // If we only have two slides and loop is enabled, we cannot have a previous
    // because previous === next. In this case, return -1.
    if (self.loop() && self.count() === 2) {
      return -1;
    }
    return slideList.previous(index);
  }

  // Gets the index to the next of the given slide, default scope.selectedIndex
  function next(index) {
    index = arguments.length ? index : scope.selectedIndex;
    return slideList.next(index);
  }

  function enableSlide(isEnabled) {
    if (arguments.length) {
      self.dragDisabled = !isEnabled;
    }
    return !!self.dragDisabled;
  }

  function autoPlay(newInterval) {
    self.autoPlayInterval = newInterval;
    $interval.cancel(self.autoPlayTimeout);

    if (angular.isNumber(newInterval) && newInterval > 0) {
      self.autoPlayTimeout = $interval(function() {
        self.select(self.next());
      }, newInterval);
    }
  }

  function selected() {
    return self.isInRange(scope.selectedIndex) ? scope.selectedIndex : -1;
  }

  /*
   * Select and change slides
   */
  function select(newIndex, transitionDuration, force) {
    if (!self.isInRange(newIndex)) return;

    scope.selectedIndex = newIndex;

    oldRelevantSlides = relevantSlides;
    relevantSlides = {
      previous: self.at(self.previous()),
      selected: self.at(newIndex),
      next: self.at(self.next())
    };

    if (!force &&
        oldRelevantSlides.next === relevantSlides.next &&
        oldRelevantSlides.previous === relevantSlides.previous &&
        oldRelevantSlides.selected === relevantSlides.selected) {
      // do nothing;
      return;
    }

    slidesParent.css(
      ionic.CSS.TRANSITION_DURATION,
      (transitionDuration || SLIDE_TRANSITION_DURATION) + 'ms'
    );

    var delta = self.delta(scope.selectedIndex, newIndex);
    if (self.isInRange(scope.selectedIndex) && Math.abs(delta) > 1) {
      // if the new slide is > 1 away, then it is currently not attached to the DOM.
      // Attach it in the position from which it will slide in.
      self.at(newIndex).setState(delta > 1 ? 'next' : 'previous');
      // Wait one frame so the new slide can 'settle' in its new place and
      // be ready to properly transition in
      ionic.requestAnimationFrame(doSelect);
    } else {
      doSelect();
    }

    function doSelect() {
      // If a new selection has happened before this frame, abort.
      if (scope.selectedIndex !== newIndex) return;
      scope.$evalAsync(function() {
        if (scope.selectedIndex !== newIndex) return;
        arrangeSlides(newIndex);
      });
    }
  }

  function onDragStart() {
    if (self.dragDisabled) return false;
  }

  // percent is negative 0-1 for backward slide
  // positive 0-1 for forward slide
  function onDrag(percent) {
    var target = self.at(percent > 0 ? self.next() : self.previous());
    var current = self.at(self.selected());

    target && target.transform(percent);
    current && current.transform(percent);
  }

  function onDragEnd(percent, velocity) {
    var nextIndex = -1;
    if (Math.abs(percent) > 0.5 || velocity > SLIDE_SUCCESS_VELOCITY) {
      nextIndex = percent > 0 ? self.next() : self.previous();
    }

    // Select a new slide if it's avaiable
    if (self.isInRange(nextIndex)) {
      var distanceRemaining = (1 - Math.abs(percent)) * slidesParent.prop('offsetWidth');
      var transitionDuration = Math.min(
        distanceRemaining / velocity,
        SLIDE_TRANSITION_DURATION
      );
      self.select(nextIndex, transitionDuration);
    } else {
      self.select(scope.selectedIndex, 0, true);
    }
  }

  // ***
  // Private Methods
  // ***

  function checkSlidesChanged() {
    checkSlidesChanged.queued = false;

    // If one of the child nodes was destroyed but not yet removed
    // from the DOM, we'll enqueue a new digest to re-check
    // once the element is actually removed.
    var slideScope;
    for (var i = 0; i < slideNodes.length; i++) {
      if ( (slideScope = angular.element(slideNodes[i]).scope()) && slideScope.$$destroyed) {
        $timeout(angular.noop);
        break;
      }
    }

    if (!relevantSlides.selected) {
      if (!angular.isNumber(scope.selectedIndex) || scope.selectedIndex === -1) {
        self.select(0);
      } else if (self.isInRange(scope.selectedIndex)) {
        // If we are waiting for a certain scope.selectedIndex that isn't yet selected, select it now.
        self.select(scope.selectedIndex);
      }

    } else if (relevantSlides.selected !== self.at(scope.selectedIndex) ||
               relevantSlides.next !== self.next() ||
               relevantSlides.previous !== self.previous()) {
      // If the next, previous, or selected item has been moved or removed,
      // find what to reselect.
      var newIndex = self.indexOf(relevantSlides.selected);
      if (newIndex === -1) {
        // If the selected slide was removed, try to select the nearest available slide
        self.select(scope.selectedIndex > 0 ? scope.selectedIndex - 1 : scope.selectedIndex);
      } else {
        // Else, reselect the selected slide.
        self.select(newIndex);
      }
    }

  }

  function arrangeSlides() {
    relevantSlides.previous && relevantSlides.previous.setState('previous');
    relevantSlides.selected && relevantSlides.selected.setState('selected');
    relevantSlides.next && relevantSlides.next.setState('next');

    if (oldRelevantSlides) {
      var oldShown = oldRelevantSlides.selected;
      var delta = self.delta(self.indexOf(oldRelevantSlides.selected), self.indexOf(relevantSlides.selected));
      if (Math.abs(delta) > 1) {
        // If we're changing by more than one slide, we need to manually transition
        // the current slide out and then put it into its new state.
        oldShown.setState(delta > 1 ? 'previous' : 'next').then(function() {
          oldShown.setState(
            relevantSlides.previous === oldShown ?  'previous' :
            relevantSlides.next === oldShown ? 'next' :
            'detached'
          );
        });
      } else {
        detachIfUnused(oldRelevantSlides.selected);
      }
      //Additionally, we need to detach both of the old slides.
      detachIfUnused(oldRelevantSlides.previous);
      detachIfUnused(oldRelevantSlides.next);
    }

    function detachIfUnused(oldSlide) {
      if (oldSlide && oldSlide !== relevantSlides.previous &&
          oldSlide !== relevantSlides.selected &&
          oldSlide !== relevantSlides.next) {
        oldSlide.setState('detached');
      }
    }
  }

}]);
<commit_msg>chore(slideBox): remove extra deprecated slidesCount<commit_after>IonicModule
.controller('$ionSlideBox', [
  '$scope',
  '$element',
  '$$ionicAttachDrag',
  '$interval',
  '$rootScope',
  '$timeout',
function(scope, element, $$ionicAttachDrag, $interval, $rootScope, $timeout) {
  var self = this;

  var relevantSlides = {
    previous: null,
    selected: null,
    next: null
  };
  var oldRelevantSlides = relevantSlides;

  // This is a live nodeList that is updated whenever child ion-slides
  // are added or removed
  var slideNodes = element[0].getElementsByTagName('ion-slide');
  var slideList = ionic.Utils.list(slideNodes);

  var slidesParent = angular.element(element[0].querySelector('.slider-slides'));

  // Successful slide requires velocity to be greater than this amount
  var SLIDE_SUCCESS_VELOCITY = (1 / 4); // pixels / ms
  var SLIDE_TRANSITION_DURATION = 250; //ms

  $$ionicAttachDrag(scope, element, {
    getDistance: function() { return slidesParent.prop('offsetWidth'); },
    onDragStart: onDragStart,
    onDrag: onDrag,
    onDragEnd: onDragEnd
  });

  // At the very end of every digest, check if slides changed
  // This is because our nodes won't be added until after data has been processed
  // (eg you add a slide to data with ng-if, then the ng-if processes and the element
  // now exists)
  $rootScope.$watch(function() {
    if (!checkSlidesChanged.queued) {
      $rootScope.$$postDigest(checkSlidesChanged);
    }
    return true;
  });

  self.element = element;
  self.isRelevant = isRelevant;
  self.previous = previous;
  self.next = next;

  // Methods calling straight back to Utils.list
  self.at = at;
  self.count = slideList.count;
  self.indexOf = indexOf;
  self.isInRange = slideList.isInRange;
  self.loop = slideList.loop;
  self.delta = slideList.delta;

  self.enableSlide = enableSlide;
  self.autoPlay = autoPlay;
  self.selected = selected;
  self.select = select;
  self.onDragStart = onDragStart;
  self.onDrag = onDrag;
  self.onDragEnd = onDragEnd;

  /** DEPRECATED METHODS **/
  self.update = deprecated.method(
    '$ionicSlideBoxDelegate.update() has been deprecated! Slidebox updates on its own now.',
    console.warn,
    angular.noop
  );
  self.currentIndex = deprecated.method(
     '$ionicSlideBoxDelegate.currentIndex() has been deprecated! Use self.selected() instead.',
     console.warn,
     self.selected
  );
  self.slide = deprecated.method(
     '$ionicSlideBoxDelegate.slide(newIndex[, speed]) has been deprecated! Use self.select(newIndex[, speed]) instead.',
     console.warn,
     self.select
  );
  self.slidesCount = deprecated.method(
     '$ionicSlideBoxDelegate.slidesCount has been deprecated! Use self.slidesCount() instead.',
     console.warn,
     self.count
  );
  self.stop = deprecated.method(
    '$ionicSlideBoxDelegate.stop() has been deprecated! Use $ionicSlideBoxDelegate.autoPlay(0) to stop instead.',
    console.warn,
    function() {
      self._stoppedInterval = self.autoPlayInterval;
      self.autoPlay(0);
    }
  );
  self.start = deprecated.method(
    '$ionicSlideBoxDelegate.start() has been deprecated! Use $ionicSlideBoxDelegate.autoPlay(newInterval) to start instead.',
    console.warn,
    function() {
      self.autoPlay(self._stoppedInterval);
    }
  );

  // ***
  // Public Methods
  // ***
  function at(index) {
    return jqLite( slideList.at(index) ).controller('ionSlide');
  }

  function indexOf(slide) {
    return slide && slideList.indexOf(slide.node) || -1;
  }

  // Gets whether the given index is relevant to selected
  // That is, whether the given index is previous, selected, or next
  function isRelevant(index) {
    return slideList.isRelevant(index, scope.selectedIndex);
  }

  // Gets the index to the previous of the given slide, default scope.selectedIndex
  function previous(index) {
    index = arguments.length ? index : scope.selectedIndex;
    // If we only have two slides and loop is enabled, we cannot have a previous
    // because previous === next. In this case, return -1.
    if (self.loop() && self.count() === 2) {
      return -1;
    }
    return slideList.previous(index);
  }

  // Gets the index to the next of the given slide, default scope.selectedIndex
  function next(index) {
    index = arguments.length ? index : scope.selectedIndex;
    return slideList.next(index);
  }

  function enableSlide(isEnabled) {
    if (arguments.length) {
      self.dragDisabled = !isEnabled;
    }
    return !!self.dragDisabled;
  }

  function autoPlay(newInterval) {
    self.autoPlayInterval = newInterval;
    $interval.cancel(self.autoPlayTimeout);

    if (angular.isNumber(newInterval) && newInterval > 0) {
      self.autoPlayTimeout = $interval(function() {
        self.select(self.next());
      }, newInterval);
    }
  }

  function selected() {
    return self.isInRange(scope.selectedIndex) ? scope.selectedIndex : -1;
  }

  /*
   * Select and change slides
   */
  function select(newIndex, transitionDuration, force) {
    if (!self.isInRange(newIndex)) return;

    scope.selectedIndex = newIndex;

    oldRelevantSlides = relevantSlides;
    relevantSlides = {
      previous: self.at(self.previous()),
      selected: self.at(newIndex),
      next: self.at(self.next())
    };

    if (!force &&
        oldRelevantSlides.next === relevantSlides.next &&
        oldRelevantSlides.previous === relevantSlides.previous &&
        oldRelevantSlides.selected === relevantSlides.selected) {
      // do nothing;
      return;
    }

    slidesParent.css(
      ionic.CSS.TRANSITION_DURATION,
      (transitionDuration || SLIDE_TRANSITION_DURATION) + 'ms'
    );

    var delta = self.delta(scope.selectedIndex, newIndex);
    if (self.isInRange(scope.selectedIndex) && Math.abs(delta) > 1) {
      // if the new slide is > 1 away, then it is currently not attached to the DOM.
      // Attach it in the position from which it will slide in.
      self.at(newIndex).setState(delta > 1 ? 'next' : 'previous');
      // Wait one frame so the new slide can 'settle' in its new place and
      // be ready to properly transition in
      ionic.requestAnimationFrame(doSelect);
    } else {
      doSelect();
    }

    function doSelect() {
      // If a new selection has happened before this frame, abort.
      if (scope.selectedIndex !== newIndex) return;
      scope.$evalAsync(function() {
        if (scope.selectedIndex !== newIndex) return;
        arrangeSlides(newIndex);
      });
    }
  }

  function onDragStart() {
    if (self.dragDisabled) return false;
  }

  // percent is negative 0-1 for backward slide
  // positive 0-1 for forward slide
  function onDrag(percent) {
    var target = self.at(percent > 0 ? self.next() : self.previous());
    var current = self.at(self.selected());

    target && target.transform(percent);
    current && current.transform(percent);
  }

  function onDragEnd(percent, velocity) {
    var nextIndex = -1;
    if (Math.abs(percent) > 0.5 || velocity > SLIDE_SUCCESS_VELOCITY) {
      nextIndex = percent > 0 ? self.next() : self.previous();
    }

    // Select a new slide if it's avaiable
    if (self.isInRange(nextIndex)) {
      var distanceRemaining = (1 - Math.abs(percent)) * slidesParent.prop('offsetWidth');
      var transitionDuration = Math.min(
        distanceRemaining / velocity,
        SLIDE_TRANSITION_DURATION
      );
      self.select(nextIndex, transitionDuration);
    } else {
      self.select(scope.selectedIndex, 0, true);
    }
  }

  // ***
  // Private Methods
  // ***

  function checkSlidesChanged() {
    checkSlidesChanged.queued = false;

    // If one of the child nodes was destroyed but not yet removed
    // from the DOM, we'll enqueue a new digest to re-check
    // once the element is actually removed.
    var slideScope;
    for (var i = 0; i < slideNodes.length; i++) {
      if ( (slideScope = angular.element(slideNodes[i]).scope()) && slideScope.$$destroyed) {
        $timeout(angular.noop);
        break;
      }
    }

    if (!relevantSlides.selected) {
      if (!angular.isNumber(scope.selectedIndex) || scope.selectedIndex === -1) {
        self.select(0);
      } else if (self.isInRange(scope.selectedIndex)) {
        // If we are waiting for a certain scope.selectedIndex that isn't yet selected, select it now.
        self.select(scope.selectedIndex);
      }

    } else if (relevantSlides.selected !== self.at(scope.selectedIndex) ||
               relevantSlides.next !== self.next() ||
               relevantSlides.previous !== self.previous()) {
      // If the next, previous, or selected item has been moved or removed,
      // find what to reselect.
      var newIndex = self.indexOf(relevantSlides.selected);
      if (newIndex === -1) {
        // If the selected slide was removed, try to select the nearest available slide
        self.select(scope.selectedIndex > 0 ? scope.selectedIndex - 1 : scope.selectedIndex);
      } else {
        // Else, reselect the selected slide.
        self.select(newIndex);
      }
    }

  }

  function arrangeSlides() {
    relevantSlides.previous && relevantSlides.previous.setState('previous');
    relevantSlides.selected && relevantSlides.selected.setState('selected');
    relevantSlides.next && relevantSlides.next.setState('next');

    if (oldRelevantSlides) {
      var oldShown = oldRelevantSlides.selected;
      var delta = self.delta(self.indexOf(oldRelevantSlides.selected), self.indexOf(relevantSlides.selected));
      if (Math.abs(delta) > 1) {
        // If we're changing by more than one slide, we need to manually transition
        // the current slide out and then put it into its new state.
        oldShown.setState(delta > 1 ? 'previous' : 'next').then(function() {
          oldShown.setState(
            relevantSlides.previous === oldShown ?  'previous' :
            relevantSlides.next === oldShown ? 'next' :
            'detached'
          );
        });
      } else {
        detachIfUnused(oldRelevantSlides.selected);
      }
      //Additionally, we need to detach both of the old slides.
      detachIfUnused(oldRelevantSlides.previous);
      detachIfUnused(oldRelevantSlides.next);
    }

    function detachIfUnused(oldSlide) {
      if (oldSlide && oldSlide !== relevantSlides.previous &&
          oldSlide !== relevantSlides.selected &&
          oldSlide !== relevantSlides.next) {
        oldSlide.setState('detached');
      }
    }
  }

}]);
<|endoftext|>


<commit_before>angular.module('ionic.ui.tabs', ['ionic.service.view', 'ngSanitize'])

/**
 * @description
 *
 * The Tab Controller renders a set of pages that switch based on taps
 * on a tab bar. Modelled off of UITabBarController.
 */

.run(['$ionicViewService', function($ionicViewService) {
  // set that the tabs directive should not animate when transitioning
  // to it. Instead, the children <ion-tab> directives would animate
  $ionicViewService.disableRegisterByTagName('tabs');
}])

.controller('$ionicTabs', ['$scope', '$ionicViewService', function($scope, $ionicViewService) {
  var _this = this;

  $scope.tabCount = 0;
  $scope.selectedIndex = -1;
  $scope.$enableViewRegister = false;

  angular.extend(this, ionic.controllers.TabBarController.prototype);

  ionic.controllers.TabBarController.call(this, {
    controllerChanged: function(oldC, oldI, newC, newI) {
      $scope.controllerChanged && $scope.controllerChanged({
        oldController: oldC,
        oldIndex: oldI,
        newController: newC,
        newIndex: newI
      });
    },
    tabBar: {
      tryTabSelect: function() {},
      setSelectedItem: function(index) {},
      addItem: function(item) {}
    }
  });

  this.add = function(tabScope) {
    tabScope.tabIndex = $scope.tabCount;
    this.addController(tabScope);
    if(tabScope.tabIndex === 0) {
      this.select(0);
    }
    $scope.tabCount++;
  };

  function controllerByTabIndex(tabIndex) {
    for (var x=0; x<_this.controllers.length; x++) {
      if (_this.controllers[x].tabIndex === tabIndex) {
        return _this.controllers[x];
      }
    }
  }

  this.select = function(tabIndex, emitChange) {
    if(tabIndex !== $scope.selectedIndex) {

      $scope.selectedIndex = tabIndex;
      $scope.activeAnimation = $scope.animation;
      _this.selectController(tabIndex);

      var viewData = {
        type: 'tab',
        typeIndex: tabIndex
      };

      var tabController = controllerByTabIndex(tabIndex);
      if (tabController) {
        viewData.title = tabController.title;
        viewData.historyId = tabController.$historyId;
        viewData.url = tabController.url;
        viewData.uiSref = tabController.viewSref;
        viewData.navViewName = tabController.navViewName;
        viewData.hasNavView = tabController.hasNavView;
      }

      if(emitChange) {
        $scope.$emit('viewState.changeHistory', viewData);
      }
    } else if(emitChange) {
      var currentView = $ionicViewService.getCurrentView();
      if (currentView) {
        $ionicViewService.goToHistoryRoot(currentView.historyId);
      }
    }
  };

  $scope.controllers = this.controllers;

  $scope.tabsController = this;

}])

.directive('ionTabs', ['$ionicViewService', function($ionicViewService) {
  return {
    restrict: 'E',
    replace: true,
    scope: true,
    transclude: true,
    controller: '$ionicTabs',
    template: '
<ion-tab-controller-bar></ion-tab-controller-bar>
',
    compile: function(element, attr, transclude, tabsCtrl) {
      return function link($scope, $element, $attr) {

        var tabs = $element[0].querySelector('.tabs');

        $scope.tabsType = $attr.tabsType || 'tabs-positive';
        $scope.tabsStyle = $attr.tabsStyle;
        $scope.animation = $attr.animation;

        $scope.animateNav = $scope.$eval($attr.animateNav);
        if($scope.animateNav !== false) {
          $scope.animateNav = true;
        }

        $attr.$observe('tabsStyle', function(val) {
          if(tabs) {
            angular.element(tabs).addClass($attr.tabsStyle);
          }
        });

        $attr.$observe('tabsType', function(val) {
          if(tabs) {
            angular.element(tabs).addClass($attr.tabsType);
          }
        });

        $scope.$watch('activeAnimation', function(value) {
          $element.addClass($scope.activeAnimation);
        });
        transclude($scope, function(cloned) {
          $element.prepend(cloned);
        });

      };
    }
  };
}])

// Generic controller directive
.directive('ionTab', ['$ionicViewService', '$rootScope', '$parse', '$interpolate', function($ionicViewService, $rootScope, $parse, $interpolate) {
  return {
    restrict: 'E',
    require: '^ionTabs',
    scope: true,
    transclude: 'element',
    compile: function(element, attr, transclude) {

      return function link($scope, $element, $attr, tabsCtrl) {
        var childScope, childElement;

        $ionicViewService.registerHistory($scope);

        $scope.title = $attr.title;
        $scope.icon = $attr.icon;
        $scope.iconOn = $attr.iconOn;
        $scope.iconOff = $attr.iconOff;
        $scope.viewSref = $attr.uiSref;
        $scope.url = $attr.href;
        if($scope.url && $scope.url.indexOf('#') === 0) {
          $scope.url = $scope.url.replace('#', '');
        }

        // Should we hide a back button when this tab is shown
        $scope.hideBackButton = $scope.$eval($attr.hideBackButton);

        if($scope.hideBackButton !== true) {
          $scope.hideBackButton = false;
        }

        // Whether we should animate on tab change, also impacts whether we
        // tell any parent nav controller to animate
        $scope.animate = $scope.$eval($attr.animate);

        var badgeGet = $parse($attr.badge);
        $scope.$watch(badgeGet, function(value) {
          $scope.badge = value;
        });

        $attr.$observe('badgeStyle', function(value) {
          $scope.badgeStyle = value;
        });

        var leftButtonsGet = $parse($attr.leftButtons);
        $scope.$watch(leftButtonsGet, function(value) {
          $scope.leftButtons = value;
          if($scope.doesUpdateNavRouter) {
            $scope.$emit('viewState.leftButtonsChanged', $scope.rightButtons);
          }
        });

        var rightButtonsGet = $parse($attr.rightButtons);
        $scope.$watch(rightButtonsGet, function(value) {
          $scope.rightButtons = value;
        });

        tabsCtrl.add($scope);

        function cleanupChild() {
          if(childElement) {
            childElement.remove();
            childElement = null;
          }
          if(childScope) {
            childScope.$destroy();
            childScope = null;
          }
        }

        $scope.$watch('isVisible', function(value) {
          if (value) {
            cleanupChild();
            childScope = $scope.$new();
            transclude(childScope, function(clone) {
              clone.addClass('pane');
              clone.removeAttr('title');
              childElement = clone;
              $element.parent().append(childElement);
            });
            $scope.$broadcast('tab.shown');
          } else if (childScope) {
            $scope.$broadcast('tab.hidden');
            cleanupChild();
          }
        });

        // on link, check if it has a nav-view in it
        transclude($scope.$new(), function(clone) {
          var navViewEle = clone[0].getElementsByTagName("ion-nav-view");
          $scope.hasNavView = (navViewEle.length > 0);
          if($scope.hasNavView) {
            // this tab has a ui-view
            $scope.navViewName = navViewEle[0].getAttribute('name');
            if( $ionicViewService.isCurrentStateNavView( $scope.navViewName ) ) {
              // this tab's ui-view is the current one, go to it!
              tabsCtrl.select($scope.tabIndex);
            }
          }
        });

        var unregister = $rootScope.$on('$stateChangeSuccess', function(value){
          if( $ionicViewService.isCurrentStateNavView($scope.navViewName) &&
              $scope.tabIndex !== tabsCtrl.selectedIndex) {
            tabsCtrl.select($scope.tabIndex);
          }
        });

        $scope.$on('$destroy', unregister);

      };
    }
  };
}])

.directive('ionTabControllerBar', function() {
  return {
    restrict: 'E',
    require: '^ionTabs',
    transclude: true,
    replace: true,
    scope: true,
    template: '
' +
      '<ion-tab-controller-item icon-title="{{c.title}}" icon="{{c.icon}}" icon-on="{{c.iconOn}}" icon-off="{{c.iconOff}}" badge="c.badge" badge-style="c.badgeStyle" active="c.isVisible" index="$index" ng-repeat="c in controllers"></ion-tab-controller-item>' +
    '
',
    link: function($scope, $element, $attr, tabsCtrl) {
      $element.addClass($scope.tabsType);
      $element.addClass($scope.tabsStyle);
    }
  };
})

.directive('ionTabControllerItem', ['$window', function($window) {
  return {
    restrict: 'E',
    replace: true,
    require: '^ionTabs',
    scope: {
      iconTitle: '@',
      icon: '@',
      iconOn: '@',
      iconOff: '@',
      badge: '=',
      badgeStyle: '=',
      active: '=',
      tabSelected: '@',
      index: '='
    },
    link: function(scope, element, attrs, tabsCtrl) {
      if(attrs.icon) {
        scope.iconOn = scope.iconOff = attrs.icon;
      }

      scope.selectTab = function() {
        tabsCtrl.select(scope.index, true);
      };
    },
    template:
      '' +
        '{{badge}}' +
        '' +
        '' +
        '' +
        '' +
      ''
  };
}]);

<commit_msg>use .view instead of .pane, for no translate3d, for tab directive<commit_after>angular.module('ionic.ui.tabs', ['ionic.service.view', 'ngSanitize'])

/**
 * @description
 *
 * The Tab Controller renders a set of pages that switch based on taps
 * on a tab bar. Modelled off of UITabBarController.
 */

.run(['$ionicViewService', function($ionicViewService) {
  // set that the tabs directive should not animate when transitioning
  // to it. Instead, the children <ion-tab> directives would animate
  $ionicViewService.disableRegisterByTagName('tabs');
}])

.controller('$ionicTabs', ['$scope', '$ionicViewService', function($scope, $ionicViewService) {
  var _this = this;

  $scope.tabCount = 0;
  $scope.selectedIndex = -1;
  $scope.$enableViewRegister = false;

  angular.extend(this, ionic.controllers.TabBarController.prototype);

  ionic.controllers.TabBarController.call(this, {
    controllerChanged: function(oldC, oldI, newC, newI) {
      $scope.controllerChanged && $scope.controllerChanged({
        oldController: oldC,
        oldIndex: oldI,
        newController: newC,
        newIndex: newI
      });
    },
    tabBar: {
      tryTabSelect: function() {},
      setSelectedItem: function(index) {},
      addItem: function(item) {}
    }
  });

  this.add = function(tabScope) {
    tabScope.tabIndex = $scope.tabCount;
    this.addController(tabScope);
    if(tabScope.tabIndex === 0) {
      this.select(0);
    }
    $scope.tabCount++;
  };

  function controllerByTabIndex(tabIndex) {
    for (var x=0; x<_this.controllers.length; x++) {
      if (_this.controllers[x].tabIndex === tabIndex) {
        return _this.controllers[x];
      }
    }
  }

  this.select = function(tabIndex, emitChange) {
    if(tabIndex !== $scope.selectedIndex) {

      $scope.selectedIndex = tabIndex;
      $scope.activeAnimation = $scope.animation;
      _this.selectController(tabIndex);

      var viewData = {
        type: 'tab',
        typeIndex: tabIndex
      };

      var tabController = controllerByTabIndex(tabIndex);
      if (tabController) {
        viewData.title = tabController.title;
        viewData.historyId = tabController.$historyId;
        viewData.url = tabController.url;
        viewData.uiSref = tabController.viewSref;
        viewData.navViewName = tabController.navViewName;
        viewData.hasNavView = tabController.hasNavView;
      }

      if(emitChange) {
        $scope.$emit('viewState.changeHistory', viewData);
      }
    } else if(emitChange) {
      var currentView = $ionicViewService.getCurrentView();
      if (currentView) {
        $ionicViewService.goToHistoryRoot(currentView.historyId);
      }
    }
  };

  $scope.controllers = this.controllers;

  $scope.tabsController = this;

}])

.directive('ionTabs', ['$ionicViewService', function($ionicViewService) {
  return {
    restrict: 'E',
    replace: true,
    scope: true,
    transclude: true,
    controller: '$ionicTabs',
    template: '
<ion-tab-controller-bar></ion-tab-controller-bar>
',
    compile: function(element, attr, transclude, tabsCtrl) {
      return function link($scope, $element, $attr) {

        var tabs = $element[0].querySelector('.tabs');

        $scope.tabsType = $attr.tabsType || 'tabs-positive';
        $scope.tabsStyle = $attr.tabsStyle;
        $scope.animation = $attr.animation;

        $scope.animateNav = $scope.$eval($attr.animateNav);
        if($scope.animateNav !== false) {
          $scope.animateNav = true;
        }

        $attr.$observe('tabsStyle', function(val) {
          if(tabs) {
            angular.element(tabs).addClass($attr.tabsStyle);
          }
        });

        $attr.$observe('tabsType', function(val) {
          if(tabs) {
            angular.element(tabs).addClass($attr.tabsType);
          }
        });

        $scope.$watch('activeAnimation', function(value) {
          $element.addClass($scope.activeAnimation);
        });
        transclude($scope, function(cloned) {
          $element.prepend(cloned);
        });

      };
    }
  };
}])

// Generic controller directive
.directive('ionTab', ['$ionicViewService', '$rootScope', '$parse', '$interpolate', function($ionicViewService, $rootScope, $parse, $interpolate) {
  return {
    restrict: 'E',
    require: '^ionTabs',
    scope: true,
    transclude: 'element',
    compile: function(element, attr, transclude) {

      return function link($scope, $element, $attr, tabsCtrl) {
        var childScope, childElement;

        $ionicViewService.registerHistory($scope);

        $scope.title = $attr.title;
        $scope.icon = $attr.icon;
        $scope.iconOn = $attr.iconOn;
        $scope.iconOff = $attr.iconOff;
        $scope.viewSref = $attr.uiSref;
        $scope.url = $attr.href;
        if($scope.url && $scope.url.indexOf('#') === 0) {
          $scope.url = $scope.url.replace('#', '');
        }

        // Should we hide a back button when this tab is shown
        $scope.hideBackButton = $scope.$eval($attr.hideBackButton);

        if($scope.hideBackButton !== true) {
          $scope.hideBackButton = false;
        }

        // Whether we should animate on tab change, also impacts whether we
        // tell any parent nav controller to animate
        $scope.animate = $scope.$eval($attr.animate);

        var badgeGet = $parse($attr.badge);
        $scope.$watch(badgeGet, function(value) {
          $scope.badge = value;
        });

        $attr.$observe('badgeStyle', function(value) {
          $scope.badgeStyle = value;
        });

        var leftButtonsGet = $parse($attr.leftButtons);
        $scope.$watch(leftButtonsGet, function(value) {
          $scope.leftButtons = value;
          if($scope.doesUpdateNavRouter) {
            $scope.$emit('viewState.leftButtonsChanged', $scope.rightButtons);
          }
        });

        var rightButtonsGet = $parse($attr.rightButtons);
        $scope.$watch(rightButtonsGet, function(value) {
          $scope.rightButtons = value;
        });

        tabsCtrl.add($scope);

        function cleanupChild() {
          if(childElement) {
            childElement.remove();
            childElement = null;
          }
          if(childScope) {
            childScope.$destroy();
            childScope = null;
          }
        }

        $scope.$watch('isVisible', function(value) {
          if (value) {
            cleanupChild();
            childScope = $scope.$new();
            transclude(childScope, function(clone) {
              clone.addClass('view');
              clone.removeAttr('title');
              childElement = clone;
              $element.parent().append(childElement);
            });
            $scope.$broadcast('tab.shown');
          } else if (childScope) {
            $scope.$broadcast('tab.hidden');
            cleanupChild();
          }
        });

        // on link, check if it has a nav-view in it
        transclude($scope.$new(), function(clone) {
          var navViewEle = clone[0].getElementsByTagName("ion-nav-view");
          $scope.hasNavView = (navViewEle.length > 0);
          if($scope.hasNavView) {
            // this tab has a ui-view
            $scope.navViewName = navViewEle[0].getAttribute('name');
            if( $ionicViewService.isCurrentStateNavView( $scope.navViewName ) ) {
              // this tab's ui-view is the current one, go to it!
              tabsCtrl.select($scope.tabIndex);
            }
          }
        });

        var unregister = $rootScope.$on('$stateChangeSuccess', function(value){
          if( $ionicViewService.isCurrentStateNavView($scope.navViewName) &&
              $scope.tabIndex !== tabsCtrl.selectedIndex) {
            tabsCtrl.select($scope.tabIndex);
          }
        });

        $scope.$on('$destroy', unregister);

      };
    }
  };
}])

.directive('ionTabControllerBar', function() {
  return {
    restrict: 'E',
    require: '^ionTabs',
    transclude: true,
    replace: true,
    scope: true,
    template: '
' +
      '<ion-tab-controller-item icon-title="{{c.title}}" icon="{{c.icon}}" icon-on="{{c.iconOn}}" icon-off="{{c.iconOff}}" badge="c.badge" badge-style="c.badgeStyle" active="c.isVisible" index="$index" ng-repeat="c in controllers"></ion-tab-controller-item>' +
    '
',
    link: function($scope, $element, $attr, tabsCtrl) {
      $element.addClass($scope.tabsType);
      $element.addClass($scope.tabsStyle);
    }
  };
})

.directive('ionTabControllerItem', ['$window', function($window) {
  return {
    restrict: 'E',
    replace: true,
    require: '^ionTabs',
    scope: {
      iconTitle: '@',
      icon: '@',
      iconOn: '@',
      iconOff: '@',
      badge: '=',
      badgeStyle: '=',
      active: '=',
      tabSelected: '@',
      index: '='
    },
    link: function(scope, element, attrs, tabsCtrl) {
      if(attrs.icon) {
        scope.iconOn = scope.iconOff = attrs.icon;
      }

      scope.selectTab = function() {
        tabsCtrl.select(scope.index, true);
      };
    },
    template:
      '' +
        '{{badge}}' +
        '' +
        '' +
        '' +
        '' +
      ''
  };
}]);

<|endoftext|>


<commit_before>// View model for the page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetNameRapport");}, gvm);
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("HomeRapportTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetRapportManual");}, gvm);

    gvm.availableCourses = ko.observableArray([]);

    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);
    gvm.tabledata = ko.observableArray([]);

     // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.currentCourseId = null;

    gvm.updateCourseRapport = function() {
        $.getJSON('api/coursefromteacher/' + gvm.userId, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    $(".btn-courseRapport span:first").text($(this).text());
                    loadTablePage(1);
                });
            });
        });
    };

    gvm.addTableData = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.tabledata.push(tblOject);

        $('#removebtn-' + id).bind('click', function(event, data){
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        $('#editbtn-' + id).bind('click', function(event, data){
            showEditWorksheetModal(id, name);
            event.stopPropagation();
        });

        $('#copybtn-' + id).bind('click', function(event, data){
            copyTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function addNewWorksheet(serialData, courseid, callback) {
    $.ajax({
        url: "/api/addworksheet/" + courseid,
        type: "POST",
        data: serialData,
        success: function(data) {
            callback(true);
            window.location = "/api/worksheet/" + data['id'] + "/" + data['name'] + '/' + courseid;
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateWorksheet(id, serialData, callback) {
    $.ajax({
        url: "/api/updateworksheet/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function copyTableItem(id, tblObject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil kopiëren? ", function(val){
        if(val){
            $.ajax({
                url: "/api/coursecopy/" + id,
                type: "post"

            });
        }
    });*/
}

function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/deleteworksheet/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });
}

function showNewWorksheetModal() {
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewWorksheet"));
    setGeneralModalBody('<form id="newworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \

 \
            </form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
       addNewWorksheet($('#newworksheetform').serialize(), viewModel.currentCourseId, function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

function showEditWorksheetModal(id, name)
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditWorksheet"));
    setGeneralModalBody('<form id="updateworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name" value="' + name + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateWorksheet(id, $('#updateworksheetform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr + '/' + viewModel.currentCourseId, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.Name);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $('#addWorksheetBtn').click(function() {
        alert(viewModel.currentCourseId);
        if (typeof null == viewModel.currentCourseId) {
            showNewWorksheetModal();
        } else
            alert("Gelieve een vak te selecteren.");
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateCourseRapport();
    });
}
<commit_msg>Bij toevoegen worksheet controleren of er een vak toegevoegd is.<commit_after>// View model for the page
function pageViewModel(gvm) {
    // Page specific i18n bindings
    gvm.app  = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetNameRapport");}, gvm);
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("HomeRapportTitle");}, gvm);
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectRapportName");}, gvm);
    gvm.homeManual = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("WorksheetRapportManual");}, gvm);

    gvm.availableCourses = ko.observableArray([]);

    gvm.selectCourse = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SelectCourse");}, gvm);
    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);
    gvm.tabledata = ko.observableArray([]);

     // Table i18n bindings
    gvm.werkficheID = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheID");}, gvm);
    gvm.werkficheName = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheName");}, gvm);
    gvm.werkficheAction = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("werkficheAction");}, gvm);

    gvm.currentCourseId = null;

    gvm.updateCourseRapport = function() {
        $.getJSON('api/coursefromteacher/' + gvm.userId, function(data) {
            gvm.availableCourses.removeAll();
            $.each(data, function(i, item) {
                //  Put item in list
                gvm.availableCourses.push(item);

                // Add listener to listitem
                $("#coursebtn-" + item.id).click(function(){
                    gvm.currentCourseId = item.id;
                    $(".btn-courseRapport span:first").text($(this).text());
                    loadTablePage(1);
                });
            });
        });
    };

    gvm.addTableData = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.tabledata.push(tblOject);

        $('#removebtn-' + id).bind('click', function(event, data){
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });

        $('#editbtn-' + id).bind('click', function(event, data){
            showEditWorksheetModal(id, name);
            event.stopPropagation();
        });

        $('#copybtn-' + id).bind('click', function(event, data){
            copyTableItem(id, tblOject);
            event.stopPropagation();
        });
    }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }
}

function addNewWorksheet(serialData, courseid, callback) {
    $.ajax({
        url: "/api/addworksheet/" + courseid,
        type: "POST",
        data: serialData,
        success: function(data) {
            callback(true);
            window.location = "/api/worksheet/" + data['id'] + "/" + data['name'] + '/' + courseid;
        },
        error: function(data) {
            callback(false);
        }
    });
}

function updateWorksheet(id, serialData, callback) {
    $.ajax({
        url: "/api/updateworksheet/" + id,
        type: "PUT",
        data: serialData,
        success: function(data) {
            loadTablePage(1);
            callback(true);
        },
        error: function(data) {
            callback(false);
        }
    });
}

function copyTableItem(id, tblObject) {
    /*showYesNoModal("Bent u zeker dat u dit item wil kopiëren? ", function(val){
        if(val){
            $.ajax({
                url: "/api/coursecopy/" + id,
                type: "post"

            });
        }
    });*/
}

function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            $.ajax({
                url: "/api/deleteworksheet/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
        }
    });
}

function showNewWorksheetModal() {
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("AddNewWorksheet"));
    setGeneralModalBody('<form id="newworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name"> \

 \
            </form>' );

    addGeneralModalButton(i18n.__("AddBtn"), function(){
       addNewWorksheet($('#newworksheetform').serialize(), viewModel.currentCourseId, function(result){
            hideModal();
        });
    });

    showGeneralModal();
}

function showEditWorksheetModal(id, name)
{
    resetGeneralModal();
    setGeneralModalTitle(i18n.__("EditWorksheet"));
    setGeneralModalBody('<form id="updateworksheetform"> \

 \
                <input type="text" class="form-control input-lg" placeholder="' + i18n.__('NameTableTitle') + '" " name="name" value="' + name + '"> \

 \
        </form>');
    $.getJSON()

    addGeneralModalButton(i18n.__("SaveBtn"), function(){
        updateWorksheet(id, $('#updateworksheetform').serialize(), function(result){
            hideModal();
        });
    });

    addGeneralModalButton(i18n.__("CancelBtn"), function(){
        hideModal();
    })

    showGeneralModal();
}

function loadTablePage(pagenr)
{
    $.getJSON('/api/worksheets/page/' + pagenr + '/' + viewModel.currentCourseId, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            viewModel.addTableData(item.id, item.Name);
        });

        /* Let previous en next buttons work */
        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

function initPage() {
    $('#addWorksheetBtn').click(function() {
        alert(viewModel.currentCourseId);
        if (viewModel.currentCourseId === undefined || viewModel.currentCourseId === null ) {
            alert("Gelieve een vak te selecteren.");
        } else
            showNewWorksheetModal();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        viewModel.updateCourseRapport();
    });
}
<|endoftext|>


<commit_before>
var db = require("org/arangodb").db;
var internal = require("internal");
var jsunity = require("jsunity");
var fs = require("fs");

function runSetup () {
  internal.debugClearFailAt();

  db._drop("UnitTestsRecovery");
  var c = db._create("UnitTestsRecovery");
  var i, num = 9999999999;
  for (i = 0; i < 4; ++i) {
    var filename = fs.join(db._path(), "collection-" + c._id + "/datafile-" + num + ".db");
    num++;

    // save an empty file
    fs.write(filename, "");
  }

  c.save({ test: "testValue" }, true); // wait for sync

  internal.debugSegfault("crashing server");
}

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////

function recoverySuite () {
  jsunity.jsUnity.attachAssertions();

  return {
    setUp: function () {
    },
    tearDown: function () {
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test whether we can start the server
////////////////////////////////////////////////////////////////////////////////

    testEmptyDatafiles : function () {
      var c = db._collection("UnitTestsRecovery");
      assertTrue(1, c.count());
      assertEqual("testValue", c.toArray()[0].test);
    }

  };
}

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suite
////////////////////////////////////////////////////////////////////////////////

function main (argv) {
  if (argv[1] === "setup") {
    runSetup();
    return 0;
  }
  else {
    jsunity.run(recoverySuite);
    return jsunity.done().status ? 0 : 1;
  }
}

<commit_msg>fixed jslint warnings<commit_after>/*jshint strict: true, unused : false */
/*global require, assertEqual, assertTrue */

var db = require("org/arangodb").db;
var internal = require("internal");
var jsunity = require("jsunity");
var fs = require("fs");

function runSetup () {
  "use strict";
  internal.debugClearFailAt();

  db._drop("UnitTestsRecovery");
  var c = db._create("UnitTestsRecovery");
  var i, num = 9999999999;
  for (i = 0; i < 4; ++i) {
    var filename = fs.join(db._path(), "collection-" + c._id + "/datafile-" + num + ".db");
    num++;

    // save an empty file
    fs.write(filename, "");
  }

  c.save({ test: "testValue" }, true); // wait for sync

  internal.debugSegfault("crashing server");
}

////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////

function recoverySuite () {
  "use strict";
  jsunity.jsUnity.attachAssertions();

  return {
    setUp: function () {
    },
    tearDown: function () {
    },

////////////////////////////////////////////////////////////////////////////////
/// @brief test whether we can start the server
////////////////////////////////////////////////////////////////////////////////

    testEmptyDatafiles : function () {
      var c = db._collection("UnitTestsRecovery");
      assertTrue(1, c.count());
      assertEqual("testValue", c.toArray()[0].test);
    }

  };
}

////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suite
////////////////////////////////////////////////////////////////////////////////

function main (argv) {
  "use strict";
  if (argv[1] === "setup") {
    runSetup();
    return 0;
  }
  else {
    jsunity.run(recoverySuite);
    return jsunity.done().status ? 0 : 1;
  }
}

<|endoftext|>


<commit_before>/**
 * TreeWalker.js
 *
 * Copyright, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

tinymce.dom.TreeWalker = function(startNode, rootNode) {
	var node = startNode;

	function findSibling(node, startName, siblingName, shallow) {
			var sibling, parent;

			if (node) {
				// Walk into nodes if it has a start
				if (!shallow && node[startName]) {
					return node[startName];
				}

				// Return the sibling if it has one
				if (node != rootNode) {
					sibling = node[siblingName];
					if (sibling) {
						return sibling;
					}

					// Walk up the parents to look for siblings
					for (parent = node.parentNode; parent && parent != rootNode; parent = parent.parentNode) {
						sibling = parent[siblingName];
						if (sibling) {
							return sibling;
						}
					}
				}
			}
		}

	function findPreviousNode(node, startName, siblingName, shallow) {
			var sibling, parent, child;

			if (node) {
				sibling = node[siblingName];
				if (rootNode && sibling === rootNode) {
					return;
				}

				if (sibling) {
					if (!shallow) {
						// Walk up the parents to look for siblings
						for (child = sibling[startName]; child; child = child[startName]) {
							if (!child[startName]) {
								return child;
							}
						}
					}

					return sibling;
				}

				parent = node.parentNode;
				if (parent && parent !== rootNode) {
					return parent;
				}
			}
		}

	/**
	 * Returns the current node.
	 *
	 * @return {Node} Current node where the walker is.
	 */
	this.current = function() {
		return node;
	};

	/**
	 * Walks to the next node in tree.
	 *
	 * @return {Node} Current node where the walker is after moving to the next node.
	 */
	this.next = function(shallow) {
		return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
	};

	/**
	 * Walks to the previous node in tree.
	 *
	 * @return {Node} Current node where the walker is after moving to the previous node.
	 */
	this.prev = function(shallow) {
		return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
	};
};
<commit_msg>Add missing prev2 function (used in Tables)<commit_after>/**
 * TreeWalker.js
 *
 * Copyright, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

tinymce.dom.TreeWalker = function(startNode, rootNode) {
	var node = startNode;

	function findSibling(node, startName, siblingName, shallow) {
			var sibling, parent;

			if (node) {
				// Walk into nodes if it has a start
				if (!shallow && node[startName]) {
					return node[startName];
				}

				// Return the sibling if it has one
				if (node != rootNode) {
					sibling = node[siblingName];
					if (sibling) {
						return sibling;
					}

					// Walk up the parents to look for siblings
					for (parent = node.parentNode; parent && parent != rootNode; parent = parent.parentNode) {
						sibling = parent[siblingName];
						if (sibling) {
							return sibling;
						}
					}
				}
			}
		}

	function findPreviousNode(node, startName, siblingName, shallow) {
			var sibling, parent, child;

			if (node) {
				sibling = node[siblingName];
				if (rootNode && sibling === rootNode) {
					return;
				}

				if (sibling) {
					if (!shallow) {
						// Walk up the parents to look for siblings
						for (child = sibling[startName]; child; child = child[startName]) {
							if (!child[startName]) {
								return child;
							}
						}
					}

					return sibling;
				}

				parent = node.parentNode;
				if (parent && parent !== rootNode) {
					return parent;
				}
			}
		}

	/**
	 * Returns the current node.
	 *
	 * @return {Node} Current node where the walker is.
	 */
	this.current = function() {
		return node;
	};

	/**
	 * Walks to the next node in tree.
	 *
	 * @return {Node} Current node where the walker is after moving to the next node.
	 */
	this.next = function(shallow) {
		return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
	};

	/**
	 * Walks to the previous node in tree.
	 *
	 * @return {Node} Current node where the walker is after moving to the previous node.
	 */
	this.prev = function(shallow) {
		return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
	};

	this.prev2 = function(shallow) {
		node = findPreviousNode(node, 'lastChild', 'previousSibling', shallow);
		return node;
	};
};
<|endoftext|>