<commit_before>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'kama',
		enterMode: ( CKEDITOR.env.gecko ? CKEDITOR.ENTER_BR : CKEDITOR.ENTER_P),
		shiftEnterMode: CKEDITOR.ENTER_P,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = '' + size;
			CKEDITOR.addCss('.cke_editable { font-size: '+ size +'; }');
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = '' + family;
			CKEDITOR.addCss('.cke_editable { font-family: '+ family +'; }');
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
		if( resize == true ) {
			self.config.resize_enabled = true;
		} else {
			self.config.resize_enabled = false;
		}
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() { };
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');<commit_msg>Revert "Change indention in some places to match that used in rest of file"<commit_after>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'kama',
		enterMode: ( CKEDITOR.env.gecko ? CKEDITOR.ENTER_BR : CKEDITOR.ENTER_P),
		shiftEnterMode: CKEDITOR.ENTER_P,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = ''+size;
			CKEDITOR.addCss( '.cke_editable{ font-size: '+ size +'; }' );
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = ''+family;
			CKEDITOR.addCss( '.cke_editable{ font-family: '+ family +'; }' );
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
	    if( resize == true )
		self.config.resize_enabled = true;
	    else
		self.config.resize_enabled = false;
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() {};
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');<|endoftext|>


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

  angular
    .module('deck')
    .controller('DeckController', DeckController);

  /** @ngInject */
  function DeckController($stateParams, $state, BackendService, $log, DeckService) {
    var vm = this;
    vm.deckId = $stateParams.deckId;
    vm.selectedDeck = new BackendService.Deck();
    vm.load = false;
    vm.getDecks = getDecks;
    vm.selectedDeckChange = selectedDeckChange;
    vm.createDeck = createDeck;
    vm.selectDeck = selectDeck;
    vm.selectCard = selectCard;
    vm.removeCard = removeCard;
    vm.clear = clear;

    function getDecks(query) {
      //for not loading list of deck on page init
      if (vm.load) {
        if (!vm.decks) {
          //create request for deck list
          vm.decks = BackendService.getDecks();
        }
        return vm.decks
          .then(function (result) {
            var list = query ? result.filter(queryFilter(query)) : result;
            if (query){
              list.push({name:query});
            }
            return list
          })
      } else {
        vm.load = true
      }
    }

    function selectedDeckChange(deck) {
      if (deck) {
        if (deck.id){
          selectDeck(deck);
        } else {
          createDeck(deck);
        }
      }
    }

    function createDeck(deck) {
      DeckService.setDeckName(deck.name);
      if (vm.deckId.trim()){
        $state.go("deck", {deckId: null});
        //odblokowanie ui ale nie działa autocomplete
        //clear();
      } else{
        $state.reload();
      }
    }

    function selectDeck(deck) {
      if (deck.id != vm.deckId){
        $state.go("deck", {deckId: vm.selectedDeck.id});
        //odblokowanie ui ale nie działa autocomplete
        //clear();
      }
    }

    function selectCard(card) {
      DeckService.setCardObj(card);
      vm.selectedCardId = card.id;
      $state.go("deck.addCard", {cardId: card.id})
    }

    function removeCard(cardId){
      if (vm.cards.length > 1){
        deleteCard(cardId)
      } else {
        $log.warn('last one flashcard')
      }
    }

    function deleteCard(cardId) {
      vm.selectedDeck.removeFlashcard(cardId)
        .then(function (result) {
          $state.go("deck", {deckId: vm.selectedDeck.id});
          getCards();
          $log.log(result);
        }, function (e) {
          $log.error(e);
        });
    }

    //LOCAL FUNCTIONS
    function queryFilter(query) {
      var lowercaseQuery = angular.lowercase(query);
      return function filterFn(deck) {
        if(deck.name){
          return (deck.name.toLowerCase().indexOf(lowercaseQuery) === 0);
        }
      };
    }

    function clear() {
      vm.searchText = null;
    }

    function getCards() {
      vm.selectedDeck.getFlashcards()
        .then(function (result) {
          vm.cards = result;
        }, function (e) {
          $log.error(e);
        });
    }

    //init current selected deck
    function initDeck(value) {
      BackendService.getDeckById(value)
        .then(function (result) {
          //load flashcards for selected deck
          if (vm.deckId.trim()) {
            vm.selectedDeck = result;
            vm.inputDeck = vm.selectedDeck;
            getCards();
          } else {
            vm.searchText = DeckService.getDeckName();
          }
        }, function (e) {
          $log.error(e);
        });
    }
    initDeck(vm.deckId);
  }

})();
<commit_msg>not notify<commit_after>(function () {
  'use strict';

  angular
    .module('deck')
    .controller('DeckController', DeckController);

  /** @ngInject */
  function DeckController($stateParams, $state, BackendService, $log, DeckService) {
    var vm = this;
    vm.deckId = $stateParams.deckId;
    vm.selectedDeck = new BackendService.Deck();
    vm.load = false;
    vm.getDecks = getDecks;
    vm.selectedDeckChange = selectedDeckChange;
    vm.createDeck = createDeck;
    vm.selectDeck = selectDeck;
    vm.selectCard = selectCard;
    vm.removeCard = removeCard;
    vm.clear = clear;

    function getDecks(query) {
      //for not loading list of deck on page init
      if (vm.load) {
        if (!vm.decks) {
          //create request for deck list
          vm.decks = BackendService.getDecks();
        }
        return vm.decks
          .then(function (result) {
            var list = query ? result.filter(queryFilter(query)) : result;
            if (query){
              list.push({name:query});
            }
            return list
          })
      } else {
        vm.load = true
      }
    }

    function selectedDeckChange(deck) {
      if (deck) {
        if (deck.id){
          selectDeck(deck);
        } else {
          createDeck(deck);
        }
      }
    }

    function createDeck(deck) {
      DeckService.setDeckName(deck.name);
      console.log('create')
      if (vm.deckId){
        console.log('sure')
        $state.go("deck", {deckId: null}, {notify: false});
        vm.deckId = vm.selectedDeck.id;
        initDeck(vm.deckId);
        $state.go("deck.addCard", {cardId: null})
      }
    }

    function selectDeck(deck) {
      if (deck.id != vm.deckId){
        $state.go("deck", {deckId: deck.id}, {notify: false});
        vm.deckId = vm.selectedDeck.id;
        initDeck(vm.deckId);
        $state.go("deck.addCard", {cardId: null})
      }
    }

    function selectCard(card) {
      DeckService.setCardObj(card);
      vm.selectedCardId = card.id;
      $state.go("deck.addCard", {cardId: card.id})
    }

    function removeCard(cardId){
      if (vm.cards.length > 1){
        deleteCard(cardId)
      } else {
        $log.warn('last one flashcard')
      }
    }

    function deleteCard(cardId) {
      vm.selectedDeck.removeFlashcard(cardId)
        .then(function (result) {
          $state.go("deck", {deckId: vm.selectedDeck.id});
          getCards();
          $log.log(result);
        }, function (e) {
          $log.error(e);
        });
    }

    //LOCAL FUNCTIONS
    function queryFilter(query) {
      var lowercaseQuery = angular.lowercase(query);
      return function filterFn(deck) {
        if(deck.name){
          return (deck.name.toLowerCase().indexOf(lowercaseQuery) === 0);
        }
      };
    }

    function clear() {
      vm.searchText = null;
    }

    function getCards() {
      vm.selectedDeck.getFlashcards()
        .then(function (result) {
          vm.cards = result;
        }, function (e) {
          $log.error(e);
        });
    }

    //init current selected deck
    function initDeck(value) {
      BackendService.getDeckById(value)
        .then(function (result) {
          //load flashcards for selected deck
          if (vm.deckId.trim()) {
            vm.selectedDeck = result;
            vm.inputDeck = vm.selectedDeck;
            getCards();
          } else {
            vm.searchText = DeckService.getDeckName();
          }
        }, function (e) {
          $log.error(e);
        });
    }
    initDeck(vm.deckId);
  }

})();
<|endoftext|>


<commit_before>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'kama',
		enterMode: CKEDITOR.ENTER_BR,
		shiftEnterMode: CKEDITOR.ENTER_P,
		forcePasteAsPlainText: false,
		allowedContent: true,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setLanguage = function( language ) {
		self.config.language = language;
	}

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = '' + size;
			CKEDITOR.addCss('.cke_editable { font-size: '+ size +'; }');
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = '' + family;
			CKEDITOR.addCss('.cke_editable { font-family: '+ family +'; }');
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
		if( resize == true ) {
			self.config.resize_enabled = true;
		} else {
			self.config.resize_enabled = false;
		}
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() { };
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');
<commit_msg>Remove top margin from P elements in Ckeditor content<commit_after>function ComponentCkeditor( id ) {
	var self = new ComponentTextfield(id);

	self.setDefaultState('text-value');
	self.setState('text-value', '');

	self.editor = CKEDITOR.instances[id];
	self.editorIsReady = false;
	self.editorToolbar = 'OneRow';
	self.haveUnsetData = false;

	self.config = {
		skin: 'kama',
		enterMode: CKEDITOR.ENTER_BR,
		shiftEnterMode: CKEDITOR.ENTER_P,
		forcePasteAsPlainText: false,
		allowedContent: true,
		disableNativeSpellChecker: false,
		browserContextMenuOnCtrl: true,
		colorButton_enableMore: false,
		resize_dir: 'both',
		/*resize_enabled: true,*/
		fontSize_sizes:
			'8/8pt;' +
			'9/9pt;' +
			'10/10pt;' +
			'11/11pt;' +
			'12/12pt;' +
			'14/14pt;' +
			'16/16pt;' +
			'18/18pt;' +
			'20/20pt;' +
			'22/22pt;' +
			'24/24pt;' +
			'26/26pt;' +
			'28/28pt;' +
			'36/36pt;' +
			'48/48pt',
		font_names:
			'Arial/Arial, Helvetica, sans-serif;' +
			'Arial black;' +
			'Calibri/Calibri, sans-serif;' +
			'Comic Sans MS/Comic Sans MS, cursive;' +
			'Courier New/Courier New, Courier, monospace;' +
			'Georgia/Georgia, serif;' +
			'Lucida Console/Lucida Console, monospace;' +
			'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' +
			'Tahoma/Tahoma, Geneva, sans-serif;' +
			'Times New Roman/Times New Roman, Times, serif;' +
			'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' +
			'Verdana/Verdana, Geneva, sans-serif',
		toolbar_Empty: [],
		toolbar_SingleRow: [
			[ 'SpellCheckerLanguage' ],
			[ 'SpellChecker' ]
		],
		toolbar_OneRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ], [ 'PasteFromWord' ],
			[ 'Font' ], [ 'FontSize' ],
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], [ 'Resize' ]
		],
		toolbar_TwoRow: [
			[ 'Bold', 'Italic', 'Underline', 'Strike' ],
			[ 'NumberedList', 'BulletedList' ],
			[ 'Indent', 'Outdent', 'Blockquote' ],
			[ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ], [ 'PasteFromWord' ],
			[ 'Link', 'Image', 'Youtube', 'HorizontalRule' ],
			[ 'Font' ], [ 'FontSize' ],'/',
			[ 'TextColor', 'BGColor' ],
			[ 'SpellCheckerLanguage' ], [ 'SpellChecker' ], ['Resize']
		],
		toolbar: 'OneRow',
		plugins:
			'basicstyles,' +
			'blockquote,' +
			'clipboard,' +
			'colorbutton,' +
			'contextmenu,' +
			'enterkey,' +
			'font,' +
			'horizontalrule,' +
			'htmlwriter,' +
			'indent,' +
			'justify,' +
			'link,' +
			'list,' +
			'magicline,' +
			'pastetext,' +
			/* 'removeformat,' + */
			'showborders,' +
			'tab,' +
			/*'table,' + */
			/*'tabletools,' + */
			'toolbar,' +
			'undo,' +
			'wysiwygarea,' +
			'cention_spellcheck,' +
			'cention_image,' +
			'pastefromword,' +
			'resize,' +
			'youtube',
		contentsCss: [
			WFServerURI + 'Resources/CSS/jquery.spellchecker.css',
			WFServerURI + 'Resources/Javascript/ckeditor/contents.css',
			WFServerURI + 'Support/Components/Ckeditor/Ckeditor.css',
		],
		spellCheckLanguages: []
	};

	self.setLanguage = function( language ) {
		self.config.language = language;
	}

	self.setFontSize = function( size ){
		if( size ){
			self.config.fontSize_defaultLabel = '' + size;
			CKEDITOR.addCss('.cke_editable { font-size: '+ size +'; }');
		}
	};

	self.setFontFamily = function( family ){
		if( family ){
			self.config.font_defaultLabel = '' + family;
			CKEDITOR.addCss('.cke_editable { font-family: '+ family +'; }');
		}
	}

	self.setLanguages = function( list ) {
	    self.config.spellCheckLanguages = list;
	};
	self.setImages = function( list ) {
		if( self.editor ) {
			self.editor.___fileArchiveImages = list;
		}
	};
	self.setShowResize = function( resize ) {
		if( resize == true ) {
			self.config.resize_enabled = true;
		} else {
			self.config.resize_enabled = false;
		}
	};
	self.setItemHeight = function( height ){
		self.config.height = height;
	};
	self.showBasicToolbar = function() { };
	self.showAdvancedToolbar = function() { };
	self.setTwoRowToolbar = function( value ) {
		if( value ) {
			self.editorToolbar = 'TwoRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setShowToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'Empty';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setSimpleToolbar = function( value ) {
		if( !value ) {
			self.editorToolbar = 'SingleRow';
			self.config.toolbar = self.editorToolbar;
		}
	};
	self.setReadOnly = function( value ) {};
	self.setEnabled = function( value ) {};

	self.empty = function() {
		if( self.editor ) {
			if( self.editor.getData() )
				return false;
		}
		return true;
	};

	var previousGetState = self.getState;
	self.getState = function( state ) {
		if( state == 'text-value' ) {
			return self.editor.getData();
		}
		return previousGetState(state);
	};

	var previousSetState = self.setState;
	self.setState = function( state, value ) {
		if( state == 'text-value' ) {
			var dataSet = false;
			self._states['text-value'] = value;
			if( self.editor ) {
				if( self.editorIsReady ) {
					self.editor.setData(value);
					self.editor.updateElement();
					dataSet = true;
				}
			}
			if( !dataSet ) {
				self.haveUnsetData = true;
			}
		} else {
			previousSetState(state, value);
		}
	};

	self.updateVisual = function() {};
	self.updateFormValue = function() {
		if( self.editor ) {
			self.editor.updateElement();
		}
	};

	var previousActivate = self.activate;
	self.activate = function() {
		self.editor = CKEDITOR.replace(self.identifier(), self.config);
		self.editor.on('contentDom', function() {
			self.editorIsReady = true;
			if( self.haveUnsetData ) {
				self.editor.setData(self._states['text-value']);
				self.editor.updateElement();
				self.haveUnsetData = false;
			}
		});

		self.editor.on('contentDomUnload', function() {
			self.editorIsReady = false;
		});
		previousActivate();
	};

	return self;
}

CKEDITOR.addCss('body { margin-left: 5px; margin-right: 5px; margin-top: 3px; margin-bottom: 3px; }');
CKEDITOR.addCss('p { margin-top: 0; }');
<|endoftext|>


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

  /**
   * @ngdoc     controller
   * @name      app.controller:MainController
   * @requires  {object}  vehicles  The vehicles service
   * @description
   *   The Main Controller.
   **/
  angular
    .module('app')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location'];

  function MainController ($scope, $route, $routeParams, $location) {

    // A reference to the View Model.
    var vm = this;

    vm.title = 'Main';

    vm.$route = $route;
    vm.$location = $location;
    vm.$routeParams = $routeParams;

    $scope.$on('$routeChangeSuccess', function(event) {
      //console.log('Main $routeChangeSuccess');
    });

    $scope.$on('$viewContentLoaded', function(event) {
      //console.log('Main $viewContentLoaded');
    });
  }
})();
<commit_msg>renamed viewModel variable<commit_after>(function() {
  'use strict';

  /**
   * @ngdoc     controller
   * @name      app.controller:MainController
   * @requires  {object}  vehicles  The vehicles service
   * @description
   *   The Main Controller.
   **/
  angular
    .module('app')
    .controller('MainController', MainController);

  MainController.$inject = ['$scope', '$route', '$routeParams', '$location'];

  function MainController ($scope, $route, $routeParams, $location) {
    // A reference to the View Model.
    var main = this;

    main.title = 'Main';

    main.$route = $route;
    main.$location = $location;
    main.$routeParams = $routeParams;

    $scope.$on('$routeChangeSuccess', function(event) {
      //console.log('Main $routeChangeSuccess');
    });

    $scope.$on('$viewContentLoaded', function(event) {
      //console.log('Main $viewContentLoaded');
    });
  }
})();
<|endoftext|>


<commit_before>const builder = require('focus').component.builder;
const React = require('react');
const type = require('focus').component.types;
const {pluck, sortBy} = require('lodash/collection');
const applicationStateBehaviour = require('./mixin/application-state');
const headerMixin = {
    mixins: [applicationStateBehaviour],
    /** @inheriteddoc */
    getDefaultProps: function getMenuDefaultProps() {
        return {
            /**
            * Selector for the domNode on which the scroll is attached.
            * @type {string}
            */
            scrollTargetSelector: undefined,
            /**
            * Default style of the component.s
            * @type {Object}
            */
            style: {},
            /**
            * Default size of the bar. Should be present in sizeMap.
            * @type {String}
            */
            size: 'medium',
            /**
            * Map which defines sizes exists for the components and their border.
            * @type {Object}
            */
            sizeMap: {
                'small': {
                    'sizeBorder': 5
                },
                'medium': {
                    'sizeBorder': 0
                }
            },
            /**
            * A way to redefine the process size of the element.
            * @type {function}
            */
            processSize: undefined,
            /**
            * A handler to notify other elements that the size has changed.
            * @type {[type]}
            */
            notifySizeChange: undefined
        };
    },
    /** @inheritdoc */
    propTypes: {
        size: type('string'),
        scrollTargetSelector: type('string'),
        style: type('object'),
        sizeMap: type('object'),
        notifySizeChange: type(['function', 'object']),
        processSize: type(['function', 'object'])
    },
    /** @inheritdoc */
    getInitialState: function getMenuDefaultState() {
        /** @inheriteddoc */
        return {
            open: this.props.open,
            size: this.props.size
        };
    },

    /** @inheriteddoc */
    componentWillMount: function barWillMount() {
        this._processSizes();
        this.scrollTargetNode = (this.props.scrollTargetSelector && this.props.scrollTargetSelector !== '') ? document.querySelector(this.props.scrollTargetSelector) : window;
    },
    /** @inheriteddoc */
    componentDidMount: function barDidMount(){
        this.attachScrollListener();
    },
    /** @inheriteddoc */
    componentWillUnMount: function barWillUnMount(){
        this.detachScrollListener();
        this.appStateWillUnmount();
    },
    /**
    * Process the sizeMap in order to sort them by border size and create a sizes array.
    */
    _processSizes: function processSizes(){
        var sizes = [];
        for(var sz in this.props.sizeMap){
            sizes.push({name: sz, sizeBorder: this.props.sizeMap[sz].sizeBorder});
        }
        this.sizes = pluck(sortBy(sizes, 'sizeBorder'), 'name');
    },
    /**
    * Get the current element size.
    * @returns {int} - The size in pixel of the current element in the browser.
    */
    _processElementSize: function processElementSize(){
        return React.findDOMNode(this).offsetHeight;
    },
    /**
    * Get the scroll position from the top of the screen.
    * @returns {int} - The position in pixel from the top of the scroll container.
    */
    _getScrollPosition: function getScrollPosition(){
        //The pageYOffset is done in order to deal with the window case. Another possibility would have been to use window.docment.body as a node for scrollTop.
        //But the scrollListener on the page is only on the window element.
        return this.scrollTargetNode.pageYOffset !== undefined ? this.scrollTargetNode.pageYOffset : this.scrollTargetNode.scrollTop;
    },
    /**
    * Notify other elements that the size has changed.
    */
    _notifySizeChange: function notifySizeChanged(){
        if(this.props.notifySizeChange){
            this.props.notifySizeChange(this.state.size);
        }
    },
    /**
    * Change the size of the bar.
    * @param {string} newSize - The new size.
    * @returns {undefined} -  A way to stop the propagation.
    */
    _changeSize: function changeSize(newSize){
        // Todo: see if the notification of the changed size can be called before.
        return this.setState({size: newSize}, this._notifySizeChange);
    },
    /**
    * Process the size in order to know if the size should be changed depending on the scroll position and the border of each zone.
    * @returns {object} - The return is used to stop the treatement.
    */
    _processSize: function _processSize(){
        //Allow the user to redefine the process size function.
        if(this.props.processSize){
            return this.props.processSize();
        }
        var currentIndex = this.sizes.indexOf(this.state.size);
        var currentScrollPosition = this._getScrollPosition();
        //Process increase treatement.
        if(currentIndex < (this.sizes.length - 1)){
            var increaseBorder = this.props.sizeMap[this.sizes[currentIndex + 1]].sizeBorder;
            if(currentScrollPosition > increaseBorder){
                return this._changeSize(this.sizes[currentIndex + 1]);
            }
        }
        //Process decrease treatement.
        if(currentIndex > 0){
            var decreaseBorder = this.props.sizeMap[this.sizes[currentIndex - 1]].sizeBorder;
            if(currentScrollPosition <= decreaseBorder){
                return this._changeSize(this.sizes[currentIndex - 1]);
            }
        }
    },
    /**
    * Handle the scroll event in order to resize the page.
    * @param {object} event [description]
    */
    handleScroll: function handleScrollEvent(event){
        this._processSize();
    },

    /**
    * Attach scroll listener on the scroll target node.
    */
    attachScrollListener: function attachScrollListener() {
        this.scrollTargetNode.addEventListener('scroll', this.handleScroll);
        this.scrollTargetNode.addEventListener('resize', this.handleScroll);
    },

    /**
    * Detach scroll handler on the scroll target node.
    */
    detachScrollListener: function detachScrollListener() {
        this.scrollTargetNode.removeEventListener('scroll', this.handleScroll);
        this.scrollTargetNode.removeEventListener('resize', this.handleScroll);
    },
    /** @inheriteddoc */
    render: function renderBar() {
        const className = `mdl-layout__header header-${this.state.size}`;
        return (
            <header className={className} data-focus='header' data-route={this.state.route} data-mode={this.state.mode} data-size={this.state.size}>
            {this.props.children}
            </header>
        );
    }
};

module.exports = builder(headerMixin);
<commit_msg>[header] Remove mdl class<commit_after>const builder = require('focus').component.builder;
const React = require('react');
const type = require('focus').component.types;
const {pluck, sortBy} = require('lodash/collection');
const applicationStateBehaviour = require('./mixin/application-state');
const headerMixin = {
    mixins: [applicationStateBehaviour],
    /** @inheriteddoc */
    getDefaultProps: function getMenuDefaultProps() {
        return {
            /**
            * Selector for the domNode on which the scroll is attached.
            * @type {string}
            */
            scrollTargetSelector: undefined,
            /**
            * Default style of the component.s
            * @type {Object}
            */
            style: {},
            /**
            * Default size of the bar. Should be present in sizeMap.
            * @type {String}
            */
            size: 'medium',
            /**
            * Map which defines sizes exists for the components and their border.
            * @type {Object}
            */
            sizeMap: {
                'small': {
                    'sizeBorder': 5
                },
                'medium': {
                    'sizeBorder': 0
                }
            },
            /**
            * A way to redefine the process size of the element.
            * @type {function}
            */
            processSize: undefined,
            /**
            * A handler to notify other elements that the size has changed.
            * @type {[type]}
            */
            notifySizeChange: undefined
        };
    },
    /** @inheritdoc */
    propTypes: {
        size: type('string'),
        scrollTargetSelector: type('string'),
        style: type('object'),
        sizeMap: type('object'),
        notifySizeChange: type(['function', 'object']),
        processSize: type(['function', 'object'])
    },
    /** @inheritdoc */
    getInitialState: function getMenuDefaultState() {
        /** @inheriteddoc */
        return {
            open: this.props.open,
            size: this.props.size
        };
    },

    /** @inheriteddoc */
    componentWillMount: function barWillMount() {
        this._processSizes();
        this.scrollTargetNode = (this.props.scrollTargetSelector && this.props.scrollTargetSelector !== '') ? document.querySelector(this.props.scrollTargetSelector) : window;
    },
    /** @inheriteddoc */
    componentDidMount: function barDidMount(){
        this.attachScrollListener();
    },
    /** @inheriteddoc */
    componentWillUnMount: function barWillUnMount(){
        this.detachScrollListener();
        this.appStateWillUnmount();
    },
    /**
    * Process the sizeMap in order to sort them by border size and create a sizes array.
    */
    _processSizes: function processSizes(){
        var sizes = [];
        for(var sz in this.props.sizeMap){
            sizes.push({name: sz, sizeBorder: this.props.sizeMap[sz].sizeBorder});
        }
        this.sizes = pluck(sortBy(sizes, 'sizeBorder'), 'name');
    },
    /**
    * Get the current element size.
    * @returns {int} - The size in pixel of the current element in the browser.
    */
    _processElementSize: function processElementSize(){
        return React.findDOMNode(this).offsetHeight;
    },
    /**
    * Get the scroll position from the top of the screen.
    * @returns {int} - The position in pixel from the top of the scroll container.
    */
    _getScrollPosition: function getScrollPosition(){
        //The pageYOffset is done in order to deal with the window case. Another possibility would have been to use window.docment.body as a node for scrollTop.
        //But the scrollListener on the page is only on the window element.
        return this.scrollTargetNode.pageYOffset !== undefined ? this.scrollTargetNode.pageYOffset : this.scrollTargetNode.scrollTop;
    },
    /**
    * Notify other elements that the size has changed.
    */
    _notifySizeChange: function notifySizeChanged(){
        if(this.props.notifySizeChange){
            this.props.notifySizeChange(this.state.size);
        }
    },
    /**
    * Change the size of the bar.
    * @param {string} newSize - The new size.
    * @returns {undefined} -  A way to stop the propagation.
    */
    _changeSize: function changeSize(newSize){
        // Todo: see if the notification of the changed size can be called before.
        return this.setState({size: newSize}, this._notifySizeChange);
    },
    /**
    * Process the size in order to know if the size should be changed depending on the scroll position and the border of each zone.
    * @returns {object} - The return is used to stop the treatement.
    */
    _processSize: function _processSize(){
        //Allow the user to redefine the process size function.
        if(this.props.processSize){
            return this.props.processSize();
        }
        var currentIndex = this.sizes.indexOf(this.state.size);
        var currentScrollPosition = this._getScrollPosition();
        //Process increase treatement.
        if(currentIndex < (this.sizes.length - 1)){
            var increaseBorder = this.props.sizeMap[this.sizes[currentIndex + 1]].sizeBorder;
            if(currentScrollPosition > increaseBorder){
                return this._changeSize(this.sizes[currentIndex + 1]);
            }
        }
        //Process decrease treatement.
        if(currentIndex > 0){
            var decreaseBorder = this.props.sizeMap[this.sizes[currentIndex - 1]].sizeBorder;
            if(currentScrollPosition <= decreaseBorder){
                return this._changeSize(this.sizes[currentIndex - 1]);
            }
        }
    },
    /**
    * Handle the scroll event in order to resize the page.
    * @param {object} event [description]
    */
    handleScroll: function handleScrollEvent(event){
        this._processSize();
    },

    /**
    * Attach scroll listener on the scroll target node.
    */
    attachScrollListener: function attachScrollListener() {
        this.scrollTargetNode.addEventListener('scroll', this.handleScroll);
        this.scrollTargetNode.addEventListener('resize', this.handleScroll);
    },

    /**
    * Detach scroll handler on the scroll target node.
    */
    detachScrollListener: function detachScrollListener() {
        this.scrollTargetNode.removeEventListener('scroll', this.handleScroll);
        this.scrollTargetNode.removeEventListener('resize', this.handleScroll);
    },
    /** @inheriteddoc */
    render: function renderBar() {
        const className = `header-${this.state.size}`;
        return (
            <header className={className} data-focus='header' data-route={this.state.route} data-mode={this.state.mode} data-size={this.state.size}>
            {this.props.children}
            </header>
        );
    }
};

module.exports = builder(headerMixin);
<|endoftext|>


<commit_before>/**
 * Bootstrap Modal wrapper for use with Backbone.
 *
 * Takes care of instantiation, manages multiple modals,
 * adds several options and removes the element from the DOM when closed
 *
 * @author Charles Davison <charlie@powmedia.co.uk>
 *
 * Events:
 * shown: Fired when the modal has finished animating in
 * hidden: Fired when the modal has finished animating out
 * cancel: The user dismissed the modal
 * ok: The user clicked OK
 */
(function($, _, Backbone) {

  //Set custom template settings
  var _interpolateBackup = _.templateSettings;
  _.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g,
    evaluate: /<%([\s\S]+?)%>/g
  }

  var template = _.template('\
    <% if (title) { %>\

\
        <% if (allowCancel) { %>\
          ×\
        <% } %>\

{{title}}
\

\
    <% } %>\

{{content}}
\

\
      <% if (allowCancel) { %>\
        <% if (cancelText) { %>\
          {{cancelText}}\
        <% } %>\
      <% } %>\
      {{okText}}\

\
  ');

  //Reset to users' template settings
  _.templateSettings = _interpolateBackup;

  var Modal = Backbone.View.extend({

    className: 'modal',

    events: {
      'click .close': function(event) {
        event.preventDefault();

        this.trigger('cancel');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('cancel', this);
        }
      },
      'click .cancel': function(event) {
        event.preventDefault();

        this.trigger('cancel');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('cancel', this);
        }
      },
      'click .ok': function(event) {
        event.preventDefault();

        this.trigger('ok');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('ok', this);
        }

        if (this.options.okCloses) {
          this.close();
        }
      },
      'keypress': function(event) {
        if (this.options.enterTriggersOk && event.which == 13) {
          event.preventDefault();

          this.trigger('ok');

          if (this.options.content && this.options.content.trigger) {
            this.options.content.trigger('ok', this);
          }

          if (this.options.okCloses) {
            this.close();
          }
        }
      }
    },

    /**
     * Creates an instance of a Bootstrap Modal
     *
     * @see http://twitter.github.com/bootstrap/javascript.html#modals
     *
     * @param {Object} options
     * @param {String|View} [options.content]     Modal content. Default: none
     * @param {String} [options.title]            Title. Default: none
     * @param {String} [options.okText]           Text for the OK button. Default: 'OK'
     * @param {String} [options.cancelText]       Text for the cancel button. Default: 'Cancel'. If passed a falsey value, the button will be removed
     * @param {Boolean} [options.allowCancel      Whether the modal can be closed, other than by pressing OK. Default: true
     * @param {Boolean} [options.escape]          Whether the 'esc' key can dismiss the modal. Default: true, but false if options.cancellable is true
     * @param {Boolean} [options.animate]         Whether to animate in/out. Default: false
     * @param {Function} [options.template]       Compiled underscore template to override the default one
     * @param {Boolean} [options.enterTriggersOk] Whether the 'enter' key will trigger OK. Default: false
     */
    initialize: function(options) {
      this.options = _.extend({
        title: null,
        okText: 'OK',
        focusOk: true,
        okCloses: true,
        cancelText: 'Cancel',
        allowCancel: true,
        escape: true,
        animate: false,
        template: template,
        enterTriggersOk: false
      }, options);
    },

    /**
     * Creates the DOM element
     *
     * @api private
     */
    render: function() {
      var $el = this.$el,
          options = this.options,
          content = options.content;

      //Create the modal container
      $el.html(options.template(options));

      var $content = this.$content = $el.find('.modal-body')

      //Insert the main content if it's a view
      if (content.$el) {
        content.render();
        $el.find('.modal-body').html(content.$el);
      }

      if (options.animate) $el.addClass('fade');

      this.isRendered = true;

      return this;
    },

    /**
     * Renders and shows the modal
     *
     * @param {Function} [cb]     Optional callback that runs only when OK is pressed.
     */
    open: function(cb) {
      if (!this.isRendered) this.render();

      var self = this,
          $el = this.$el;

      //Create it
      $el.modal(_.extend({
        keyboard: this.options.allowCancel,
        backdrop: this.options.allowCancel ? true : 'static'
      }, this.options.modalOptions));

      //Focus OK button
      $el.one('shown', function() {
        if (self.options.focusOk) {
          $el.find('.btn.ok').focus();
        }

        if (self.options.content && self.options.content.trigger) {
          self.options.content.trigger('shown', self);
        }

        self.trigger('shown');
      });

      //Adjust the modal and backdrop z-index; for dealing with multiple modals
      var numModals = Modal.count,
          $backdrop = $('.modal-backdrop:eq('+numModals+')'),
          backdropIndex = parseInt($backdrop.css('z-index'),10),
          elIndex = parseInt($backdrop.css('z-index'), 10);

      $backdrop.css('z-index', backdropIndex + numModals);
      this.$el.css('z-index', elIndex + numModals);

      if (this.options.allowCancel) {
        $backdrop.one('click', function() {
          if (self.options.content && self.options.content.trigger) {
            self.options.content.trigger('cancel', self);
          }

          self.trigger('cancel');
        });

        $(document).one('keyup.dismiss.modal', function (e) {
          e.which == 27 && self.trigger('cancel');

          if (self.options.content && self.options.content.trigger) {
            e.which == 27 && self.options.content.trigger('shown', self);
          }
        });
      }

      this.on('cancel', function() {
        self.close();
      });

      Modal.count++;

      //Run callback on OK if provided
      if (cb) {
        self.on('ok', cb);
      }

      return this;
    },

    /**
     * Closes the modal
     */
    close: function() {
      var self = this,
          $el = this.$el;

      //Check if the modal should stay open
      if (this._preventClose) {
        this._preventClose = false;
        return;
      }

      $el.one('hidden', function onHidden(e) {
        // Ignore events propagated from interior objects, like bootstrap tooltips
        if(e.target !== e.currentTarget){
          return $el.one('hidden', onHidden);
        }
        self.remove();

        if (self.options.content && self.options.content.trigger) {
          self.options.content.trigger('hidden', self);
        }

        self.trigger('hidden');
      });

      $el.modal('hide');

      Modal.count--;
    },

    /**
     * Stop the modal from closing.
     * Can be called from within a 'close' or 'ok' event listener.
     */
    preventClose: function() {
      this._preventClose = true;
    }
  }, {
    //STATICS

    //The number of modals on display
    count: 0
  });

  //EXPORTS
  //CommonJS
  if (typeof require == 'function' && typeof module !== 'undefined' && exports) {
    module.exports = Modal;
  }

  //AMD / RequireJS
  if (typeof define === 'function' && define.amd) {
    return define(function() {
      Backbone.BootstrapModal = Modal;
    })
  }

  //Regular; add to Backbone.Bootstrap.Modal
  else {
    Backbone.BootstrapModal = Modal;
  }

})(jQuery, _, Backbone);
<commit_msg>Fixed unterminated statement<commit_after>/**
 * Bootstrap Modal wrapper for use with Backbone.
 *
 * Takes care of instantiation, manages multiple modals,
 * adds several options and removes the element from the DOM when closed
 *
 * @author Charles Davison <charlie@powmedia.co.uk>
 *
 * Events:
 * shown: Fired when the modal has finished animating in
 * hidden: Fired when the modal has finished animating out
 * cancel: The user dismissed the modal
 * ok: The user clicked OK
 */
(function($, _, Backbone) {

  //Set custom template settings
  var _interpolateBackup = _.templateSettings;
  _.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g,
    evaluate: /<%([\s\S]+?)%>/g
  };

  var template = _.template('\
    <% if (title) { %>\

\
        <% if (allowCancel) { %>\
          ×\
        <% } %>\

{{title}}
\

\
    <% } %>\

{{content}}
\

\
      <% if (allowCancel) { %>\
        <% if (cancelText) { %>\
          {{cancelText}}\
        <% } %>\
      <% } %>\
      {{okText}}\

\
  ');

  //Reset to users' template settings
  _.templateSettings = _interpolateBackup;

  var Modal = Backbone.View.extend({

    className: 'modal',

    events: {
      'click .close': function(event) {
        event.preventDefault();

        this.trigger('cancel');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('cancel', this);
        }
      },
      'click .cancel': function(event) {
        event.preventDefault();

        this.trigger('cancel');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('cancel', this);
        }
      },
      'click .ok': function(event) {
        event.preventDefault();

        this.trigger('ok');

        if (this.options.content && this.options.content.trigger) {
          this.options.content.trigger('ok', this);
        }

        if (this.options.okCloses) {
          this.close();
        }
      },
      'keypress': function(event) {
        if (this.options.enterTriggersOk && event.which == 13) {
          event.preventDefault();

          this.trigger('ok');

          if (this.options.content && this.options.content.trigger) {
            this.options.content.trigger('ok', this);
          }

          if (this.options.okCloses) {
            this.close();
          }
        }
      }
    },

    /**
     * Creates an instance of a Bootstrap Modal
     *
     * @see http://twitter.github.com/bootstrap/javascript.html#modals
     *
     * @param {Object} options
     * @param {String|View} [options.content]     Modal content. Default: none
     * @param {String} [options.title]            Title. Default: none
     * @param {String} [options.okText]           Text for the OK button. Default: 'OK'
     * @param {String} [options.cancelText]       Text for the cancel button. Default: 'Cancel'. If passed a falsey value, the button will be removed
     * @param {Boolean} [options.allowCancel      Whether the modal can be closed, other than by pressing OK. Default: true
     * @param {Boolean} [options.escape]          Whether the 'esc' key can dismiss the modal. Default: true, but false if options.cancellable is true
     * @param {Boolean} [options.animate]         Whether to animate in/out. Default: false
     * @param {Function} [options.template]       Compiled underscore template to override the default one
     * @param {Boolean} [options.enterTriggersOk] Whether the 'enter' key will trigger OK. Default: false
     */
    initialize: function(options) {
      this.options = _.extend({
        title: null,
        okText: 'OK',
        focusOk: true,
        okCloses: true,
        cancelText: 'Cancel',
        allowCancel: true,
        escape: true,
        animate: false,
        template: template,
        enterTriggersOk: false
      }, options);
    },

    /**
     * Creates the DOM element
     *
     * @api private
     */
    render: function() {
      var $el = this.$el,
          options = this.options,
          content = options.content;

      //Create the modal container
      $el.html(options.template(options));

      var $content = this.$content = $el.find('.modal-body')

      //Insert the main content if it's a view
      if (content.$el) {
        content.render();
        $el.find('.modal-body').html(content.$el);
      }

      if (options.animate) $el.addClass('fade');

      this.isRendered = true;

      return this;
    },

    /**
     * Renders and shows the modal
     *
     * @param {Function} [cb]     Optional callback that runs only when OK is pressed.
     */
    open: function(cb) {
      if (!this.isRendered) this.render();

      var self = this,
          $el = this.$el;

      //Create it
      $el.modal(_.extend({
        keyboard: this.options.allowCancel,
        backdrop: this.options.allowCancel ? true : 'static'
      }, this.options.modalOptions));

      //Focus OK button
      $el.one('shown', function() {
        if (self.options.focusOk) {
          $el.find('.btn.ok').focus();
        }

        if (self.options.content && self.options.content.trigger) {
          self.options.content.trigger('shown', self);
        }

        self.trigger('shown');
      });

      //Adjust the modal and backdrop z-index; for dealing with multiple modals
      var numModals = Modal.count,
          $backdrop = $('.modal-backdrop:eq('+numModals+')'),
          backdropIndex = parseInt($backdrop.css('z-index'),10),
          elIndex = parseInt($backdrop.css('z-index'), 10);

      $backdrop.css('z-index', backdropIndex + numModals);
      this.$el.css('z-index', elIndex + numModals);

      if (this.options.allowCancel) {
        $backdrop.one('click', function() {
          if (self.options.content && self.options.content.trigger) {
            self.options.content.trigger('cancel', self);
          }

          self.trigger('cancel');
        });

        $(document).one('keyup.dismiss.modal', function (e) {
          e.which == 27 && self.trigger('cancel');

          if (self.options.content && self.options.content.trigger) {
            e.which == 27 && self.options.content.trigger('shown', self);
          }
        });
      }

      this.on('cancel', function() {
        self.close();
      });

      Modal.count++;

      //Run callback on OK if provided
      if (cb) {
        self.on('ok', cb);
      }

      return this;
    },

    /**
     * Closes the modal
     */
    close: function() {
      var self = this,
          $el = this.$el;

      //Check if the modal should stay open
      if (this._preventClose) {
        this._preventClose = false;
        return;
      }

      $el.one('hidden', function onHidden(e) {
        // Ignore events propagated from interior objects, like bootstrap tooltips
        if(e.target !== e.currentTarget){
          return $el.one('hidden', onHidden);
        }
        self.remove();

        if (self.options.content && self.options.content.trigger) {
          self.options.content.trigger('hidden', self);
        }

        self.trigger('hidden');
      });

      $el.modal('hide');

      Modal.count--;
    },

    /**
     * Stop the modal from closing.
     * Can be called from within a 'close' or 'ok' event listener.
     */
    preventClose: function() {
      this._preventClose = true;
    }
  }, {
    //STATICS

    //The number of modals on display
    count: 0
  });

  //EXPORTS
  //CommonJS
  if (typeof require == 'function' && typeof module !== 'undefined' && exports) {
    module.exports = Modal;
  }

  //AMD / RequireJS
  if (typeof define === 'function' && define.amd) {
    return define(function() {
      Backbone.BootstrapModal = Modal;
    })
  }

  //Regular; add to Backbone.Bootstrap.Modal
  else {
    Backbone.BootstrapModal = Modal;
  }

})(jQuery, _, Backbone);
<|endoftext|>


<commit_before>/* globals chrome, bgapp */
{
    // http://stackoverflow.com/questions/15124995/how-to-wait-for-an-asynchronous-methods-callback-return-value
    bgapp.tabUrlTracker = (function() {
        // All opened urls
        const urls = {};
        const closeListeners = [];

        const queryTabsCallback = function(allTabs) {
            if (allTabs) {
                allTabs.forEach(function(tab) {
                    urls[tab.id] = tab.url;
                });
            }
        };

        const updateTabCallback = function(tabId, changeinfo, tab) {
            urls[tabId] = tab.url;
        };

        // Not all tabs will fire an update event. If the page is pre-rendered,
        // a replace will happen instead.
        const tabReplacedCallback = function(newTabId, oldTabId) {
            delete urls[oldTabId];
            chrome.tabs.get(newTabId, function(tab) {
                urls[tab.id] = tab.url;
            });
        };

        const removeTabCallback = function(tabId) {
            closeListeners.forEach(function(fn) {
                fn(urls[tabId]);
            });
            delete urls[tabId];
        };

        // init
        chrome.tabs.query({}, queryTabsCallback);
        chrome.tabs.onUpdated.addListener(updateTabCallback);
        chrome.tabs.onRemoved.addListener(removeTabCallback);
        chrome.tabs.onReplaced.addListener(tabReplacedCallback);

        return {
            getUrlFromId: function(id) {
                return urls[id];
            }
        };
    })();
}
<commit_msg>Only update tabUrlTracker on URL change (#53)<commit_after>/* globals chrome, bgapp */
{
    // http://stackoverflow.com/questions/15124995/how-to-wait-for-an-asynchronous-methods-callback-return-value
    bgapp.tabUrlTracker = (function() {
        // All opened urls
        const urls = {};
        const closeListeners = [];

        const queryTabsCallback = function(allTabs) {
            if (allTabs) {
                allTabs.forEach(function(tab) {
                    urls[tab.id] = tab.url;
                });
            }
        };

        const updateTabCallback = function(tabId, changeinfo, tab) {
            if (changeinfo.url) {
                urls[tabId] = changeinfo.url;
            }
        };

        // Not all tabs will fire an update event. If the page is pre-rendered,
        // a replace will happen instead.
        const tabReplacedCallback = function(newTabId, oldTabId) {
            delete urls[oldTabId];
            chrome.tabs.get(newTabId, function(tab) {
                urls[tab.id] = tab.url;
            });
        };

        const removeTabCallback = function(tabId) {
            closeListeners.forEach(function(fn) {
                fn(urls[tabId]);
            });
            delete urls[tabId];
        };

        // init
        chrome.tabs.query({}, queryTabsCallback);
        chrome.tabs.onUpdated.addListener(updateTabCallback);
        chrome.tabs.onRemoved.addListener(removeTabCallback);
        chrome.tabs.onReplaced.addListener(tabReplacedCallback);

        return {
            getUrlFromId: function(id) {
                return urls[id];
            }
        };
    })();
}
<|endoftext|>


<commit_before>/*!
 * Bootstrap Fileselect v1.1
 * https://github.com/Neoflow/Bootstrap-Fileselect
 *
 * Released under the MIT license
 * https://github.com/Neoflow/Bootstrap-Fileselect/blob/master/LICENSE.md
 */
(function(b,c){var a=function(e,d){this.$fileInput=c(e);this.options=d;this.metadata=this.$fileInput.data();this.$inputGroup=c("
").addClass("input-group");this.$inputGroupBtn=c("").addClass("input-group-btn");this.$browseBtn=c("");this.$labelInput=c("<input>").attr("type","text").attr("readonly",true).addClass("form-control");this.translations={en:{browse:"Browse",rules:{limit:"The number of uploadable files is limited to [num] file(s)",filelimit:"The files are restricted to following file extensions: [ext]"}},de:{browse:"Durchsuchen",rules:{limit:"Die Anzahl der hochladbaren Dateien ist limitiert auf [num] Datei(en)",extensions:"Die Dateien sind eingeschränkt auf folgende Dateierweiterungen: [ext]"}}}};a.prototype={defaults:{browseBtnClass:"btn btn-primary",browseIcon:'',limit:false,extensions:false,language:false},init:function(){this.config=this.loadConfig();this.translations=this.loadTranslation();this.$fileInput.hide().after(this.$inputGroup);this.$inputGroup.append(this.$inputGroupBtn,this.$labelInput);this.$inputGroupBtn.append(this.$browseBtn).append(this.$fileInput);this.$browseBtn.addClass(this.config.browseBtnClass).text(this.translations.browse).append(" …");if(this.config.browseIcon){this.$browseBtn.prepend(this.config.browseIcon,"  ")}this.$fileInput.on("change",c.proxy(this.changeEvent,this));return this},changeEvent:function(g){var f=this.$fileInput[0].files,d=c.map(f,function(e){return e.name}).join(", ");if(this.validateLimit(f)&&this.valiateExtensions(f)){this.$labelInput.val(d);return true}this.$fileInput.val(null);return false},loadConfig:function(){var d=c.extend({},this.defaults,this.options,this.metadata);if(typeof d.extensions==="string"){d.extensions=d.extensions.split(",")}return d},loadTranslation:function(){var e=this.config.language||navigator.language||navigator.userLanguage,d=c.map(this.translations,function(f,g){return g});if(c.inArray(e,d)===-1){e="en"}return this.translations[e]},validateLimit:function(d){if(this.config.limit&&d.length>parseInt(this.config.limit)){alert(this.translations.rules.limit.replace("[num]",this.config.limit));return false}return true},valiateExtensions:function(e){var d=true;if(this.config.extensions){c.each(e,c.proxy(function(g,f){var h=f.name.replace(/^.*\./,"").toLowerCase();if(c.inArray(h,this.config.extensions)===-1){alert(this.translations.rules.extensions.replace("[ext]",this.config.extensions.join(", ")));d=false;return d}},this))}return d}};a.defaults=a.prototype.defaults;c.fn.fileselect=function(d){return this.each(function(){new a(this,d).init()})};b.Fileselect=a})(window,jQuery);<commit_msg>Created minified<commit_after>/*!
 * Bootstrap Fileselect v1.2
 * https://github.com/Neoflow/Bootstrap-Fileselect
 *
 * Released under the MIT license
 * https://github.com/Neoflow/Bootstrap-Fileselect/blob/master/LICENSE.md
 */
(function(b,c){var a=function(e,d){this.$fileInput=c(e);this.options=d;this.metadata=this.$fileInput.data();this.$inputGroup=c("
").addClass("input-group");this.$inputGroupBtn=c("").addClass("input-group-btn");this.$browseBtn=c("");this.$labelInput=c("<input>").attr("type","text").attr("readonly",true).addClass("form-control");this.translations={en:{browse:"Browse",rules:{numberOfFiles:"The number of uploadable files is limited to [num] file(s)",fileExtensions:"The files are restricted to following file extensions: [ext]",fileSize:"The file size is limited to [size]"}},de:{browse:"Durchsuchen",rules:{numberOfFiles:"Die Anzahl der hochladbaren Dateien ist limitiert auf [num] Datei(en)",fileExtensions:"Die Dateien sind eingeschränkt auf folgende Dateierweiterungen: [ext]",fileSize:"Die Grösse ist eingeschränkt auf [size] pro Datei"}}}};a.prototype={defaults:{browseBtnClass:"btn btn-primary",browseIcon:'',limit:false,extensions:false,allowedFileSize:false,allowedFileExtensions:false,allowedNumberOfFiles:false,language:false},init:function(){this.config=this.loadConfig();this.translations=this.loadTranslation();this.$fileInput.hide().after(this.$inputGroup);this.$inputGroup.append(this.$inputGroupBtn,this.$labelInput);this.$inputGroupBtn.append(this.$browseBtn).append(this.$fileInput);this.$browseBtn.addClass(this.config.browseBtnClass).text(this.translations.browse).append(" …");if(this.config.browseIcon){this.$browseBtn.prepend(this.config.browseIcon,"  ")}this.$fileInput.on("change",c.proxy(this.changeEvent,this));return this},changeEvent:function(g){var f=this.$fileInput[0].files,d=c.map(f,function(e){return e.name}).join(", ");if(this.validateNumberOfFiles(f)&&this.valiateFileExtensions(f)&&this.validateFileSize(f)){this.$labelInput.val(d);return true}this.$fileInput.val(null);return false},loadConfig:function(){var d=c.extend({},this.defaults,this.options,this.metadata);if(typeof d.extensions==="string"){d.extensions=d.extensions.split(",")}return d},loadTranslation:function(){var e=this.config.language||navigator.language||navigator.userLanguage,d=c.map(this.translations,function(f,g){return g});if(c.inArray(e,d)===-1){e="en"}return this.translations[e]},validateNumberOfFiles:function(d){if(this.config.allowedNumberOfFiles&&d.length>parseInt(this.config.allowedNumberOfFiles)){alert(this.translations.rules.allowedNumberOfFiles.replace("[num]",this.config.allowedNumberOfFiles));return false}return true},valiateFileExtensions:function(e){var d=true;if(this.config.allowedFileExtensions){c.each(e,c.proxy(function(g,f){var h=f.name.replace(/^.*\./,"").toLowerCase();if(c.inArray(h,this.config.allowedFileExtensions)===-1){alert(this.translations.rules.fileExtensions.replace("[ext]",this.config.allowedFileExtensions.join(", ")));d=false;return d}},this))}return d},validateFileSize:function(e){var d=true;if(this.config.allowedFileSize){c.each(e,c.proxy(function(g,f){if(f.size>this.config.allowedFileSize){alert(this.translations.rules.fileSize.replace("[size]",Math.round(this.config.allowedFileSize/1024/1024)+"MB"));d=false;return d}},this))}return d}};a.defaults=a.prototype.defaults;c.fn.fileselect=function(d){return this.each(function(){new a(this,d).init()})};b.Fileselect=a})(window,jQuery);<|endoftext|>


<commit_before>var Util = require('./util.js');

/**
 * A mesh-based distorter. Based on
 * https://github.com/mrdoob/three.js/blob/dev/examples/js/effects/CardboardEffect.js.
 *
 * Works as follows:
 * 1. Create a tesselated quad.
 * 2. Distort the quad.
 * 3. Use the distorted quad to render
 */
function CardboardDistorter(renderer) {
  this.renderer = renderer;
  this.genuineRender = renderer.render;
  this.genuineSetSize = renderer.setSize;

  // Camera, scene and geometry to render the scene to a texture.
  this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

  var params = {
    minFilter: THREE.LinearFilter,
    magFilter: THREE.NearestFilter,
    format: THREE.RGBAFormat
  };
  this.renderTarget = new THREE.WebGLRenderTarget(512, 512, params);

	this.material = new THREE.MeshBasicMaterial({wireframe: true});
	//this.material = new THREE.MeshBasicMaterial({map: this.renderTarget});
  this.scene = new THREE.Scene();

  var geometry = this.createWarpMeshGeometry_();
  this.updateGeometry_(geometry);
}

CardboardDistorter.prototype.patch = function() {
  if (!this.isActive) {
    return;
  }

  this.renderer.render = function(scene, camera, renderTarget, forceClear) {
    this.genuineRender.call(this.renderer, scene, camera, this.renderTarget, forceClear);
  }.bind(this);

  this.renderer.setSize = function(width, height) {
    this.renderTarget.setSize(width, height);
    this.genuineSetSize.call(this.renderer, width, height);
  }.bind(this);
};

CardboardDistorter.prototype.unpatch = function() {
  if (!this.isActive) {
    return;
  }
  this.renderer.render = this.genuineRender;
  this.renderer.setSize = this.genuineSetSize;
};

CardboardDistorter.prototype.preRender = function() {
  if (!this.isActive) {
    return;
  }
  this.renderer.setRenderTarget(this.renderTarget);
};

CardboardDistorter.prototype.postRender = function() {
  if (!this.isActive) {
    return;
  }
  var size = this.renderer.getSize();
  this.renderer.setViewport(0, 0, size.width, size.height);
  this.genuineRender.call(this.renderer, this.scene, this.camera);
};

/**
 * Toggles distortion. This is called externally by the boilerplate.
 * It should be enabled only if WebVR is provided by polyfill.
 */
CardboardDistorter.prototype.setActive = function(state) {
  this.isActive = state;
};

/**
 * Called whenever the device info changes. At this point we need to
 * re-calculate the distortion mesh.
 */
CardboardDistorter.prototype.updateDeviceInfo = function(deviceInfo) {
  var geometry = this.createWarpMeshGeometry2_(deviceInfo);
  this.updateGeometry_(geometry);
};

/**
 * Creates a warp mesh that is applied to the scene (which is rendered to a
 * texture).
 */
CardboardDistorter.prototype.createWarpMeshGeometry_ = function() {
	var distortion = new THREE.Vector2( 0.441, 0.156 );

	var geometry = new THREE.PlaneBufferGeometry( 1, 1, 10, 20 );
	// Original line, but it doesn't work:
  // var geometry = new THREE.PlaneBufferGeometry( 1, 1, 10, 20 ).removeAttribute( 'normal' ).toNonIndexed();

	var positions = geometry.attributes.position.array;
	var uvs = geometry.attributes.uv.array;

	// duplicate

	var positions2 = new Float32Array( positions.length * 2 );
	positions2.set( positions );
	positions2.set( positions, positions.length );

	var uvs2 = new Float32Array( uvs.length * 2 );
	uvs2.set( uvs );
	uvs2.set( uvs, uvs.length );

	var vector = new THREE.Vector2();
	var length = positions.length / 3;

	for ( var i = 0, l = positions2.length / 3; i < l; i ++ ) {

		vector.x = positions2[ i * 3 + 0 ];
		vector.y = positions2[ i * 3 + 1 ];

		var dot = vector.dot( vector );
		var scalar = 1.5 + ( distortion.x + distortion.y * dot ) * dot;

		var offset = i < length ? 0 : 1;

		positions2[ i * 3 + 0 ] = ( vector.x / scalar ) * 1.5 - 0.5 + offset;
		positions2[ i * 3 + 1 ] = ( vector.y / scalar ) * 3.0;

		uvs2[ i * 2 ] = ( uvs2[ i * 2 ] + offset ) * 0.5;

	}

	geometry.attributes.position.array = positions2;
	geometry.attributes.uv.array = uvs2;

  return geometry;
};

CardboardDistorter.prototype.createWarpMeshGeometry2_ = function(deviceInfo) {
  var distortedProj = deviceInfo.getProjectionMatrixLeftEye();
  var undistortedProj = deviceInfo.getProjectionMatrixLeftEye(true);
  var viewport = deviceInfo.getUndistortedViewportLeftEye();

  var device = deviceInfo.device;
  var params = {
    xScale: viewport.width / (device.width / 2),
    yScale: viewport.height / device.height,
    xTrans: 2 * (viewport.x + viewport.width / 2) / (device.width / 2) - 1,
    yTrans: 2 * (viewport.y + viewport.height / 2) / device.height - 1
  }

  this.projectionLeft = Util.projectionMatrixToVector_(distortedProj);
  this.unprojectionLeft = Util.projectionMatrixToVector_(undistortedProj, params);

  /*
  this.projectionLeft = new THREE.Vector4(1.0, 1.0, -0.5, -0.5);
  this.unprojectionLeft = new THREE.Vector4(1.0, 1.0, -0.5, -0.5);
  */
  this.projectionRight = Util.leftProjectionVectorToRight_(this.projectionLeft);
  this.unprojectionRight = Util.leftProjectionVectorToRight_(this.unprojectionLeft);

  this.distortion = new THREE.Vector2();
  this.distortion.fromArray(deviceInfo.viewer.distortionCoefficients);

  // Calculate the distortion mesh (this is a port of https://goo.gl/LgpmzU).
  var geometry = new THREE.PlaneBufferGeometry(1, 1, 40, 40);
  var indices = geometry.index.array;
  var positions = geometry.attributes.position.array;
  var uvs = geometry.attributes.uv.array;

  // Go through the triangle strip and distort each vertex.
  var vector = new THREE.Vector2();
  var length = Math.round(indices.length / 3) + 1;
  for (var i = 0; i < length; i++) {
    vector.x = positions[i * 3 + 0];
    vector.y = positions[i * 3 + 1];

    // Vectors should be in [0, 1]^2.
    vector.x += 0.5;
    vector.y += 0.5;

    // Now we split screen coordinates into left and right eye coordinates, each
    // into [0, 1]^2.
    var isLeft = (vector.x < 0.5)
    var offset = (isLeft ? 0 : 0.5);
    vector.x = (vector.x - offset) * 2;

    // Next, apply barrel distortion.
    vector = this.distort_(vector, isLeft);

    // Convert from eye into screen coordinates.
    vector.x = vector.x / 2 + offset;

    // We are in [0, 1], but need to ultimately convert to [-1, 1] to cover the
    // whole orthographic camera frustum.
    vector.x = (vector.x - 0.5) * 2;
    vector.y = (vector.y - 0.5) * 2;

    positions[i * 3 + 0] = vector.x;
    positions[i * 3 + 1] = vector.y;
  }

  return geometry;
};

CardboardDistorter.prototype.updateGeometry_ = function(geometry) {
  // Remove all objects from the scene.
  var scene = this.scene;
  scene.traverse(function(child) {
    scene.remove(child);
  });

  // Add this mesh to the scene.
	var mesh = new THREE.Mesh(geometry, this.material);
  this.scene.add(mesh);
};

/**
 * Given a vector in [0, 1], distort it
 *
 * @param {Vector2} vec
 * @param {Boolean} isLeft True iff it's the left eye. False otherwise.
 */
CardboardDistorter.prototype.distort_ = function(vector, isLeft) {
  /*
  var dot = vector.dot( vector );
  var scalar = 1.0 + ( this.distortion.x + this.distortion.y * dot ) * dot;
  vector.divideScalar(scalar);
  return vector;
  */

  var proj = isLeft ? this.projectionLeft : this.projectionRight;
  var unproj = isLeft ? this.unprojectionLeft : this.unprojectionRight;
  return this.barrel_(vector, proj, unproj, this.distortion);
};

/**
 * @param {THREE.Vector2} vec
 * @param {THREE.Vector4} projection
 * @param {THREE.Vector4} unprojection
 *
 * @return {THREE.Vector2} Barrel distorted version of vec.
 */
CardboardDistorter.prototype.barrel_ = function(vec, projection, unprojection, distortion) {
  // 'vec2 w = (v + unprojection.zw) / unprojection.xy;',
  var w = new THREE.Vector2();
  w.x = (vec.x + unprojection.z) / unprojection.x;
  w.y = (vec.y + unprojection.w) / unprojection.y;

  // 'return projection.xy * (poly(dot(w, w)) * w) - projection.zw;',
  var out = new THREE.Vector2();
  w.multiplyScalar(this.poly_(w.dot(w), distortion));
  out.x = projection.x * w.x - projection.z;
  out.y = projection.y * w.y - projection.w;

  return out;
};

/**
 * @return {Number} Polynomial output of the distorter.
 */
CardboardDistorter.prototype.poly_ = function(val, distortion) {
  if (this.showCenter && val < 0.001) {
    return 10000;
  }
  return 1.0 + (distortion.x + distortion.y * val) * val;
};

module.exports = CardboardDistorter;
<commit_msg>Update distortion mesh.<commit_after>var Util = require('./util.js');

/**
 * A mesh-based distorter. Based on
 * https://github.com/mrdoob/three.js/blob/dev/examples/js/effects/CardboardEffect.js.
 *
 * Works as follows:
 * 1. Create a tesselated quad.
 * 2. Distort the quad.
 * 3. Use the distorted quad to render
 */
function CardboardDistorter(renderer) {
  this.renderer = renderer;
  this.genuineRender = renderer.render;
  this.genuineSetSize = renderer.setSize;

  // Camera, scene and geometry to render the scene to a texture.
  this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);

  var params = {
    minFilter: THREE.LinearFilter,
    magFilter: THREE.NearestFilter,
    format: THREE.RGBAFormat
  };
  this.renderTarget = new THREE.WebGLRenderTarget(512, 512, params);

	//this.material = new THREE.MeshBasicMaterial({wireframe: true});
	this.material = new THREE.MeshBasicMaterial({map: this.renderTarget});
  //this.material = new THREE.MeshBasicMaterial({map: THREE.ImageUtils.loadTexture('img/UV_Grid_Sm.jpg')});
  this.scene = new THREE.Scene();

  var geometry = this.createWarpMeshGeometry_();
  this.updateGeometry_(geometry);
}

CardboardDistorter.prototype.patch = function() {
  if (!this.isActive) {
    return;
  }

  this.renderer.render = function(scene, camera, renderTarget, forceClear) {
    this.genuineRender.call(this.renderer, scene, camera, this.renderTarget, forceClear);
  }.bind(this);

  this.renderer.setSize = function(width, height) {
    this.renderTarget.setSize(width, height);
    this.genuineSetSize.call(this.renderer, width, height);
  }.bind(this);
};

CardboardDistorter.prototype.unpatch = function() {
  if (!this.isActive) {
    return;
  }
  this.renderer.render = this.genuineRender;
  this.renderer.setSize = this.genuineSetSize;
};

CardboardDistorter.prototype.preRender = function() {
  if (!this.isActive) {
    return;
  }
  this.renderer.setRenderTarget(this.renderTarget);
};

CardboardDistorter.prototype.postRender = function() {
  if (!this.isActive) {
    return;
  }
  var size = this.renderer.getSize();
  this.renderer.setViewport(0, 0, size.width, size.height);
  this.genuineRender.call(this.renderer, this.scene, this.camera);
};

/**
 * Toggles distortion. This is called externally by the boilerplate.
 * It should be enabled only if WebVR is provided by polyfill.
 */
CardboardDistorter.prototype.setActive = function(state) {
  this.isActive = state;
};

/**
 * Called whenever the device info changes. At this point we need to
 * re-calculate the distortion mesh.
 */
CardboardDistorter.prototype.updateDeviceInfo = function(deviceInfo) {
  var geometry = this.createWarpMeshGeometry2_(deviceInfo);
  this.updateGeometry_(geometry);
};

/**
 * Creates a warp mesh that is applied to the scene (which is rendered to a
 * texture).
 */
CardboardDistorter.prototype.createWarpMeshGeometry_ = function() {
	var distortion = new THREE.Vector2( 0.441, 0.156 );

	//var geometry = new THREE.PlaneBufferGeometry( 1, 1, 10, 20 );
	// Original line, but it doesn't work:
  var geometry = new THREE.PlaneBufferGeometry( 1, 1, 20, 40 ).removeAttribute( 'normal' ).toNonIndexed();

	var positions = geometry.attributes.position.array;
	var uvs = geometry.attributes.uv.array;

	// duplicate

	var positions2 = new Float32Array( positions.length * 2 );
	positions2.set( positions );
	positions2.set( positions, positions.length );

	var uvs2 = new Float32Array( uvs.length * 2 );
	uvs2.set( uvs );
	uvs2.set( uvs, uvs.length );

	var vector = new THREE.Vector2();
	var length = positions.length / 3;

	for ( var i = 0, l = positions2.length / 3; i < l; i ++ ) {

		vector.x = positions2[ i * 3 + 0 ];
		vector.y = positions2[ i * 3 + 1 ];

		var dot = vector.dot( vector );
		var scalar = 1.5 + ( distortion.x + distortion.y * dot ) * dot;

		var offset = i < length ? 0 : 1;

		positions2[ i * 3 + 0 ] = ( vector.x / scalar ) * 1.5 - 0.5 + offset;
		positions2[ i * 3 + 1 ] = ( vector.y / scalar ) * 3.0;

		uvs2[ i * 2 ] = ( uvs2[ i * 2 ] + offset ) * 0.5;

	}

	geometry.attributes.position.array = positions2;
	geometry.attributes.uv.array = uvs2;

  return geometry;
};

CardboardDistorter.prototype.createWarpMeshGeometry2_ = function(deviceInfo) {
  var distortedProj = deviceInfo.getProjectionMatrixLeftEye();
  var undistortedProj = deviceInfo.getProjectionMatrixLeftEye(true);
  var viewport = deviceInfo.getUndistortedViewportLeftEye();

  var device = deviceInfo.device;
  var params = {
    xScale: viewport.width / (device.width / 2),
    yScale: viewport.height / device.height,
    xTrans: 2 * (viewport.x + viewport.width / 2) / (device.width / 2) - 1,
    yTrans: 2 * (viewport.y + viewport.height / 2) / device.height - 1
  }

  this.projectionLeft = Util.projectionMatrixToVector_(distortedProj);
  this.unprojectionLeft = Util.projectionMatrixToVector_(undistortedProj, params);

  /*
  this.projectionLeft = new THREE.Vector4(1.0, 1.0, -0.5, -0.5);
  this.unprojectionLeft = new THREE.Vector4(1.0, 1.0, -0.5, -0.5);
  */
  this.projectionRight = Util.leftProjectionVectorToRight_(this.projectionLeft);
  this.unprojectionRight = Util.leftProjectionVectorToRight_(this.unprojectionLeft);

  this.distortion = new THREE.Vector2();
  this.distortion.fromArray(deviceInfo.viewer.distortionCoefficients);

  // Calculate the distortion mesh (this is a port of https://goo.gl/LgpmzU).
  //var geometry = new THREE.PlaneBufferGeometry(1, 2, 10, 20);
  var geometry = new THREE.PlaneBufferGeometry(1, 2, 10, 20).removeAttribute('normal').toNonIndexed();
  var eyePositions = geometry.attributes.position.array;
  var eyeUvs = geometry.attributes.uv.array;

  // Distortion mesh consists of two eye meshes, each one independent of the
  // other. So we take the original (half) geometry created above, duplicate it
  // and translate it.
	var positions = new Float32Array(eyePositions.length * 2);
	positions.set(eyePositions);
	positions.set(eyePositions, eyePositions.length);

	uvs = new Float32Array(eyeUvs.length * 2);
	uvs.set(eyeUvs);
	uvs.set(eyeUvs, eyeUvs.length);

  // Go through the triangle strip and distort each vertex.
  var vector = new THREE.Vector2();
  var length = uvs.length/2;
  for (var i = 0; i < length; i++) {
    vector.x = uvs[i * 2 + 0];
    vector.y = uvs[i * 2 + 1];

    // Now we split screen coordinates into left and right eye coordinates, each
    // into [0, 1]^2.
    var isLeft = i < length/2;
    var uvOffset = (isLeft ? 0 : 0.5);

    // Next, apply barrel distortion.
    vector = this.distort_(vector, isLeft);

    // Convert from eye into screen coordinates.
    vector.x = vector.x / 2 + uvOffset;

    uvs[i * 2 + 0] = vector.x;
    uvs[i * 2 + 1] = vector.y;

    var positionOffset = (isLeft ? -0.5 : 0.5);
    positions[i * 3] = positions[i * 3] + positionOffset;
  }

  // Use both eyes in the final geometry.
	geometry.attributes.position.array = positions;
	geometry.attributes.uv.array = uvs;
  return geometry;
};

CardboardDistorter.prototype.updateGeometry_ = function(geometry) {
  // Remove all objects from the scene.
  var scene = this.scene;
  scene.traverse(function(child) {
    scene.remove(child);
  });

  // Add this mesh to the scene.
	var mesh = new THREE.Mesh(geometry, this.material);
  this.scene.add(mesh);
};

/**
 * Given a vector in [0, 1], distort it
 *
 * @param {Vector2} vec
 * @param {Boolean} isLeft True iff it's the left eye. False otherwise.
 */
CardboardDistorter.prototype.distort_ = function(vector, isLeft) {
  /*
  var dot = vector.dot( vector );
  var scalar = 1.0 + ( this.distortion.x + this.distortion.y * dot ) * dot;
  vector.divideScalar(scalar);
  return vector;
  */

  var proj = isLeft ? this.projectionLeft : this.projectionRight;
  var unproj = isLeft ? this.unprojectionLeft : this.unprojectionRight;
  return this.barrel_(vector, proj, unproj, this.distortion);
};

/**
 * @param {THREE.Vector2} vec
 * @param {THREE.Vector4} projection
 * @param {THREE.Vector4} unprojection
 *
 * @return {THREE.Vector2} Barrel distorted version of vec.
 */
CardboardDistorter.prototype.barrel_ = function(vec, projection, unprojection, distortion) {
  // 'vec2 w = (v + unprojection.zw) / unprojection.xy;',
  var w = new THREE.Vector2();
  w.x = (vec.x + unprojection.z) / unprojection.x;
  w.y = (vec.y + unprojection.w) / unprojection.y;

  // 'return projection.xy * (poly(dot(w, w)) * w) - projection.zw;',
  var out = new THREE.Vector2();
  w.multiplyScalar(this.poly_(w.dot(w), distortion));
  out.x = projection.x * w.x - projection.z;
  out.y = projection.y * w.y - projection.w;

  return out;
};

/**
 * @return {Number} Polynomial output of the distorter.
 */
CardboardDistorter.prototype.poly_ = function(val, distortion) {
  if (this.showCenter && val < 0.001) {
    return 10000;
  }
  return 1.0 + (distortion.x + distortion.y * val) * val;
};

module.exports = CardboardDistorter;
<|endoftext|>


<commit_before><commit_msg>Fix export sound on Android in Abecedarium<commit_after><|endoftext|>