Commit bd5123efcee6e52d5183ff0276274005e0c88d82

Authored by Adabriand Furtado
1 parent e8e3a9d2
Exists in master

Refat. do wikilibras.js - criação do módulo de ícones, de menu de conf., de seleção e de render.

Showing 38 changed files with 4003 additions and 3904 deletions   Show diff stats
view/assets/css/main.css
... ... @@ -254,7 +254,7 @@ body {
254 254 }
255 255  
256 256 /* Configuration Panel */
257   -#configuration-panel {
  257 +#configuration-menu {
258 258 background-color: #556575;
259 259 border-style: solid;
260 260 border-color: #9cbfe3;
... ... @@ -263,7 +263,7 @@ body {
263 263 padding: 10px 10px 5px 5px;
264 264 }
265 265  
266   -.configuration-panel-label {
  266 +.configuration-menu-label {
267 267 color: #FFFFFF;
268 268 font-family: 'Titillium Web', sans-serif;
269 269 font-size: 14px;
... ...
view/assets/js/articulation.js
... ... @@ -1,143 +0,0 @@
1   -(function(articulation, $, undefined) {
2   -
3   - var server_host = '';
4   - var MAX_COLUMNS = 14;
5   -
6   - function _updateASelector(container, ballSelector, step) {
7   - var pointSelector = parseInt(step) == 2 ? 'A' : 'B';
8   - $(container + ' .ball-selector.active').each(function() {
9   - $(this).removeClass('active');
10   - $(this).find('.point-selector').remove();
11   - });
12   - ballSelector.addClass('active');
13   - ballSelector.append('<div class="point-selector"><img src="'
14   - + server_host + '/img/pa/' + pointSelector
15   - + '-Seletor.png" class="point-selector" alt=""></div>');
16   - $(container + ' .selection-panel-option[select=true]').attr('select',
17   - false);
18   - $(ballSelector).attr('select', true);
19   - }
20   -
21   - function _getSelectedY(hand, subConfig, step) {
22   - step = parseInt(step) - 1;
23   - var previousStepId = '.selection-panel-body[mainConfig=' + hand
24   - + '][subConfig=' + subConfig + '][step=' + step
25   - + '] .module-x-y';
26   - return $(previousStepId).attr('data-y');
27   - }
28   -
29   - function _setupModuleZ(hand, subConfig, step, selectedY) {
30   - if (typeof selectedY == 'undefined' || selectedY == '')
31   - return;
32   -
33   - var base_id = '.selection-panel-body[mainConfig=' + hand
34   - + '][subConfig=' + subConfig + '][step=' + step + ']';
35   - var articulation_z = base_id + ' .module-z';
36   - $(articulation_z + ' .ball-selector').hide();
37   - $(articulation_z + ' .row-number-' + selectedY + ' .ball-selector')
38   - .show();
39   -
40   - var z = $(articulation_z).attr('data-z');
41   - if (typeof z != 'undefined') {
42   - var ball_selector = $(articulation_z + ' .row-number-' + selectedY
43   - + ' .ball-' + z);
44   - _updateASelector(articulation_z, ball_selector, step);
45   - }
46   - }
47   -
48   - function _setupBallSelectorXY(hand, subConfig, step) {
49   - var base_id = '.selection-panel-body[mainConfig=' + hand
50   - + '][subConfig=' + subConfig + '][step=' + step + ']';
51   - var articulation_x_y = base_id + ' .module-x-y';
52   - $(articulation_x_y + ' .ball-selector')
53   - .off('click')
54   - .on(
55   - 'click',
56   - function(a) {
57   - var b = $(a.target);
58   - if (!b.hasClass('ball-selector')) {
59   - dynworkflow.userSelectedAnOption();
60   - return;
61   - }
62   - var c = b.parent('.grid-row'), d = $(articulation_x_y), f = b
63   - .attr('data-x'), g = c.attr('data-y');
64   - d.attr('data-x', f), d.attr('data-y', g);
65   -
66   - var nextStep = parseInt(step) + 1;
67   - _updateASelector(articulation_x_y, b, nextStep);
68   - _setupModuleZ(hand, subConfig, nextStep, g);
69   -
70   - wikilibras.updateTempParameterJSON(hand, subConfig,
71   - step, f + ';' + g);
72   - dynworkflow.userSelectedAnOption();
73   - });
74   - }
75   -
76   - function _setupBallSelectorZ(hand, subConfig, step) {
77   - var base_id = '.selection-panel-body[mainConfig=' + hand
78   - + '][subConfig=' + subConfig + '][step=' + step + ']';
79   - var articulation_z = base_id + ' .module-z';
80   - $(articulation_z + ' .ball-selector').off('click').on(
81   - 'click',
82   - function(a) {
83   - var b = $(a.target);
84   - if (!b.hasClass('ball-selector')) {
85   - dynworkflow.userSelectedAnOption();
86   - return;
87   - }
88   - var c = b.parent('.grid-row'), e = $(articulation_z), h = b
89   - .attr('data-z');
90   - b.attr('data-z') && e.attr('data-z', h), _updateASelector(
91   - articulation_z, b, step);
92   -
93   - wikilibras
94   - .updateTempParameterJSON(hand, subConfig, step, h);
95   - dynworkflow.userSelectedAnOption();
96   - });
97   - }
98   -
99   - function _calculateArticulationPointIndex(hand, xValue, yValue, zValue) {
100   - var x = xValue;
101   - var y = yValue;
102   - var z = zValue;
103   - if (hand == 'left-hand') {
104   - x = MAX_COLUMNS - x + 1;
105   - }
106   -
107   - var value = (z - 1) * MAX_COLUMNS + x + 3 * MAX_COLUMNS * (y - 1);
108   - //console.log(value);
109   - return value;
110   - }
111   -
112   - articulation.processValue = function(hand, selectionArray) {
113   - var xyValueSplit = selectionArray[0].split(';');
114   - var xValue = parseInt(xyValueSplit[0]);
115   - var yValue = parseInt(xyValueSplit[1]);
116   - var zValue = parseInt(selectionArray[1]);
117   - return _calculateArticulationPointIndex(hand, xValue, yValue, zValue);
118   - };
119   -
120   - articulation.setupModuleXY = function(serverhost, hand, subConfig, step) {
121   - server_host = serverhost;
122   - _setupBallSelectorXY(hand, subConfig, step);
123   - };
124   -
125   - articulation.setupModuleZ = function(serverhost, hand, subConfig, step) {
126   - server_host = serverhost;
127   - _setupBallSelectorZ(hand, subConfig, step);
128   -
129   - var selectedY = _getSelectedY(hand, subConfig, step);
130   - _setupModuleZ(hand, subConfig, step, selectedY);
131   - };
132   -
133   - articulation.clean = function() {
134   - $('.ball-selector.active').each(function() {
135   - $(this).removeClass('active');
136   - $(this).find('.point-selector').remove();
137   - });
138   - $('.module-x-y').attr('data-x', '');
139   - $('.module-x-y').attr('data-y', '');
140   - $('.module-z').attr('data-z', '');
141   - }
142   -
143   -}(window.articulation = window.articulation || {}, jQuery));
view/assets/js/configuration-screen.js 0 → 100644
... ... @@ -0,0 +1,62 @@
  1 +(function(configurationScreen, $, undefined) {
  2 +
  3 + function _isMenuSelected() {
  4 + return $('#configuration-menu .icon_container[select=true]').length > 0;
  5 + }
  6 +
  7 + function _getCurrentMainConfiguration() {
  8 + return _isMenuSelected() ? $(
  9 + '#configuration-menu .icon_container[select=true]').attr(
  10 + 'name') : '';
  11 + }
  12 +
  13 + configurationScreen.isMenuSelected = function() {
  14 + return _isMenuSelected();
  15 + }
  16 +
  17 + configurationScreen.getCurrentMainConfiguration = function() {
  18 + return _getCurrentMainConfiguration();
  19 + }
  20 +
  21 + configurationScreen.setup = function() {
  22 + $('.icon_container').off('mouseover').on('mouseover', function() {
  23 + if (iconHelper.canHover(this)) {
  24 + iconHelper.enableIconHover(this, true);
  25 + }
  26 + });
  27 + $('.icon_container').off('mouseout').on('mouseout', function() {
  28 + if (iconHelper.canHover(this)) {
  29 + iconHelper.enableIconHover(this, false);
  30 + }
  31 + });
  32 + $('.config-menu-option').off('click').on('click', function() {
  33 + selectionPanel.show($(this).attr('panel'));
  34 + });
  35 + $('#minimize-icon-container').off('click').on('click', function() {
  36 + $('#ref-video-container').hide();
  37 + $('#minimize-icon-container').hide();
  38 + $('#maximize-icon-container').show();
  39 + });
  40 + $('#maximize-icon-container').off('click').on('click', function() {
  41 + $('#ref-video-container').show();
  42 + $('#maximize-icon-container').hide();
  43 + $('#minimize-icon-container').show();
  44 + });
  45 + selectionPanel.setup();
  46 + };
  47 +
  48 + function _showConfigurationScreen(toShow) {
  49 + if (toShow) {
  50 + $("#configuration-screen").show();
  51 + videoHelper.play("#ref-video-container video");
  52 + } else {
  53 + $("#configuration-screen").hide();
  54 + videoHelper.pause("#ref-video-container video");
  55 + }
  56 + }
  57 +
  58 + configurationScreen.show = function(toShow) {
  59 + _showConfigurationScreen(toShow);
  60 + }
  61 +
  62 +}(window.configurationScreen = window.configurationScreen || {}, jQuery));
... ...
view/assets/js/configuration.js
... ... @@ -1,43 +0,0 @@
1   -(function(configuration, $, undefined) {
2   -
3   - configuration.setupFingersGroup = function(hand, subConfig, step) {
4   - var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
5   - subConfig + '][step=' + step + ']';
6   - $(baseId + ' .selection-panel-option'
7   - ).off('click').on('click', function() {
8   - wikilibras.selectAnOption(baseId, this);
9   - _setupFingersToShow(hand, subConfig, step);
10   -
11   - dynworkflow.userSelectedAnOption();
12   - });
13   - };
14   -
15   - function _setupFingersToShow(hand, subConfig, step) {
16   - var stepOneBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
17   - subConfig + '][step=' + step + ']';
18   - var nextStep = parseInt(step) + 1;
19   - var stepTwoBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
20   - subConfig + '][step=' + nextStep + ']';
21   -
22   - var finger_group = $(stepOneBaseId + ' .selection-panel-option[select=true]').attr('value');
23   - finger_group = typeof finger_group == 'undefined' ? '0' : finger_group;
24   -
25   - // clean next step
26   - dynworkflow.cleanStep(hand, subConfig, nextStep);
27   - $(stepTwoBaseId + ' .finger-group').hide();
28   - $(stepTwoBaseId + ' .finger-group[group=' + finger_group + ']').show();
29   - }
30   -
31   - configuration.setupFingersPosition = function(hand, subConfig, step) {
32   - var stepTwoBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
33   - subConfig + '][step=' + step + ']';
34   - $(stepTwoBaseId + ' .selection-panel-option').off('click').on(
35   - 'click', function() {
36   - wikilibras.selectAnOption(stepTwoBaseId, this);
37   - dynworkflow.userSelectedAnOption();
38   - });
39   - var previousStep = parseInt(step) - 1;
40   - _setupFingersToShow(hand, subConfig, previousStep);
41   - };
42   -
43   -}(window.configuration = window.configuration || {}, jQuery));
view/assets/js/defaultConfigurationHandler.js
... ... @@ -1,27 +0,0 @@
1   -(function(defaultConfigurationHandler, $, undefined) {
2   -
3   - defaultConfigurationHandler.setup = function(hand, subConfig, step) {
4   - var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
5   - subConfig + '][step=' + step + ']';
6   - $(baseId + ' .selection-panel-option').off('click').on(
7   - 'click', function() {
8   - wikilibras.selectAnOption(baseId, this);
9   - dynworkflow.userSelectedAnOption();
10   - });
11   - };
12   -
13   - function _startVideoLoop(hand, subConfig, step, timeBetweenLoops) {
14   - setTimeout(function(){
15   - $('.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
16   - subConfig + '][step=' + step + '] video').each(function(){
17   - $(this).get(0).play();
18   - });
19   - _startVideoLoop(hand, subConfig, step, timeBetweenLoops);
20   - }, timeBetweenLoops);
21   - }
22   -
23   - defaultConfigurationHandler.startVideoLoop = function(hand, subConfig, step, timeBetweenLoops) {
24   - _startVideoLoop(hand, subConfig, step, timeBetweenLoops);
25   - }
26   -
27   -}(window.defaultConfigurationHandler = window.defaultConfigurationHandler || {}, jQuery));
view/assets/js/dynamic-loading-engine.js
... ... @@ -1,96 +0,0 @@
1   -(function(dynengine, $, undefined) {
2   - var setup = undefined;
3   -
4   - _preprocessHtml = function(data, url) {
5   - var matchSubConfig = data.match(/sub(?:C|c)onfig="(.*?)"/);
6   - var currentMainConfig = dynworkflow.getMainConfig(); // right-hand or left-hand
7   - var goodData = data;
8   -
9   - var isRightHand = function(hand) {
10   - return hand === 'right-hand';
11   - };
12   -
13   - var replaceConfigurationTag = function(data, mainConfig) {
14   - if (isRightHand(mainConfig)) {
15   - return data.replace(/{{ configuracao }}/g, 'cmd');
16   - } else {
17   - return data.replace(/{{ configuracao }}/g, 'cme');
18   - }
19   - }
20   -
21   - var replaceOrientationTag = function(data, mainConfig) {
22   - if (isRightHand(mainConfig)) {
23   - return data.replace(/{{ orientacao }}/g, 'ord');
24   - } else {
25   - return data.replace(/{{ orientacao }}/g, 'ore');
26   - }
27   - }
28   -
29   - var replaceHandFolderTag = function(data, mainConfig) {
30   - if (isRightHand(mainConfig)) {
31   - return data.replace(/{{ hand-folder }}/g, 'md');
32   - } else {
33   - return data.replace(/{{ hand-folder }}/g, 'me');
34   - }
35   - }
36   -
37   - var replaceMovementNameTag = function(data, mainConfig) {
38   - var selectedMovement = movement.getPreviousSelectedMovement(mainConfig);
39   - if (typeof selectedMovement != "undefined") {
40   - return data.replace(/{{ movement-name }}/g, selectedMovement);
41   - }
42   - return data
43   - }
44   -
45   - if (matchSubConfig) { // case defined
46   - // There is no specific(right or left hand dependent) assets for: articulacao, duracao, expressao, movimento, transicao
47   - // Specific configurations: configuracao, orientacao
48   - // possible values on the side as comment
49   - var subConfig = matchSubConfig[1]; // articulacao | configuracao | duracao | expressao | movimento | orientacao | transicao
50   -
51   - // possible subconfigs that need changing
52   - switch (subConfig) {
53   - case 'configuracao':
54   - goodData = replaceConfigurationTag(data, currentMainConfig);
55   - break;
56   - case 'configuracao-retilineo':
57   - goodData = replaceConfigurationTag(data, currentMainConfig);
58   - break;
59   - case 'orientacao':
60   - goodData = replaceOrientationTag(data, currentMainConfig);
61   - break;
62   - case 'orientacao-retilineo':
63   - goodData = replaceOrientationTag(data, currentMainConfig);
64   - break;
65   - }
66   - }
67   - goodData = replaceHandFolderTag(goodData, currentMainConfig);
68   - goodData = replaceMovementNameTag(goodData, currentMainConfig);
69   - goodData = goodData.replace(/{{ hand }}/g, currentMainConfig);
70   - return goodData.replace(/{{ server }}/g, url);
71   - };
72   -
73   - dynengine.render = function(serverUrl, templatePath, target, prepend, callback) {
74   - var url = serverUrl + templatePath;
75   - $.get(url, function(data) {
76   - var processedHtml = _preprocessHtml(data, serverUrl);
77   - if (prepend) {
78   - $(target).prepend(processedHtml);
79   - } else {
80   - $(target).append(processedHtml);
81   - }
82   - })
83   - .done(function() {
84   - callback && callback(); // call if defined
85   - });
86   - };
87   -
88   - dynengine.clean = function(target) {
89   - $(target).html('');
90   - };
91   -
92   - dynengine.load = function() {
93   - var url = $('#server-url').data('url');
94   - };
95   -
96   -}(window.dynengine = window.dynengine || {}, jQuery));
view/assets/js/dynamic-selection-workflow.js
... ... @@ -1,369 +0,0 @@
1   -(function(dynworkflow, $, undefined) {
2   -
3   - // Workflow configuration
4   - var jsonWF = {};
5   - var baseUrl = '';
6   -
7   - // Main configurations: right-hand, left-hand and facial
8   - var mainConfig = '';
9   - // The converted Main Config (right/left-hand) to hand for using the same configuration
10   - var preprocessedMainConfig = '';
11   - // Subconfigurations: movimento, articulacao, configuracao, orientacao, etc
12   - var currentSubconfig = '';
13   - var currentSubConfigName = '';
14   - var currentSubconfigParent = '';
15   - var currentStep = 0;
16   -
17   - function _preprocessMainConfig(config) {
18   - config = config.replace('right-hand', 'hand');
19   - config = config.replace('left-hand', 'hand');
20   - return config;
21   - }
22   -
23   - function _getFirstKey(json) {
24   - var first_key = undefined;
25   - for (first_key in json)
26   - break;
27   - return first_key;
28   - }
29   -
30   - function _getAttributes(json) {
31   - var result = [];
32   - for (attr in json) {
33   - result.push(attr);
34   - }
35   - return result;
36   - }
37   -
38   - function _updateAndGetFirstMovementSubConfig() {
39   - var selectedMovement = movement.getPreviousSelectedMovement(mainConfig);
40   - if (typeof selectedMovement == 'undefined')
41   - return -1;
42   -
43   - currentSubconfigParent = jsonWF[preprocessedMainConfig]['movimento'][selectedMovement];
44   - currentSubConfigName = _getFirstKey(currentSubconfigParent);
45   - return currentSubConfigName;
46   - }
47   -
48   - function _updateAndGetMovementConfig() {
49   - currentSubconfigParent = jsonWF[preprocessedMainConfig];
50   - currentSubConfigName = _getFirstKey(currentSubconfigParent);
51   - return currentSubConfigName;
52   - }
53   -
54   - function _getNextSubConfig(toForward) {
55   - var attrs = _getAttributes(currentSubconfigParent);
56   - for (var i = 0; i < attrs.length; i++) {
57   - if (toForward && attrs[i] == currentSubConfigName
58   - && i < attrs.length - 1) {
59   - return attrs[i + 1];
60   - } else if (!toForward && attrs[i] == currentSubConfigName && i >= 1) {
61   - return attrs[i - 1];
62   - }
63   - }
64   - if (toForward && currentSubConfigName == 'movimento') {
65   - return _updateAndGetFirstMovementSubConfig();
66   - } else if (!toForward && preprocessedMainConfig == 'hand') {
67   - return _updateAndGetMovementConfig();
68   - } else if (!toForward) {
69   - return currentSubConfigName;
70   - } else {
71   - return -1;
72   - }
73   - }
74   -
75   - function _showCurrentSubconfig() {
76   - _showSubconfiguration(mainConfig, currentSubConfigName, currentStep);
77   - }
78   -
79   - // It checks if a selection panel is already loaded
80   - function _isSubconfigurationPanelLoaded(mainConfig, subConfig, stepNumber) {
81   - var stepNumber = stepNumber + 1;
82   - return $('.selection-panel-body[mainConfig=' + mainConfig
83   - + '][subConfig=' + subConfig + '][step=' + stepNumber + ']').length > 0;
84   - }
85   -
86   - function _showLoadedSubconfigurationPanel(mainConfig, subConfig, stepNumber) {
87   - var stepNumber = stepNumber + 1;
88   - return $(
89   - '.selection-panel-body[mainConfig=' + mainConfig
90   - + '][subConfig=' + subConfig + '][step=' + stepNumber
91   - + ']').show();
92   - }
93   -
94   - // It renders or shows the requested selection panel
95   - function _showSubconfiguration(mainConfig, subConfig, stepNumber) {
96   - $('.selection-panel-body').hide();
97   - if (_isSubconfigurationPanelLoaded(mainConfig, subConfig, stepNumber)) {
98   - _showLoadedSubconfigurationPanel(mainConfig, subConfig, stepNumber);
99   - } else {
100   - var step = currentSubconfig[stepNumber];
101   - step = typeof step == 'undefined' ? 'passo-1' : step;
102   - dynengine.render(baseUrl, '/' + preprocessedMainConfig + '/'
103   - + subConfig + '/' + step + '.html', '#selection-panel',
104   - true);
105   - }
106   - _selectTimelineIcon(mainConfig, subConfig, true);
107   - }
108   -
109   - function _selectSubConfig(subConfig) {
110   - if (subConfig == 'movimento') {
111   - _updateAndGetMovementConfig();
112   - } else if (currentSubConfigName == 'movimento') {
113   - _updateAndGetFirstMovementSubConfig();
114   - }
115   - currentSubConfigName = subConfig;
116   - currentSubconfig = currentSubconfigParent[currentSubConfigName];
117   - currentStep = 0;
118   - _showCurrentSubconfig();
119   - }
120   -
121   - // It shows the next selection panel on the workflow
122   - function _showNextSubConfig() {
123   - _walkOnTheWorkflow(true);
124   - }
125   -
126   - function _showPreviousSubConfig() {
127   - _walkOnTheWorkflow(false);
128   - }
129   -
130   - function _walkOnTheWorkflow(toForward) {
131   - currentStep = toForward ? currentStep + 1 : currentStep - 1;
132   -
133   - if (currentStep >= 0 && currentStep < currentSubconfig.length) {
134   - _showCurrentSubconfig();
135   - } else {
136   - var nextSubConfig = _getNextSubConfig(toForward);
137   - if (nextSubConfig != -1) {
138   - _selectSubConfig(nextSubConfig);
139   - } else {
140   - wikilibras.hideSelectionPanel();
141   - }
142   - }
143   - }
144   -
145   - function _checkIfFinished(mainConfig, currentSubConfigName) {
146   - var numberOfSteps = currentSubconfig.length;
147   - var completedSteps = $('.selection-panel-body[mainConfig=' + mainConfig
148   - + '][subConfig=' + currentSubConfigName
149   - + '] .selection-panel-option[select=true]').length;
150   - return completedSteps != 0 && completedSteps == numberOfSteps;
151   - }
152   -
153   - // A callback function to be called when the user selects a option on a panel
154   - function _userSelectedAnOption() {
155   - if (_checkIfFinished(mainConfig, currentSubConfigName)) {
156   - _setupCheckIcon(mainConfig, currentSubConfigName);
157   - }
158   - _showNextSubConfig();
159   - }
160   -
161   - function _cleanStep(mainConfig, subConfig, step) {
162   - var baseId = '.selection-panel-body[mainConfig=' + mainConfig
163   - + '][subConfig=' + subConfig + '][step=' + step + ']';
164   - $(baseId + ' .selection-panel-option').removeAttr('select');
165   - var icon_id = '.subconfiguration-panel[mainConfig=' + mainConfig
166   - + '] .icon_container[json_name=' + subConfig + ']';
167   - $(icon_id).removeAttr('complete');
168   - }
169   -
170   - // Timeline functions
171   - function _selectTimelineIcon(mainConfig, subConfig) {
172   - var baseId = '.subconfiguration-panel[mainConfig=' + mainConfig
173   - + '] .subconfiguration-options';
174   - var iconContainer = '.icon_container[json_name=' + subConfig + ']';
175   - var iconId = baseId + ' ' + iconContainer;
176   -
177   - var previousSelected = $(baseId + ' .icon_container[select=true]')
178   - .attr('json_name');
179   - if (typeof previousSelected != 'undefined') {
180   - _deselectTimelineIcon(mainConfig, previousSelected);
181   - }
182   -
183   - wikilibras.enableIconHover($(iconId), true);
184   - $(iconId).attr('select', true);
185   - $(baseId).scrollTo(iconContainer, {
186   - 'offset' : -60,
187   - 'duration' : 750
188   - });
189   - }
190   -
191   - function _deselectTimelineIcon(mainConfig, subConfig) {
192   - var icon_id = '.subconfiguration-panel[mainConfig=' + mainConfig
193   - + '] .icon_container[json_name=' + subConfig + ']';
194   -
195   - if ($(icon_id + '[complete=true]').length > 0) {
196   - _setupCheckIcon(mainConfig, subConfig);
197   - } else {
198   - wikilibras.enableIconHover($(icon_id), false);
199   - $(icon_id).removeAttr('select');
200   - }
201   - }
202   -
203   - function _setupCheckIcon(mainConfig, subConfig) {
204   - var icon_id = $('.subconfiguration-panel[mainConfig=' + mainConfig
205   - + '] .icon_container[json_name=' + subConfig + ']');
206   - wikilibras.enableIconCheck(icon_id, true);
207   - $(icon_id).attr('complete', true);
208   - $(icon_id).attr('select', false);
209   - }
210   -
211   - function _isTimelineLoaded() {
212   - return $('.subconfiguration-panel[mainConfig=' + mainConfig + ']').length > 0;
213   - }
214   -
215   - function _setupTimelineListeners(timelineBaseId) {
216   - $(timelineBaseId + ' .icon_container[json_name]').off('click').on(
217   - 'click', function() {
218   - var subConfig = $(this).attr('json_name');
219   - _selectSubConfig(subConfig);
220   - });
221   - $(timelineBaseId + ' .icon_container[json_name]').off('mouseover').on(
222   - 'mouseover', function() {
223   - if (wikilibras.canHover(this)) {
224   - wikilibras.enableIconHover(this, true);
225   - }
226   - });
227   - $(timelineBaseId + ' .icon_container[json_name]').off('mouseout').on(
228   - 'mouseout', function() {
229   - if (wikilibras.canHover(this)) {
230   - wikilibras.enableIconHover(this, false);
231   - }
232   - });
233   - $(timelineBaseId + ' .arrow[name=right-arrow]').off('click').on(
234   - 'click', function() {
235   - _showNextSubConfig();
236   - });
237   - $(timelineBaseId + ' .arrow[name=left-arrow]').off('click').on('click',
238   - function() {
239   - _showPreviousSubConfig();
240   - });
241   - }
242   -
243   - function _setupTimelineIcons(timelineBaseId, toUpdate) {
244   - if (!toUpdate) {
245   - $(timelineBaseId).show();
246   - $(timelineBaseId + " .subconfiguration-options").scrollTo(0, 0);
247   - return;
248   - }
249   -
250   - $(timelineBaseId + ' .icon_container[json_name]').attr("active",
251   - "false");
252   - for ( var name in currentSubconfigParent) {
253   - $(timelineBaseId + ' .icon_container[json_name=' + name + ']')
254   - .attr("active", "true");
255   - }
256   -
257   - if (preprocessedMainConfig == 'hand') {
258   - $(timelineBaseId + ' .icon_container[json_name=movimento]').attr(
259   - "active", "true");
260   - _setupCheckIcon(mainConfig, 'movimento');
261   - }
262   - _selectTimelineIcon(mainConfig, currentSubConfigName);
263   - _setupTimelineListeners(timelineBaseId);
264   - $(timelineBaseId).show();
265   - }
266   -
267   - function _setupTimeline(toUpdate) {
268   - var timelineBaseId = '.subconfiguration-panel[mainConfig=' + mainConfig
269   - + ']';
270   - if (_isTimelineLoaded()) {
271   - _setupTimelineIcons(timelineBaseId, toUpdate);
272   - } else {
273   - dynengine.render(baseUrl, '/' + preprocessedMainConfig
274   - + '/timeline.html', '#selection-panel', false, function() {
275   - _setupTimelineIcons(timelineBaseId, true);
276   - });
277   - }
278   - }
279   -
280   - function _initTimeline() {
281   - if (preprocessedMainConfig != 'hand' || _isTimelineLoaded()) {
282   - _setupTimeline(false);
283   - }
284   - }
285   -
286   - function _cleanTimeline() {
287   - $(".subconfiguration-panel").remove();
288   - }
289   -
290   - function _cleanPreviousLoadedPanel() {
291   - $('.selection-panel-body[mainConfig=' + mainConfig + ']').each(
292   - function() {
293   - var subConfigName = $(this).attr("subConfig");
294   - if (subConfigName.indexOf("articulacao") != -1
295   - || subConfigName.indexOf("configuracao") != -1
296   - || subConfigName.indexOf("orientacao") != -1
297   - || subConfigName.indexOf("movimento") != -1) {
298   - return;
299   - }
300   - $(
301   - '.selection-panel-body[mainConfig=' + mainConfig
302   - + '][subConfig=' + subConfigName + ']')
303   - .remove();
304   - });
305   - }
306   -
307   - // Public methods
308   - dynworkflow.selectMainConfig = function(config) {
309   - mainConfig = config;
310   - preprocessedMainConfig = _preprocessMainConfig(mainConfig);
311   - currentSubconfigParent = jsonWF[preprocessedMainConfig];
312   - currentSubConfigName = _getFirstKey(currentSubconfigParent);
313   - currentSubconfig = currentSubconfigParent[currentSubConfigName];
314   - currentStep = 0;
315   -
316   - _showCurrentSubconfig();
317   - };
318   -
319   - dynworkflow.selectMovement = function(movement) {
320   - var subconfigJSON = currentSubconfig[movement];
321   - currentSubConfigName = _getFirstKey(subconfigJSON);
322   - currentSubconfigParent = subconfigJSON;
323   - currentSubconfig = subconfigJSON[currentSubConfigName];
324   - currentStep = 0;
325   -
326   - _cleanPreviousLoadedPanel();
327   - _showCurrentSubconfig();
328   - _setupTimeline(true);
329   - };
330   -
331   - dynworkflow.selectSubConfig = function(subConfig) {
332   - _selectSubConfig(subConfig);
333   - };
334   -
335   - dynworkflow.userSelectedAnOption = function() {
336   - _userSelectedAnOption();
337   - };
338   -
339   - dynworkflow.cleanStep = function(mainConfig, subConfig, step) {
340   - _cleanStep(mainConfig, subConfig, step);
341   - };
342   -
343   - dynworkflow.getFacialParameters = function() {
344   - return _getAttributes(jsonWF['facial']);
345   - };
346   -
347   - dynworkflow.getMovementParameters = function(movementName) {
348   - return _getAttributes(jsonWF['hand']['movimento'][movementName]);
349   - };
350   -
351   - dynworkflow.getMainConfig = function() {
352   - return mainConfig;
353   - };
354   -
355   - dynworkflow.initTimeline = function() {
356   - _initTimeline();
357   - };
358   -
359   - dynworkflow.load = function() {
360   - baseUrl = $('#server-url').data('url');
361   - $.get(baseUrl + '/conf/selection-workflow-json', function(result) {
362   - jsonWF = $.parseJSON(result);
363   - }).fail(function() {
364   - console.log('Failed to load the workflow configuration');
365   - });
366   - _cleanTimeline();
367   - };
368   -
369   -}(window.dynworkflow = window.dynworkflow || {}, jQuery));
view/assets/js/external-libs/jquery.fileupload.js 0 → 100755
... ... @@ -0,0 +1,1477 @@
  1 +/*
  2 + * jQuery File Upload Plugin
  3 + * https://github.com/blueimp/jQuery-File-Upload
  4 + *
  5 + * Copyright 2010, Sebastian Tschan
  6 + * https://blueimp.net
  7 + *
  8 + * Licensed under the MIT license:
  9 + * http://www.opensource.org/licenses/MIT
  10 + */
  11 +
  12 +/* jshint nomen:false */
  13 +/* global define, require, window, document, location, Blob, FormData */
  14 +
  15 +(function (factory) {
  16 + 'use strict';
  17 + if (typeof define === 'function' && define.amd) {
  18 + // Register as an anonymous AMD module:
  19 + define([
  20 + 'jquery',
  21 + 'jquery.ui.widget'
  22 + ], factory);
  23 + } else if (typeof exports === 'object') {
  24 + // Node/CommonJS:
  25 + factory(
  26 + require('jquery'),
  27 + require('./vendor/jquery.ui.widget')
  28 + );
  29 + } else {
  30 + // Browser globals:
  31 + factory(window.jQuery);
  32 + }
  33 +}(function ($) {
  34 + 'use strict';
  35 +
  36 + // Detect file input support, based on
  37 + // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
  38 + $.support.fileInput = !(new RegExp(
  39 + // Handle devices which give false positives for the feature detection:
  40 + '(Android (1\\.[0156]|2\\.[01]))' +
  41 + '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
  42 + '|(w(eb)?OSBrowser)|(webOS)' +
  43 + '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
  44 + ).test(window.navigator.userAgent) ||
  45 + // Feature detection for all other devices:
  46 + $('<input type="file">').prop('disabled'));
  47 +
  48 + // The FileReader API is not actually used, but works as feature detection,
  49 + // as some Safari versions (5?) support XHR file uploads via the FormData API,
  50 + // but not non-multipart XHR file uploads.
  51 + // window.XMLHttpRequestUpload is not available on IE10, so we check for
  52 + // window.ProgressEvent instead to detect XHR2 file upload capability:
  53 + $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
  54 + $.support.xhrFormDataFileUpload = !!window.FormData;
  55 +
  56 + // Detect support for Blob slicing (required for chunked uploads):
  57 + $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
  58 + Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
  59 +
  60 + // Helper function to create drag handlers for dragover/dragenter/dragleave:
  61 + function getDragHandler(type) {
  62 + var isDragOver = type === 'dragover';
  63 + return function (e) {
  64 + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
  65 + var dataTransfer = e.dataTransfer;
  66 + if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
  67 + this._trigger(
  68 + type,
  69 + $.Event(type, {delegatedEvent: e})
  70 + ) !== false) {
  71 + e.preventDefault();
  72 + if (isDragOver) {
  73 + dataTransfer.dropEffect = 'copy';
  74 + }
  75 + }
  76 + };
  77 + }
  78 +
  79 + // The fileupload widget listens for change events on file input fields defined
  80 + // via fileInput setting and paste or drop events of the given dropZone.
  81 + // In addition to the default jQuery Widget methods, the fileupload widget
  82 + // exposes the "add" and "send" methods, to add or directly send files using
  83 + // the fileupload API.
  84 + // By default, files added via file input selection, paste, drag & drop or
  85 + // "add" method are uploaded immediately, but it is possible to override
  86 + // the "add" callback option to queue file uploads.
  87 + $.widget('blueimp.fileupload', {
  88 +
  89 + options: {
  90 + // The drop target element(s), by the default the complete document.
  91 + // Set to null to disable drag & drop support:
  92 + dropZone: $(document),
  93 + // The paste target element(s), by the default undefined.
  94 + // Set to a DOM node or jQuery object to enable file pasting:
  95 + pasteZone: undefined,
  96 + // The file input field(s), that are listened to for change events.
  97 + // If undefined, it is set to the file input fields inside
  98 + // of the widget element on plugin initialization.
  99 + // Set to null to disable the change listener.
  100 + fileInput: undefined,
  101 + // By default, the file input field is replaced with a clone after
  102 + // each input field change event. This is required for iframe transport
  103 + // queues and allows change events to be fired for the same file
  104 + // selection, but can be disabled by setting the following option to false:
  105 + replaceFileInput: true,
  106 + // The parameter name for the file form data (the request argument name).
  107 + // If undefined or empty, the name property of the file input field is
  108 + // used, or "files[]" if the file input name property is also empty,
  109 + // can be a string or an array of strings:
  110 + paramName: undefined,
  111 + // By default, each file of a selection is uploaded using an individual
  112 + // request for XHR type uploads. Set to false to upload file
  113 + // selections in one request each:
  114 + singleFileUploads: true,
  115 + // To limit the number of files uploaded with one XHR request,
  116 + // set the following option to an integer greater than 0:
  117 + limitMultiFileUploads: undefined,
  118 + // The following option limits the number of files uploaded with one
  119 + // XHR request to keep the request size under or equal to the defined
  120 + // limit in bytes:
  121 + limitMultiFileUploadSize: undefined,
  122 + // Multipart file uploads add a number of bytes to each uploaded file,
  123 + // therefore the following option adds an overhead for each file used
  124 + // in the limitMultiFileUploadSize configuration:
  125 + limitMultiFileUploadSizeOverhead: 512,
  126 + // Set the following option to true to issue all file upload requests
  127 + // in a sequential order:
  128 + sequentialUploads: false,
  129 + // To limit the number of concurrent uploads,
  130 + // set the following option to an integer greater than 0:
  131 + limitConcurrentUploads: undefined,
  132 + // Set the following option to true to force iframe transport uploads:
  133 + forceIframeTransport: false,
  134 + // Set the following option to the location of a redirect url on the
  135 + // origin server, for cross-domain iframe transport uploads:
  136 + redirect: undefined,
  137 + // The parameter name for the redirect url, sent as part of the form
  138 + // data and set to 'redirect' if this option is empty:
  139 + redirectParamName: undefined,
  140 + // Set the following option to the location of a postMessage window,
  141 + // to enable postMessage transport uploads:
  142 + postMessage: undefined,
  143 + // By default, XHR file uploads are sent as multipart/form-data.
  144 + // The iframe transport is always using multipart/form-data.
  145 + // Set to false to enable non-multipart XHR uploads:
  146 + multipart: true,
  147 + // To upload large files in smaller chunks, set the following option
  148 + // to a preferred maximum chunk size. If set to 0, null or undefined,
  149 + // or the browser does not support the required Blob API, files will
  150 + // be uploaded as a whole.
  151 + maxChunkSize: undefined,
  152 + // When a non-multipart upload or a chunked multipart upload has been
  153 + // aborted, this option can be used to resume the upload by setting
  154 + // it to the size of the already uploaded bytes. This option is most
  155 + // useful when modifying the options object inside of the "add" or
  156 + // "send" callbacks, as the options are cloned for each file upload.
  157 + uploadedBytes: undefined,
  158 + // By default, failed (abort or error) file uploads are removed from the
  159 + // global progress calculation. Set the following option to false to
  160 + // prevent recalculating the global progress data:
  161 + recalculateProgress: true,
  162 + // Interval in milliseconds to calculate and trigger progress events:
  163 + progressInterval: 100,
  164 + // Interval in milliseconds to calculate progress bitrate:
  165 + bitrateInterval: 500,
  166 + // By default, uploads are started automatically when adding files:
  167 + autoUpload: true,
  168 +
  169 + // Error and info messages:
  170 + messages: {
  171 + uploadedBytes: 'Uploaded bytes exceed file size'
  172 + },
  173 +
  174 + // Translation function, gets the message key to be translated
  175 + // and an object with context specific data as arguments:
  176 + i18n: function (message, context) {
  177 + message = this.messages[message] || message.toString();
  178 + if (context) {
  179 + $.each(context, function (key, value) {
  180 + message = message.replace('{' + key + '}', value);
  181 + });
  182 + }
  183 + return message;
  184 + },
  185 +
  186 + // Additional form data to be sent along with the file uploads can be set
  187 + // using this option, which accepts an array of objects with name and
  188 + // value properties, a function returning such an array, a FormData
  189 + // object (for XHR file uploads), or a simple object.
  190 + // The form of the first fileInput is given as parameter to the function:
  191 + formData: function (form) {
  192 + return form.serializeArray();
  193 + },
  194 +
  195 + // The add callback is invoked as soon as files are added to the fileupload
  196 + // widget (via file input selection, drag & drop, paste or add API call).
  197 + // If the singleFileUploads option is enabled, this callback will be
  198 + // called once for each file in the selection for XHR file uploads, else
  199 + // once for each file selection.
  200 + //
  201 + // The upload starts when the submit method is invoked on the data parameter.
  202 + // The data object contains a files property holding the added files
  203 + // and allows you to override plugin options as well as define ajax settings.
  204 + //
  205 + // Listeners for this callback can also be bound the following way:
  206 + // .bind('fileuploadadd', func);
  207 + //
  208 + // data.submit() returns a Promise object and allows to attach additional
  209 + // handlers using jQuery's Deferred callbacks:
  210 + // data.submit().done(func).fail(func).always(func);
  211 + add: function (e, data) {
  212 + if (e.isDefaultPrevented()) {
  213 + return false;
  214 + }
  215 + if (data.autoUpload || (data.autoUpload !== false &&
  216 + $(this).fileupload('option', 'autoUpload'))) {
  217 + data.process().done(function () {
  218 + data.submit();
  219 + });
  220 + }
  221 + },
  222 +
  223 + // Other callbacks:
  224 +
  225 + // Callback for the submit event of each file upload:
  226 + // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
  227 +
  228 + // Callback for the start of each file upload request:
  229 + // send: function (e, data) {}, // .bind('fileuploadsend', func);
  230 +
  231 + // Callback for successful uploads:
  232 + // done: function (e, data) {}, // .bind('fileuploaddone', func);
  233 +
  234 + // Callback for failed (abort or error) uploads:
  235 + // fail: function (e, data) {}, // .bind('fileuploadfail', func);
  236 +
  237 + // Callback for completed (success, abort or error) requests:
  238 + // always: function (e, data) {}, // .bind('fileuploadalways', func);
  239 +
  240 + // Callback for upload progress events:
  241 + // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
  242 +
  243 + // Callback for global upload progress events:
  244 + // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
  245 +
  246 + // Callback for uploads start, equivalent to the global ajaxStart event:
  247 + // start: function (e) {}, // .bind('fileuploadstart', func);
  248 +
  249 + // Callback for uploads stop, equivalent to the global ajaxStop event:
  250 + // stop: function (e) {}, // .bind('fileuploadstop', func);
  251 +
  252 + // Callback for change events of the fileInput(s):
  253 + // change: function (e, data) {}, // .bind('fileuploadchange', func);
  254 +
  255 + // Callback for paste events to the pasteZone(s):
  256 + // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
  257 +
  258 + // Callback for drop events of the dropZone(s):
  259 + // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
  260 +
  261 + // Callback for dragover events of the dropZone(s):
  262 + // dragover: function (e) {}, // .bind('fileuploaddragover', func);
  263 +
  264 + // Callback for the start of each chunk upload request:
  265 + // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
  266 +
  267 + // Callback for successful chunk uploads:
  268 + // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
  269 +
  270 + // Callback for failed (abort or error) chunk uploads:
  271 + // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
  272 +
  273 + // Callback for completed (success, abort or error) chunk upload requests:
  274 + // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
  275 +
  276 + // The plugin options are used as settings object for the ajax calls.
  277 + // The following are jQuery ajax settings required for the file uploads:
  278 + processData: false,
  279 + contentType: false,
  280 + cache: false,
  281 + timeout: 0
  282 + },
  283 +
  284 + // A list of options that require reinitializing event listeners and/or
  285 + // special initialization code:
  286 + _specialOptions: [
  287 + 'fileInput',
  288 + 'dropZone',
  289 + 'pasteZone',
  290 + 'multipart',
  291 + 'forceIframeTransport'
  292 + ],
  293 +
  294 + _blobSlice: $.support.blobSlice && function () {
  295 + var slice = this.slice || this.webkitSlice || this.mozSlice;
  296 + return slice.apply(this, arguments);
  297 + },
  298 +
  299 + _BitrateTimer: function () {
  300 + this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
  301 + this.loaded = 0;
  302 + this.bitrate = 0;
  303 + this.getBitrate = function (now, loaded, interval) {
  304 + var timeDiff = now - this.timestamp;
  305 + if (!this.bitrate || !interval || timeDiff > interval) {
  306 + this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
  307 + this.loaded = loaded;
  308 + this.timestamp = now;
  309 + }
  310 + return this.bitrate;
  311 + };
  312 + },
  313 +
  314 + _isXHRUpload: function (options) {
  315 + return !options.forceIframeTransport &&
  316 + ((!options.multipart && $.support.xhrFileUpload) ||
  317 + $.support.xhrFormDataFileUpload);
  318 + },
  319 +
  320 + _getFormData: function (options) {
  321 + var formData;
  322 + if ($.type(options.formData) === 'function') {
  323 + return options.formData(options.form);
  324 + }
  325 + if ($.isArray(options.formData)) {
  326 + return options.formData;
  327 + }
  328 + if ($.type(options.formData) === 'object') {
  329 + formData = [];
  330 + $.each(options.formData, function (name, value) {
  331 + formData.push({name: name, value: value});
  332 + });
  333 + return formData;
  334 + }
  335 + return [];
  336 + },
  337 +
  338 + _getTotal: function (files) {
  339 + var total = 0;
  340 + $.each(files, function (index, file) {
  341 + total += file.size || 1;
  342 + });
  343 + return total;
  344 + },
  345 +
  346 + _initProgressObject: function (obj) {
  347 + var progress = {
  348 + loaded: 0,
  349 + total: 0,
  350 + bitrate: 0
  351 + };
  352 + if (obj._progress) {
  353 + $.extend(obj._progress, progress);
  354 + } else {
  355 + obj._progress = progress;
  356 + }
  357 + },
  358 +
  359 + _initResponseObject: function (obj) {
  360 + var prop;
  361 + if (obj._response) {
  362 + for (prop in obj._response) {
  363 + if (obj._response.hasOwnProperty(prop)) {
  364 + delete obj._response[prop];
  365 + }
  366 + }
  367 + } else {
  368 + obj._response = {};
  369 + }
  370 + },
  371 +
  372 + _onProgress: function (e, data) {
  373 + if (e.lengthComputable) {
  374 + var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
  375 + loaded;
  376 + if (data._time && data.progressInterval &&
  377 + (now - data._time < data.progressInterval) &&
  378 + e.loaded !== e.total) {
  379 + return;
  380 + }
  381 + data._time = now;
  382 + loaded = Math.floor(
  383 + e.loaded / e.total * (data.chunkSize || data._progress.total)
  384 + ) + (data.uploadedBytes || 0);
  385 + // Add the difference from the previously loaded state
  386 + // to the global loaded counter:
  387 + this._progress.loaded += (loaded - data._progress.loaded);
  388 + this._progress.bitrate = this._bitrateTimer.getBitrate(
  389 + now,
  390 + this._progress.loaded,
  391 + data.bitrateInterval
  392 + );
  393 + data._progress.loaded = data.loaded = loaded;
  394 + data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
  395 + now,
  396 + loaded,
  397 + data.bitrateInterval
  398 + );
  399 + // Trigger a custom progress event with a total data property set
  400 + // to the file size(s) of the current upload and a loaded data
  401 + // property calculated accordingly:
  402 + this._trigger(
  403 + 'progress',
  404 + $.Event('progress', {delegatedEvent: e}),
  405 + data
  406 + );
  407 + // Trigger a global progress event for all current file uploads,
  408 + // including ajax calls queued for sequential file uploads:
  409 + this._trigger(
  410 + 'progressall',
  411 + $.Event('progressall', {delegatedEvent: e}),
  412 + this._progress
  413 + );
  414 + }
  415 + },
  416 +
  417 + _initProgressListener: function (options) {
  418 + var that = this,
  419 + xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
  420 + // Accesss to the native XHR object is required to add event listeners
  421 + // for the upload progress event:
  422 + if (xhr.upload) {
  423 + $(xhr.upload).bind('progress', function (e) {
  424 + var oe = e.originalEvent;
  425 + // Make sure the progress event properties get copied over:
  426 + e.lengthComputable = oe.lengthComputable;
  427 + e.loaded = oe.loaded;
  428 + e.total = oe.total;
  429 + that._onProgress(e, options);
  430 + });
  431 + options.xhr = function () {
  432 + return xhr;
  433 + };
  434 + }
  435 + },
  436 +
  437 + _isInstanceOf: function (type, obj) {
  438 + // Cross-frame instanceof check
  439 + return Object.prototype.toString.call(obj) === '[object ' + type + ']';
  440 + },
  441 +
  442 + _initXHRData: function (options) {
  443 + var that = this,
  444 + formData,
  445 + file = options.files[0],
  446 + // Ignore non-multipart setting if not supported:
  447 + multipart = options.multipart || !$.support.xhrFileUpload,
  448 + paramName = $.type(options.paramName) === 'array' ?
  449 + options.paramName[0] : options.paramName;
  450 + options.headers = $.extend({}, options.headers);
  451 + if (options.contentRange) {
  452 + options.headers['Content-Range'] = options.contentRange;
  453 + }
  454 + if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
  455 + options.headers['Content-Disposition'] = 'attachment; filename="' +
  456 + encodeURI(file.name) + '"';
  457 + }
  458 + if (!multipart) {
  459 + options.contentType = file.type || 'application/octet-stream';
  460 + options.data = options.blob || file;
  461 + } else if ($.support.xhrFormDataFileUpload) {
  462 + if (options.postMessage) {
  463 + // window.postMessage does not allow sending FormData
  464 + // objects, so we just add the File/Blob objects to
  465 + // the formData array and let the postMessage window
  466 + // create the FormData object out of this array:
  467 + formData = this._getFormData(options);
  468 + if (options.blob) {
  469 + formData.push({
  470 + name: paramName,
  471 + value: options.blob
  472 + });
  473 + } else {
  474 + $.each(options.files, function (index, file) {
  475 + formData.push({
  476 + name: ($.type(options.paramName) === 'array' &&
  477 + options.paramName[index]) || paramName,
  478 + value: file
  479 + });
  480 + });
  481 + }
  482 + } else {
  483 + if (that._isInstanceOf('FormData', options.formData)) {
  484 + formData = options.formData;
  485 + } else {
  486 + formData = new FormData();
  487 + $.each(this._getFormData(options), function (index, field) {
  488 + formData.append(field.name, field.value);
  489 + });
  490 + }
  491 + if (options.blob) {
  492 + formData.append(paramName, options.blob, file.name);
  493 + } else {
  494 + $.each(options.files, function (index, file) {
  495 + // This check allows the tests to run with
  496 + // dummy objects:
  497 + if (that._isInstanceOf('File', file) ||
  498 + that._isInstanceOf('Blob', file)) {
  499 + formData.append(
  500 + ($.type(options.paramName) === 'array' &&
  501 + options.paramName[index]) || paramName,
  502 + file,
  503 + file.uploadName || file.name
  504 + );
  505 + }
  506 + });
  507 + }
  508 + }
  509 + options.data = formData;
  510 + }
  511 + // Blob reference is not needed anymore, free memory:
  512 + options.blob = null;
  513 + },
  514 +
  515 + _initIframeSettings: function (options) {
  516 + var targetHost = $('<a></a>').prop('href', options.url).prop('host');
  517 + // Setting the dataType to iframe enables the iframe transport:
  518 + options.dataType = 'iframe ' + (options.dataType || '');
  519 + // The iframe transport accepts a serialized array as form data:
  520 + options.formData = this._getFormData(options);
  521 + // Add redirect url to form data on cross-domain uploads:
  522 + if (options.redirect && targetHost && targetHost !== location.host) {
  523 + options.formData.push({
  524 + name: options.redirectParamName || 'redirect',
  525 + value: options.redirect
  526 + });
  527 + }
  528 + },
  529 +
  530 + _initDataSettings: function (options) {
  531 + if (this._isXHRUpload(options)) {
  532 + if (!this._chunkedUpload(options, true)) {
  533 + if (!options.data) {
  534 + this._initXHRData(options);
  535 + }
  536 + this._initProgressListener(options);
  537 + }
  538 + if (options.postMessage) {
  539 + // Setting the dataType to postmessage enables the
  540 + // postMessage transport:
  541 + options.dataType = 'postmessage ' + (options.dataType || '');
  542 + }
  543 + } else {
  544 + this._initIframeSettings(options);
  545 + }
  546 + },
  547 +
  548 + _getParamName: function (options) {
  549 + var fileInput = $(options.fileInput),
  550 + paramName = options.paramName;
  551 + if (!paramName) {
  552 + paramName = [];
  553 + fileInput.each(function () {
  554 + var input = $(this),
  555 + name = input.prop('name') || 'files[]',
  556 + i = (input.prop('files') || [1]).length;
  557 + while (i) {
  558 + paramName.push(name);
  559 + i -= 1;
  560 + }
  561 + });
  562 + if (!paramName.length) {
  563 + paramName = [fileInput.prop('name') || 'files[]'];
  564 + }
  565 + } else if (!$.isArray(paramName)) {
  566 + paramName = [paramName];
  567 + }
  568 + return paramName;
  569 + },
  570 +
  571 + _initFormSettings: function (options) {
  572 + // Retrieve missing options from the input field and the
  573 + // associated form, if available:
  574 + if (!options.form || !options.form.length) {
  575 + options.form = $(options.fileInput.prop('form'));
  576 + // If the given file input doesn't have an associated form,
  577 + // use the default widget file input's form:
  578 + if (!options.form.length) {
  579 + options.form = $(this.options.fileInput.prop('form'));
  580 + }
  581 + }
  582 + options.paramName = this._getParamName(options);
  583 + if (!options.url) {
  584 + options.url = options.form.prop('action') || location.href;
  585 + }
  586 + // The HTTP request method must be "POST" or "PUT":
  587 + options.type = (options.type ||
  588 + ($.type(options.form.prop('method')) === 'string' &&
  589 + options.form.prop('method')) || ''
  590 + ).toUpperCase();
  591 + if (options.type !== 'POST' && options.type !== 'PUT' &&
  592 + options.type !== 'PATCH') {
  593 + options.type = 'POST';
  594 + }
  595 + if (!options.formAcceptCharset) {
  596 + options.formAcceptCharset = options.form.attr('accept-charset');
  597 + }
  598 + },
  599 +
  600 + _getAJAXSettings: function (data) {
  601 + var options = $.extend({}, this.options, data);
  602 + this._initFormSettings(options);
  603 + this._initDataSettings(options);
  604 + return options;
  605 + },
  606 +
  607 + // jQuery 1.6 doesn't provide .state(),
  608 + // while jQuery 1.8+ removed .isRejected() and .isResolved():
  609 + _getDeferredState: function (deferred) {
  610 + if (deferred.state) {
  611 + return deferred.state();
  612 + }
  613 + if (deferred.isResolved()) {
  614 + return 'resolved';
  615 + }
  616 + if (deferred.isRejected()) {
  617 + return 'rejected';
  618 + }
  619 + return 'pending';
  620 + },
  621 +
  622 + // Maps jqXHR callbacks to the equivalent
  623 + // methods of the given Promise object:
  624 + _enhancePromise: function (promise) {
  625 + promise.success = promise.done;
  626 + promise.error = promise.fail;
  627 + promise.complete = promise.always;
  628 + return promise;
  629 + },
  630 +
  631 + // Creates and returns a Promise object enhanced with
  632 + // the jqXHR methods abort, success, error and complete:
  633 + _getXHRPromise: function (resolveOrReject, context, args) {
  634 + var dfd = $.Deferred(),
  635 + promise = dfd.promise();
  636 + context = context || this.options.context || promise;
  637 + if (resolveOrReject === true) {
  638 + dfd.resolveWith(context, args);
  639 + } else if (resolveOrReject === false) {
  640 + dfd.rejectWith(context, args);
  641 + }
  642 + promise.abort = dfd.promise;
  643 + return this._enhancePromise(promise);
  644 + },
  645 +
  646 + // Adds convenience methods to the data callback argument:
  647 + _addConvenienceMethods: function (e, data) {
  648 + var that = this,
  649 + getPromise = function (args) {
  650 + return $.Deferred().resolveWith(that, args).promise();
  651 + };
  652 + data.process = function (resolveFunc, rejectFunc) {
  653 + if (resolveFunc || rejectFunc) {
  654 + data._processQueue = this._processQueue =
  655 + (this._processQueue || getPromise([this])).pipe(
  656 + function () {
  657 + if (data.errorThrown) {
  658 + return $.Deferred()
  659 + .rejectWith(that, [data]).promise();
  660 + }
  661 + return getPromise(arguments);
  662 + }
  663 + ).pipe(resolveFunc, rejectFunc);
  664 + }
  665 + return this._processQueue || getPromise([this]);
  666 + };
  667 + data.submit = function () {
  668 + if (this.state() !== 'pending') {
  669 + data.jqXHR = this.jqXHR =
  670 + (that._trigger(
  671 + 'submit',
  672 + $.Event('submit', {delegatedEvent: e}),
  673 + this
  674 + ) !== false) && that._onSend(e, this);
  675 + }
  676 + return this.jqXHR || that._getXHRPromise();
  677 + };
  678 + data.abort = function () {
  679 + if (this.jqXHR) {
  680 + return this.jqXHR.abort();
  681 + }
  682 + this.errorThrown = 'abort';
  683 + that._trigger('fail', null, this);
  684 + return that._getXHRPromise(false);
  685 + };
  686 + data.state = function () {
  687 + if (this.jqXHR) {
  688 + return that._getDeferredState(this.jqXHR);
  689 + }
  690 + if (this._processQueue) {
  691 + return that._getDeferredState(this._processQueue);
  692 + }
  693 + };
  694 + data.processing = function () {
  695 + return !this.jqXHR && this._processQueue && that
  696 + ._getDeferredState(this._processQueue) === 'pending';
  697 + };
  698 + data.progress = function () {
  699 + return this._progress;
  700 + };
  701 + data.response = function () {
  702 + return this._response;
  703 + };
  704 + },
  705 +
  706 + // Parses the Range header from the server response
  707 + // and returns the uploaded bytes:
  708 + _getUploadedBytes: function (jqXHR) {
  709 + var range = jqXHR.getResponseHeader('Range'),
  710 + parts = range && range.split('-'),
  711 + upperBytesPos = parts && parts.length > 1 &&
  712 + parseInt(parts[1], 10);
  713 + return upperBytesPos && upperBytesPos + 1;
  714 + },
  715 +
  716 + // Uploads a file in multiple, sequential requests
  717 + // by splitting the file up in multiple blob chunks.
  718 + // If the second parameter is true, only tests if the file
  719 + // should be uploaded in chunks, but does not invoke any
  720 + // upload requests:
  721 + _chunkedUpload: function (options, testOnly) {
  722 + options.uploadedBytes = options.uploadedBytes || 0;
  723 + var that = this,
  724 + file = options.files[0],
  725 + fs = file.size,
  726 + ub = options.uploadedBytes,
  727 + mcs = options.maxChunkSize || fs,
  728 + slice = this._blobSlice,
  729 + dfd = $.Deferred(),
  730 + promise = dfd.promise(),
  731 + jqXHR,
  732 + upload;
  733 + if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
  734 + options.data) {
  735 + return false;
  736 + }
  737 + if (testOnly) {
  738 + return true;
  739 + }
  740 + if (ub >= fs) {
  741 + file.error = options.i18n('uploadedBytes');
  742 + return this._getXHRPromise(
  743 + false,
  744 + options.context,
  745 + [null, 'error', file.error]
  746 + );
  747 + }
  748 + // The chunk upload method:
  749 + upload = function () {
  750 + // Clone the options object for each chunk upload:
  751 + var o = $.extend({}, options),
  752 + currentLoaded = o._progress.loaded;
  753 + o.blob = slice.call(
  754 + file,
  755 + ub,
  756 + ub + mcs,
  757 + file.type
  758 + );
  759 + // Store the current chunk size, as the blob itself
  760 + // will be dereferenced after data processing:
  761 + o.chunkSize = o.blob.size;
  762 + // Expose the chunk bytes position range:
  763 + o.contentRange = 'bytes ' + ub + '-' +
  764 + (ub + o.chunkSize - 1) + '/' + fs;
  765 + // Process the upload data (the blob and potential form data):
  766 + that._initXHRData(o);
  767 + // Add progress listeners for this chunk upload:
  768 + that._initProgressListener(o);
  769 + jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
  770 + that._getXHRPromise(false, o.context))
  771 + .done(function (result, textStatus, jqXHR) {
  772 + ub = that._getUploadedBytes(jqXHR) ||
  773 + (ub + o.chunkSize);
  774 + // Create a progress event if no final progress event
  775 + // with loaded equaling total has been triggered
  776 + // for this chunk:
  777 + if (currentLoaded + o.chunkSize - o._progress.loaded) {
  778 + that._onProgress($.Event('progress', {
  779 + lengthComputable: true,
  780 + loaded: ub - o.uploadedBytes,
  781 + total: ub - o.uploadedBytes
  782 + }), o);
  783 + }
  784 + options.uploadedBytes = o.uploadedBytes = ub;
  785 + o.result = result;
  786 + o.textStatus = textStatus;
  787 + o.jqXHR = jqXHR;
  788 + that._trigger('chunkdone', null, o);
  789 + that._trigger('chunkalways', null, o);
  790 + if (ub < fs) {
  791 + // File upload not yet complete,
  792 + // continue with the next chunk:
  793 + upload();
  794 + } else {
  795 + dfd.resolveWith(
  796 + o.context,
  797 + [result, textStatus, jqXHR]
  798 + );
  799 + }
  800 + })
  801 + .fail(function (jqXHR, textStatus, errorThrown) {
  802 + o.jqXHR = jqXHR;
  803 + o.textStatus = textStatus;
  804 + o.errorThrown = errorThrown;
  805 + that._trigger('chunkfail', null, o);
  806 + that._trigger('chunkalways', null, o);
  807 + dfd.rejectWith(
  808 + o.context,
  809 + [jqXHR, textStatus, errorThrown]
  810 + );
  811 + });
  812 + };
  813 + this._enhancePromise(promise);
  814 + promise.abort = function () {
  815 + return jqXHR.abort();
  816 + };
  817 + upload();
  818 + return promise;
  819 + },
  820 +
  821 + _beforeSend: function (e, data) {
  822 + if (this._active === 0) {
  823 + // the start callback is triggered when an upload starts
  824 + // and no other uploads are currently running,
  825 + // equivalent to the global ajaxStart event:
  826 + this._trigger('start');
  827 + // Set timer for global bitrate progress calculation:
  828 + this._bitrateTimer = new this._BitrateTimer();
  829 + // Reset the global progress values:
  830 + this._progress.loaded = this._progress.total = 0;
  831 + this._progress.bitrate = 0;
  832 + }
  833 + // Make sure the container objects for the .response() and
  834 + // .progress() methods on the data object are available
  835 + // and reset to their initial state:
  836 + this._initResponseObject(data);
  837 + this._initProgressObject(data);
  838 + data._progress.loaded = data.loaded = data.uploadedBytes || 0;
  839 + data._progress.total = data.total = this._getTotal(data.files) || 1;
  840 + data._progress.bitrate = data.bitrate = 0;
  841 + this._active += 1;
  842 + // Initialize the global progress values:
  843 + this._progress.loaded += data.loaded;
  844 + this._progress.total += data.total;
  845 + },
  846 +
  847 + _onDone: function (result, textStatus, jqXHR, options) {
  848 + var total = options._progress.total,
  849 + response = options._response;
  850 + if (options._progress.loaded < total) {
  851 + // Create a progress event if no final progress event
  852 + // with loaded equaling total has been triggered:
  853 + this._onProgress($.Event('progress', {
  854 + lengthComputable: true,
  855 + loaded: total,
  856 + total: total
  857 + }), options);
  858 + }
  859 + response.result = options.result = result;
  860 + response.textStatus = options.textStatus = textStatus;
  861 + response.jqXHR = options.jqXHR = jqXHR;
  862 + this._trigger('done', null, options);
  863 + },
  864 +
  865 + _onFail: function (jqXHR, textStatus, errorThrown, options) {
  866 + var response = options._response;
  867 + if (options.recalculateProgress) {
  868 + // Remove the failed (error or abort) file upload from
  869 + // the global progress calculation:
  870 + this._progress.loaded -= options._progress.loaded;
  871 + this._progress.total -= options._progress.total;
  872 + }
  873 + response.jqXHR = options.jqXHR = jqXHR;
  874 + response.textStatus = options.textStatus = textStatus;
  875 + response.errorThrown = options.errorThrown = errorThrown;
  876 + this._trigger('fail', null, options);
  877 + },
  878 +
  879 + _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
  880 + // jqXHRorResult, textStatus and jqXHRorError are added to the
  881 + // options object via done and fail callbacks
  882 + this._trigger('always', null, options);
  883 + },
  884 +
  885 + _onSend: function (e, data) {
  886 + if (!data.submit) {
  887 + this._addConvenienceMethods(e, data);
  888 + }
  889 + var that = this,
  890 + jqXHR,
  891 + aborted,
  892 + slot,
  893 + pipe,
  894 + options = that._getAJAXSettings(data),
  895 + send = function () {
  896 + that._sending += 1;
  897 + // Set timer for bitrate progress calculation:
  898 + options._bitrateTimer = new that._BitrateTimer();
  899 + jqXHR = jqXHR || (
  900 + ((aborted || that._trigger(
  901 + 'send',
  902 + $.Event('send', {delegatedEvent: e}),
  903 + options
  904 + ) === false) &&
  905 + that._getXHRPromise(false, options.context, aborted)) ||
  906 + that._chunkedUpload(options) || $.ajax(options)
  907 + ).done(function (result, textStatus, jqXHR) {
  908 + that._onDone(result, textStatus, jqXHR, options);
  909 + }).fail(function (jqXHR, textStatus, errorThrown) {
  910 + that._onFail(jqXHR, textStatus, errorThrown, options);
  911 + }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
  912 + that._onAlways(
  913 + jqXHRorResult,
  914 + textStatus,
  915 + jqXHRorError,
  916 + options
  917 + );
  918 + that._sending -= 1;
  919 + that._active -= 1;
  920 + if (options.limitConcurrentUploads &&
  921 + options.limitConcurrentUploads > that._sending) {
  922 + // Start the next queued upload,
  923 + // that has not been aborted:
  924 + var nextSlot = that._slots.shift();
  925 + while (nextSlot) {
  926 + if (that._getDeferredState(nextSlot) === 'pending') {
  927 + nextSlot.resolve();
  928 + break;
  929 + }
  930 + nextSlot = that._slots.shift();
  931 + }
  932 + }
  933 + if (that._active === 0) {
  934 + // The stop callback is triggered when all uploads have
  935 + // been completed, equivalent to the global ajaxStop event:
  936 + that._trigger('stop');
  937 + }
  938 + });
  939 + return jqXHR;
  940 + };
  941 + this._beforeSend(e, options);
  942 + if (this.options.sequentialUploads ||
  943 + (this.options.limitConcurrentUploads &&
  944 + this.options.limitConcurrentUploads <= this._sending)) {
  945 + if (this.options.limitConcurrentUploads > 1) {
  946 + slot = $.Deferred();
  947 + this._slots.push(slot);
  948 + pipe = slot.pipe(send);
  949 + } else {
  950 + this._sequence = this._sequence.pipe(send, send);
  951 + pipe = this._sequence;
  952 + }
  953 + // Return the piped Promise object, enhanced with an abort method,
  954 + // which is delegated to the jqXHR object of the current upload,
  955 + // and jqXHR callbacks mapped to the equivalent Promise methods:
  956 + pipe.abort = function () {
  957 + aborted = [undefined, 'abort', 'abort'];
  958 + if (!jqXHR) {
  959 + if (slot) {
  960 + slot.rejectWith(options.context, aborted);
  961 + }
  962 + return send();
  963 + }
  964 + return jqXHR.abort();
  965 + };
  966 + return this._enhancePromise(pipe);
  967 + }
  968 + return send();
  969 + },
  970 +
  971 + _onAdd: function (e, data) {
  972 + var that = this,
  973 + result = true,
  974 + options = $.extend({}, this.options, data),
  975 + files = data.files,
  976 + filesLength = files.length,
  977 + limit = options.limitMultiFileUploads,
  978 + limitSize = options.limitMultiFileUploadSize,
  979 + overhead = options.limitMultiFileUploadSizeOverhead,
  980 + batchSize = 0,
  981 + paramName = this._getParamName(options),
  982 + paramNameSet,
  983 + paramNameSlice,
  984 + fileSet,
  985 + i,
  986 + j = 0;
  987 + if (!filesLength) {
  988 + return false;
  989 + }
  990 + if (limitSize && files[0].size === undefined) {
  991 + limitSize = undefined;
  992 + }
  993 + if (!(options.singleFileUploads || limit || limitSize) ||
  994 + !this._isXHRUpload(options)) {
  995 + fileSet = [files];
  996 + paramNameSet = [paramName];
  997 + } else if (!(options.singleFileUploads || limitSize) && limit) {
  998 + fileSet = [];
  999 + paramNameSet = [];
  1000 + for (i = 0; i < filesLength; i += limit) {
  1001 + fileSet.push(files.slice(i, i + limit));
  1002 + paramNameSlice = paramName.slice(i, i + limit);
  1003 + if (!paramNameSlice.length) {
  1004 + paramNameSlice = paramName;
  1005 + }
  1006 + paramNameSet.push(paramNameSlice);
  1007 + }
  1008 + } else if (!options.singleFileUploads && limitSize) {
  1009 + fileSet = [];
  1010 + paramNameSet = [];
  1011 + for (i = 0; i < filesLength; i = i + 1) {
  1012 + batchSize += files[i].size + overhead;
  1013 + if (i + 1 === filesLength ||
  1014 + ((batchSize + files[i + 1].size + overhead) > limitSize) ||
  1015 + (limit && i + 1 - j >= limit)) {
  1016 + fileSet.push(files.slice(j, i + 1));
  1017 + paramNameSlice = paramName.slice(j, i + 1);
  1018 + if (!paramNameSlice.length) {
  1019 + paramNameSlice = paramName;
  1020 + }
  1021 + paramNameSet.push(paramNameSlice);
  1022 + j = i + 1;
  1023 + batchSize = 0;
  1024 + }
  1025 + }
  1026 + } else {
  1027 + paramNameSet = paramName;
  1028 + }
  1029 + data.originalFiles = files;
  1030 + $.each(fileSet || files, function (index, element) {
  1031 + var newData = $.extend({}, data);
  1032 + newData.files = fileSet ? element : [element];
  1033 + newData.paramName = paramNameSet[index];
  1034 + that._initResponseObject(newData);
  1035 + that._initProgressObject(newData);
  1036 + that._addConvenienceMethods(e, newData);
  1037 + result = that._trigger(
  1038 + 'add',
  1039 + $.Event('add', {delegatedEvent: e}),
  1040 + newData
  1041 + );
  1042 + return result;
  1043 + });
  1044 + return result;
  1045 + },
  1046 +
  1047 + _replaceFileInput: function (data) {
  1048 + var input = data.fileInput,
  1049 + inputClone = input.clone(true),
  1050 + restoreFocus = input.is(document.activeElement);
  1051 + // Add a reference for the new cloned file input to the data argument:
  1052 + data.fileInputClone = inputClone;
  1053 + $('<form></form>').append(inputClone)[0].reset();
  1054 + // Detaching allows to insert the fileInput on another form
  1055 + // without loosing the file input value:
  1056 + input.after(inputClone).detach();
  1057 + // If the fileInput had focus before it was detached,
  1058 + // restore focus to the inputClone.
  1059 + if (restoreFocus) {
  1060 + inputClone.focus();
  1061 + }
  1062 + // Avoid memory leaks with the detached file input:
  1063 + $.cleanData(input.unbind('remove'));
  1064 + // Replace the original file input element in the fileInput
  1065 + // elements set with the clone, which has been copied including
  1066 + // event handlers:
  1067 + this.options.fileInput = this.options.fileInput.map(function (i, el) {
  1068 + if (el === input[0]) {
  1069 + return inputClone[0];
  1070 + }
  1071 + return el;
  1072 + });
  1073 + // If the widget has been initialized on the file input itself,
  1074 + // override this.element with the file input clone:
  1075 + if (input[0] === this.element[0]) {
  1076 + this.element = inputClone;
  1077 + }
  1078 + },
  1079 +
  1080 + _handleFileTreeEntry: function (entry, path) {
  1081 + var that = this,
  1082 + dfd = $.Deferred(),
  1083 + errorHandler = function (e) {
  1084 + if (e && !e.entry) {
  1085 + e.entry = entry;
  1086 + }
  1087 + // Since $.when returns immediately if one
  1088 + // Deferred is rejected, we use resolve instead.
  1089 + // This allows valid files and invalid items
  1090 + // to be returned together in one set:
  1091 + dfd.resolve([e]);
  1092 + },
  1093 + successHandler = function (entries) {
  1094 + that._handleFileTreeEntries(
  1095 + entries,
  1096 + path + entry.name + '/'
  1097 + ).done(function (files) {
  1098 + dfd.resolve(files);
  1099 + }).fail(errorHandler);
  1100 + },
  1101 + readEntries = function () {
  1102 + dirReader.readEntries(function (results) {
  1103 + if (!results.length) {
  1104 + successHandler(entries);
  1105 + } else {
  1106 + entries = entries.concat(results);
  1107 + readEntries();
  1108 + }
  1109 + }, errorHandler);
  1110 + },
  1111 + dirReader, entries = [];
  1112 + path = path || '';
  1113 + if (entry.isFile) {
  1114 + if (entry._file) {
  1115 + // Workaround for Chrome bug #149735
  1116 + entry._file.relativePath = path;
  1117 + dfd.resolve(entry._file);
  1118 + } else {
  1119 + entry.file(function (file) {
  1120 + file.relativePath = path;
  1121 + dfd.resolve(file);
  1122 + }, errorHandler);
  1123 + }
  1124 + } else if (entry.isDirectory) {
  1125 + dirReader = entry.createReader();
  1126 + readEntries();
  1127 + } else {
  1128 + // Return an empy list for file system items
  1129 + // other than files or directories:
  1130 + dfd.resolve([]);
  1131 + }
  1132 + return dfd.promise();
  1133 + },
  1134 +
  1135 + _handleFileTreeEntries: function (entries, path) {
  1136 + var that = this;
  1137 + return $.when.apply(
  1138 + $,
  1139 + $.map(entries, function (entry) {
  1140 + return that._handleFileTreeEntry(entry, path);
  1141 + })
  1142 + ).pipe(function () {
  1143 + return Array.prototype.concat.apply(
  1144 + [],
  1145 + arguments
  1146 + );
  1147 + });
  1148 + },
  1149 +
  1150 + _getDroppedFiles: function (dataTransfer) {
  1151 + dataTransfer = dataTransfer || {};
  1152 + var items = dataTransfer.items;
  1153 + if (items && items.length && (items[0].webkitGetAsEntry ||
  1154 + items[0].getAsEntry)) {
  1155 + return this._handleFileTreeEntries(
  1156 + $.map(items, function (item) {
  1157 + var entry;
  1158 + if (item.webkitGetAsEntry) {
  1159 + entry = item.webkitGetAsEntry();
  1160 + if (entry) {
  1161 + // Workaround for Chrome bug #149735:
  1162 + entry._file = item.getAsFile();
  1163 + }
  1164 + return entry;
  1165 + }
  1166 + return item.getAsEntry();
  1167 + })
  1168 + );
  1169 + }
  1170 + return $.Deferred().resolve(
  1171 + $.makeArray(dataTransfer.files)
  1172 + ).promise();
  1173 + },
  1174 +
  1175 + _getSingleFileInputFiles: function (fileInput) {
  1176 + fileInput = $(fileInput);
  1177 + var entries = fileInput.prop('webkitEntries') ||
  1178 + fileInput.prop('entries'),
  1179 + files,
  1180 + value;
  1181 + if (entries && entries.length) {
  1182 + return this._handleFileTreeEntries(entries);
  1183 + }
  1184 + files = $.makeArray(fileInput.prop('files'));
  1185 + if (!files.length) {
  1186 + value = fileInput.prop('value');
  1187 + if (!value) {
  1188 + return $.Deferred().resolve([]).promise();
  1189 + }
  1190 + // If the files property is not available, the browser does not
  1191 + // support the File API and we add a pseudo File object with
  1192 + // the input value as name with path information removed:
  1193 + files = [{name: value.replace(/^.*\\/, '')}];
  1194 + } else if (files[0].name === undefined && files[0].fileName) {
  1195 + // File normalization for Safari 4 and Firefox 3:
  1196 + $.each(files, function (index, file) {
  1197 + file.name = file.fileName;
  1198 + file.size = file.fileSize;
  1199 + });
  1200 + }
  1201 + return $.Deferred().resolve(files).promise();
  1202 + },
  1203 +
  1204 + _getFileInputFiles: function (fileInput) {
  1205 + if (!(fileInput instanceof $) || fileInput.length === 1) {
  1206 + return this._getSingleFileInputFiles(fileInput);
  1207 + }
  1208 + return $.when.apply(
  1209 + $,
  1210 + $.map(fileInput, this._getSingleFileInputFiles)
  1211 + ).pipe(function () {
  1212 + return Array.prototype.concat.apply(
  1213 + [],
  1214 + arguments
  1215 + );
  1216 + });
  1217 + },
  1218 +
  1219 + _onChange: function (e) {
  1220 + var that = this,
  1221 + data = {
  1222 + fileInput: $(e.target),
  1223 + form: $(e.target.form)
  1224 + };
  1225 + this._getFileInputFiles(data.fileInput).always(function (files) {
  1226 + data.files = files;
  1227 + if (that.options.replaceFileInput) {
  1228 + that._replaceFileInput(data);
  1229 + }
  1230 + if (that._trigger(
  1231 + 'change',
  1232 + $.Event('change', {delegatedEvent: e}),
  1233 + data
  1234 + ) !== false) {
  1235 + that._onAdd(e, data);
  1236 + }
  1237 + });
  1238 + },
  1239 +
  1240 + _onPaste: function (e) {
  1241 + var items = e.originalEvent && e.originalEvent.clipboardData &&
  1242 + e.originalEvent.clipboardData.items,
  1243 + data = {files: []};
  1244 + if (items && items.length) {
  1245 + $.each(items, function (index, item) {
  1246 + var file = item.getAsFile && item.getAsFile();
  1247 + if (file) {
  1248 + data.files.push(file);
  1249 + }
  1250 + });
  1251 + if (this._trigger(
  1252 + 'paste',
  1253 + $.Event('paste', {delegatedEvent: e}),
  1254 + data
  1255 + ) !== false) {
  1256 + this._onAdd(e, data);
  1257 + }
  1258 + }
  1259 + },
  1260 +
  1261 + _onDrop: function (e) {
  1262 + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
  1263 + var that = this,
  1264 + dataTransfer = e.dataTransfer,
  1265 + data = {};
  1266 + if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
  1267 + e.preventDefault();
  1268 + this._getDroppedFiles(dataTransfer).always(function (files) {
  1269 + data.files = files;
  1270 + if (that._trigger(
  1271 + 'drop',
  1272 + $.Event('drop', {delegatedEvent: e}),
  1273 + data
  1274 + ) !== false) {
  1275 + that._onAdd(e, data);
  1276 + }
  1277 + });
  1278 + }
  1279 + },
  1280 +
  1281 + _onDragOver: getDragHandler('dragover'),
  1282 +
  1283 + _onDragEnter: getDragHandler('dragenter'),
  1284 +
  1285 + _onDragLeave: getDragHandler('dragleave'),
  1286 +
  1287 + _initEventHandlers: function () {
  1288 + if (this._isXHRUpload(this.options)) {
  1289 + this._on(this.options.dropZone, {
  1290 + dragover: this._onDragOver,
  1291 + drop: this._onDrop,
  1292 + // event.preventDefault() on dragenter is required for IE10+:
  1293 + dragenter: this._onDragEnter,
  1294 + // dragleave is not required, but added for completeness:
  1295 + dragleave: this._onDragLeave
  1296 + });
  1297 + this._on(this.options.pasteZone, {
  1298 + paste: this._onPaste
  1299 + });
  1300 + }
  1301 + if ($.support.fileInput) {
  1302 + this._on(this.options.fileInput, {
  1303 + change: this._onChange
  1304 + });
  1305 + }
  1306 + },
  1307 +
  1308 + _destroyEventHandlers: function () {
  1309 + this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
  1310 + this._off(this.options.pasteZone, 'paste');
  1311 + this._off(this.options.fileInput, 'change');
  1312 + },
  1313 +
  1314 + _setOption: function (key, value) {
  1315 + var reinit = $.inArray(key, this._specialOptions) !== -1;
  1316 + if (reinit) {
  1317 + this._destroyEventHandlers();
  1318 + }
  1319 + this._super(key, value);
  1320 + if (reinit) {
  1321 + this._initSpecialOptions();
  1322 + this._initEventHandlers();
  1323 + }
  1324 + },
  1325 +
  1326 + _initSpecialOptions: function () {
  1327 + var options = this.options;
  1328 + if (options.fileInput === undefined) {
  1329 + options.fileInput = this.element.is('input[type="file"]') ?
  1330 + this.element : this.element.find('input[type="file"]');
  1331 + } else if (!(options.fileInput instanceof $)) {
  1332 + options.fileInput = $(options.fileInput);
  1333 + }
  1334 + if (!(options.dropZone instanceof $)) {
  1335 + options.dropZone = $(options.dropZone);
  1336 + }
  1337 + if (!(options.pasteZone instanceof $)) {
  1338 + options.pasteZone = $(options.pasteZone);
  1339 + }
  1340 + },
  1341 +
  1342 + _getRegExp: function (str) {
  1343 + var parts = str.split('/'),
  1344 + modifiers = parts.pop();
  1345 + parts.shift();
  1346 + return new RegExp(parts.join('/'), modifiers);
  1347 + },
  1348 +
  1349 + _isRegExpOption: function (key, value) {
  1350 + return key !== 'url' && $.type(value) === 'string' &&
  1351 + /^\/.*\/[igm]{0,3}$/.test(value);
  1352 + },
  1353 +
  1354 + _initDataAttributes: function () {
  1355 + var that = this,
  1356 + options = this.options,
  1357 + data = this.element.data();
  1358 + // Initialize options set via HTML5 data-attributes:
  1359 + $.each(
  1360 + this.element[0].attributes,
  1361 + function (index, attr) {
  1362 + var key = attr.name.toLowerCase(),
  1363 + value;
  1364 + if (/^data-/.test(key)) {
  1365 + // Convert hyphen-ated key to camelCase:
  1366 + key = key.slice(5).replace(/-[a-z]/g, function (str) {
  1367 + return str.charAt(1).toUpperCase();
  1368 + });
  1369 + value = data[key];
  1370 + if (that._isRegExpOption(key, value)) {
  1371 + value = that._getRegExp(value);
  1372 + }
  1373 + options[key] = value;
  1374 + }
  1375 + }
  1376 + );
  1377 + },
  1378 +
  1379 + _create: function () {
  1380 + this._initDataAttributes();
  1381 + this._initSpecialOptions();
  1382 + this._slots = [];
  1383 + this._sequence = this._getXHRPromise(true);
  1384 + this._sending = this._active = 0;
  1385 + this._initProgressObject(this);
  1386 + this._initEventHandlers();
  1387 + },
  1388 +
  1389 + // This method is exposed to the widget API and allows to query
  1390 + // the number of active uploads:
  1391 + active: function () {
  1392 + return this._active;
  1393 + },
  1394 +
  1395 + // This method is exposed to the widget API and allows to query
  1396 + // the widget upload progress.
  1397 + // It returns an object with loaded, total and bitrate properties
  1398 + // for the running uploads:
  1399 + progress: function () {
  1400 + return this._progress;
  1401 + },
  1402 +
  1403 + // This method is exposed to the widget API and allows adding files
  1404 + // using the fileupload API. The data parameter accepts an object which
  1405 + // must have a files property and can contain additional options:
  1406 + // .fileupload('add', {files: filesList});
  1407 + add: function (data) {
  1408 + var that = this;
  1409 + if (!data || this.options.disabled) {
  1410 + return;
  1411 + }
  1412 + if (data.fileInput && !data.files) {
  1413 + this._getFileInputFiles(data.fileInput).always(function (files) {
  1414 + data.files = files;
  1415 + that._onAdd(null, data);
  1416 + });
  1417 + } else {
  1418 + data.files = $.makeArray(data.files);
  1419 + this._onAdd(null, data);
  1420 + }
  1421 + },
  1422 +
  1423 + // This method is exposed to the widget API and allows sending files
  1424 + // using the fileupload API. The data parameter accepts an object which
  1425 + // must have a files or fileInput property and can contain additional options:
  1426 + // .fileupload('send', {files: filesList});
  1427 + // The method returns a Promise object for the file upload call.
  1428 + send: function (data) {
  1429 + if (data && !this.options.disabled) {
  1430 + if (data.fileInput && !data.files) {
  1431 + var that = this,
  1432 + dfd = $.Deferred(),
  1433 + promise = dfd.promise(),
  1434 + jqXHR,
  1435 + aborted;
  1436 + promise.abort = function () {
  1437 + aborted = true;
  1438 + if (jqXHR) {
  1439 + return jqXHR.abort();
  1440 + }
  1441 + dfd.reject(null, 'abort', 'abort');
  1442 + return promise;
  1443 + };
  1444 + this._getFileInputFiles(data.fileInput).always(
  1445 + function (files) {
  1446 + if (aborted) {
  1447 + return;
  1448 + }
  1449 + if (!files.length) {
  1450 + dfd.reject();
  1451 + return;
  1452 + }
  1453 + data.files = files;
  1454 + jqXHR = that._onSend(null, data);
  1455 + jqXHR.then(
  1456 + function (result, textStatus, jqXHR) {
  1457 + dfd.resolve(result, textStatus, jqXHR);
  1458 + },
  1459 + function (jqXHR, textStatus, errorThrown) {
  1460 + dfd.reject(jqXHR, textStatus, errorThrown);
  1461 + }
  1462 + );
  1463 + }
  1464 + );
  1465 + return this._enhancePromise(promise);
  1466 + }
  1467 + data.files = $.makeArray(data.files);
  1468 + if (data.files.length) {
  1469 + return this._onSend(null, data);
  1470 + }
  1471 + }
  1472 + return this._getXHRPromise(false, data && data.context);
  1473 + }
  1474 +
  1475 + });
  1476 +
  1477 +}));
... ...
view/assets/js/external-libs/jquery.iframe-transport.js 0 → 100755
... ... @@ -0,0 +1,217 @@
  1 +/*
  2 + * jQuery Iframe Transport Plugin
  3 + * https://github.com/blueimp/jQuery-File-Upload
  4 + *
  5 + * Copyright 2011, Sebastian Tschan
  6 + * https://blueimp.net
  7 + *
  8 + * Licensed under the MIT license:
  9 + * http://www.opensource.org/licenses/MIT
  10 + */
  11 +
  12 +/* global define, require, window, document */
  13 +
  14 +(function (factory) {
  15 + 'use strict';
  16 + if (typeof define === 'function' && define.amd) {
  17 + // Register as an anonymous AMD module:
  18 + define(['jquery'], factory);
  19 + } else if (typeof exports === 'object') {
  20 + // Node/CommonJS:
  21 + factory(require('jquery'));
  22 + } else {
  23 + // Browser globals:
  24 + factory(window.jQuery);
  25 + }
  26 +}(function ($) {
  27 + 'use strict';
  28 +
  29 + // Helper variable to create unique names for the transport iframes:
  30 + var counter = 0;
  31 +
  32 + // The iframe transport accepts four additional options:
  33 + // options.fileInput: a jQuery collection of file input fields
  34 + // options.paramName: the parameter name for the file form data,
  35 + // overrides the name property of the file input field(s),
  36 + // can be a string or an array of strings.
  37 + // options.formData: an array of objects with name and value properties,
  38 + // equivalent to the return data of .serializeArray(), e.g.:
  39 + // [{name: 'a', value: 1}, {name: 'b', value: 2}]
  40 + // options.initialIframeSrc: the URL of the initial iframe src,
  41 + // by default set to "javascript:false;"
  42 + $.ajaxTransport('iframe', function (options) {
  43 + if (options.async) {
  44 + // javascript:false as initial iframe src
  45 + // prevents warning popups on HTTPS in IE6:
  46 + /*jshint scripturl: true */
  47 + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
  48 + /*jshint scripturl: false */
  49 + form,
  50 + iframe,
  51 + addParamChar;
  52 + return {
  53 + send: function (_, completeCallback) {
  54 + form = $('<form style="display:none;"></form>');
  55 + form.attr('accept-charset', options.formAcceptCharset);
  56 + addParamChar = /\?/.test(options.url) ? '&' : '?';
  57 + // XDomainRequest only supports GET and POST:
  58 + if (options.type === 'DELETE') {
  59 + options.url = options.url + addParamChar + '_method=DELETE';
  60 + options.type = 'POST';
  61 + } else if (options.type === 'PUT') {
  62 + options.url = options.url + addParamChar + '_method=PUT';
  63 + options.type = 'POST';
  64 + } else if (options.type === 'PATCH') {
  65 + options.url = options.url + addParamChar + '_method=PATCH';
  66 + options.type = 'POST';
  67 + }
  68 + // IE versions below IE8 cannot set the name property of
  69 + // elements that have already been added to the DOM,
  70 + // so we set the name along with the iframe HTML markup:
  71 + counter += 1;
  72 + iframe = $(
  73 + '<iframe src="' + initialIframeSrc +
  74 + '" name="iframe-transport-' + counter + '"></iframe>'
  75 + ).bind('load', function () {
  76 + var fileInputClones,
  77 + paramNames = $.isArray(options.paramName) ?
  78 + options.paramName : [options.paramName];
  79 + iframe
  80 + .unbind('load')
  81 + .bind('load', function () {
  82 + var response;
  83 + // Wrap in a try/catch block to catch exceptions thrown
  84 + // when trying to access cross-domain iframe contents:
  85 + try {
  86 + response = iframe.contents();
  87 + // Google Chrome and Firefox do not throw an
  88 + // exception when calling iframe.contents() on
  89 + // cross-domain requests, so we unify the response:
  90 + if (!response.length || !response[0].firstChild) {
  91 + throw new Error();
  92 + }
  93 + } catch (e) {
  94 + response = undefined;
  95 + }
  96 + // The complete callback returns the
  97 + // iframe content document as response object:
  98 + completeCallback(
  99 + 200,
  100 + 'success',
  101 + {'iframe': response}
  102 + );
  103 + // Fix for IE endless progress bar activity bug
  104 + // (happens on form submits to iframe targets):
  105 + $('<iframe src="' + initialIframeSrc + '"></iframe>')
  106 + .appendTo(form);
  107 + window.setTimeout(function () {
  108 + // Removing the form in a setTimeout call
  109 + // allows Chrome's developer tools to display
  110 + // the response result
  111 + form.remove();
  112 + }, 0);
  113 + });
  114 + form
  115 + .prop('target', iframe.prop('name'))
  116 + .prop('action', options.url)
  117 + .prop('method', options.type);
  118 + if (options.formData) {
  119 + $.each(options.formData, function (index, field) {
  120 + $('<input type="hidden"/>')
  121 + .prop('name', field.name)
  122 + .val(field.value)
  123 + .appendTo(form);
  124 + });
  125 + }
  126 + if (options.fileInput && options.fileInput.length &&
  127 + options.type === 'POST') {
  128 + fileInputClones = options.fileInput.clone();
  129 + // Insert a clone for each file input field:
  130 + options.fileInput.after(function (index) {
  131 + return fileInputClones[index];
  132 + });
  133 + if (options.paramName) {
  134 + options.fileInput.each(function (index) {
  135 + $(this).prop(
  136 + 'name',
  137 + paramNames[index] || options.paramName
  138 + );
  139 + });
  140 + }
  141 + // Appending the file input fields to the hidden form
  142 + // removes them from their original location:
  143 + form
  144 + .append(options.fileInput)
  145 + .prop('enctype', 'multipart/form-data')
  146 + // enctype must be set as encoding for IE:
  147 + .prop('encoding', 'multipart/form-data');
  148 + // Remove the HTML5 form attribute from the input(s):
  149 + options.fileInput.removeAttr('form');
  150 + }
  151 + form.submit();
  152 + // Insert the file input fields at their original location
  153 + // by replacing the clones with the originals:
  154 + if (fileInputClones && fileInputClones.length) {
  155 + options.fileInput.each(function (index, input) {
  156 + var clone = $(fileInputClones[index]);
  157 + // Restore the original name and form properties:
  158 + $(input)
  159 + .prop('name', clone.prop('name'))
  160 + .attr('form', clone.attr('form'));
  161 + clone.replaceWith(input);
  162 + });
  163 + }
  164 + });
  165 + form.append(iframe).appendTo(document.body);
  166 + },
  167 + abort: function () {
  168 + if (iframe) {
  169 + // javascript:false as iframe src aborts the request
  170 + // and prevents warning popups on HTTPS in IE6.
  171 + // concat is used to avoid the "Script URL" JSLint error:
  172 + iframe
  173 + .unbind('load')
  174 + .prop('src', initialIframeSrc);
  175 + }
  176 + if (form) {
  177 + form.remove();
  178 + }
  179 + }
  180 + };
  181 + }
  182 + });
  183 +
  184 + // The iframe transport returns the iframe content document as response.
  185 + // The following adds converters from iframe to text, json, html, xml
  186 + // and script.
  187 + // Please note that the Content-Type for JSON responses has to be text/plain
  188 + // or text/html, if the browser doesn't include application/json in the
  189 + // Accept header, else IE will show a download dialog.
  190 + // The Content-Type for XML responses on the other hand has to be always
  191 + // application/xml or text/xml, so IE properly parses the XML response.
  192 + // See also
  193 + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
  194 + $.ajaxSetup({
  195 + converters: {
  196 + 'iframe text': function (iframe) {
  197 + return iframe && $(iframe[0].body).text();
  198 + },
  199 + 'iframe json': function (iframe) {
  200 + return iframe && $.parseJSON($(iframe[0].body).text());
  201 + },
  202 + 'iframe html': function (iframe) {
  203 + return iframe && $(iframe[0].body).html();
  204 + },
  205 + 'iframe xml': function (iframe) {
  206 + var xmlDoc = iframe && iframe[0];
  207 + return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
  208 + $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
  209 + $(xmlDoc.body).html());
  210 + },
  211 + 'iframe script': function (iframe) {
  212 + return iframe && $.globalEval($(iframe[0].body).text());
  213 + }
  214 + }
  215 + });
  216 +
  217 +}));
... ...
view/assets/js/external-libs/jquery.scrollTo.js 0 → 100644
... ... @@ -0,0 +1,210 @@
  1 +/*!
  2 + * jQuery.scrollTo
  3 + * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
  4 + * Licensed under MIT
  5 + * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
  6 + * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery
  7 + * @author Ariel Flesler
  8 + * @version 2.1.2
  9 + */
  10 +;(function(factory) {
  11 + 'use strict';
  12 + if (typeof define === 'function' && define.amd) {
  13 + // AMD
  14 + define(['jquery'], factory);
  15 + } else if (typeof module !== 'undefined' && module.exports) {
  16 + // CommonJS
  17 + module.exports = factory(require('jquery'));
  18 + } else {
  19 + // Global
  20 + factory(jQuery);
  21 + }
  22 +})(function($) {
  23 + 'use strict';
  24 +
  25 + var $scrollTo = $.scrollTo = function(target, duration, settings) {
  26 + return $(window).scrollTo(target, duration, settings);
  27 + };
  28 +
  29 + $scrollTo.defaults = {
  30 + axis:'xy',
  31 + duration: 0,
  32 + limit:true
  33 + };
  34 +
  35 + function isWin(elem) {
  36 + return !elem.nodeName ||
  37 + $.inArray(elem.nodeName.toLowerCase(), ['iframe','#document','html','body']) !== -1;
  38 + }
  39 +
  40 + $.fn.scrollTo = function(target, duration, settings) {
  41 + if (typeof duration === 'object') {
  42 + settings = duration;
  43 + duration = 0;
  44 + }
  45 + if (typeof settings === 'function') {
  46 + settings = { onAfter:settings };
  47 + }
  48 + if (target === 'max') {
  49 + target = 9e9;
  50 + }
  51 +
  52 + settings = $.extend({}, $scrollTo.defaults, settings);
  53 + // Speed is still recognized for backwards compatibility
  54 + duration = duration || settings.duration;
  55 + // Make sure the settings are given right
  56 + var queue = settings.queue && settings.axis.length > 1;
  57 + if (queue) {
  58 + // Let's keep the overall duration
  59 + duration /= 2;
  60 + }
  61 + settings.offset = both(settings.offset);
  62 + settings.over = both(settings.over);
  63 +
  64 + return this.each(function() {
  65 + // Null target yields nothing, just like jQuery does
  66 + if (target === null) return;
  67 +
  68 + var win = isWin(this),
  69 + elem = win ? this.contentWindow || window : this,
  70 + $elem = $(elem),
  71 + targ = target,
  72 + attr = {},
  73 + toff;
  74 +
  75 + switch (typeof targ) {
  76 + // A number will pass the regex
  77 + case 'number':
  78 + case 'string':
  79 + if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
  80 + targ = both(targ);
  81 + // We are done
  82 + break;
  83 + }
  84 + // Relative/Absolute selector
  85 + targ = win ? $(targ) : $(targ, elem);
  86 + /* falls through */
  87 + case 'object':
  88 + if (targ.length === 0) return;
  89 + // DOMElement / jQuery
  90 + if (targ.is || targ.style) {
  91 + // Get the real position of the target
  92 + toff = (targ = $(targ)).offset();
  93 + }
  94 + }
  95 +
  96 + var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset;
  97 +
  98 + $.each(settings.axis.split(''), function(i, axis) {
  99 + var Pos = axis === 'x' ? 'Left' : 'Top',
  100 + pos = Pos.toLowerCase(),
  101 + key = 'scroll' + Pos,
  102 + prev = $elem[key](),
  103 + max = $scrollTo.max(elem, axis);
  104 +
  105 + if (toff) {// jQuery / DOMElement
  106 + attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]);
  107 +
  108 + // If it's a dom element, reduce the margin
  109 + if (settings.margin) {
  110 + attr[key] -= parseInt(targ.css('margin'+Pos), 10) || 0;
  111 + attr[key] -= parseInt(targ.css('border'+Pos+'Width'), 10) || 0;
  112 + }
  113 +
  114 + attr[key] += offset[pos] || 0;
  115 +
  116 + if (settings.over[pos]) {
  117 + // Scroll to a fraction of its width/height
  118 + attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos];
  119 + }
  120 + } else {
  121 + var val = targ[pos];
  122 + // Handle percentage values
  123 + attr[key] = val.slice && val.slice(-1) === '%' ?
  124 + parseFloat(val) / 100 * max
  125 + : val;
  126 + }
  127 +
  128 + // Number or 'number'
  129 + if (settings.limit && /^\d+$/.test(attr[key])) {
  130 + // Check the limits
  131 + attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
  132 + }
  133 +
  134 + // Don't waste time animating, if there's no need.
  135 + if (!i && settings.axis.length > 1) {
  136 + if (prev === attr[key]) {
  137 + // No animation needed
  138 + attr = {};
  139 + } else if (queue) {
  140 + // Intermediate animation
  141 + animate(settings.onAfterFirst);
  142 + // Don't animate this axis again in the next iteration.
  143 + attr = {};
  144 + }
  145 + }
  146 + });
  147 +
  148 + animate(settings.onAfter);
  149 +
  150 + function animate(callback) {
  151 + var opts = $.extend({}, settings, {
  152 + // The queue setting conflicts with animate()
  153 + // Force it to always be true
  154 + queue: true,
  155 + duration: duration,
  156 + complete: callback && function() {
  157 + callback.call(elem, targ, settings);
  158 + }
  159 + });
  160 + $elem.animate(attr, opts);
  161 + }
  162 + });
  163 + };
  164 +
  165 + // Max scrolling position, works on quirks mode
  166 + // It only fails (not too badly) on IE, quirks mode.
  167 + $scrollTo.max = function(elem, axis) {
  168 + var Dim = axis === 'x' ? 'Width' : 'Height',
  169 + scroll = 'scroll'+Dim;
  170 +
  171 + if (!isWin(elem))
  172 + return elem[scroll] - $(elem)[Dim.toLowerCase()]();
  173 +
  174 + var size = 'client' + Dim,
  175 + doc = elem.ownerDocument || elem.document,
  176 + html = doc.documentElement,
  177 + body = doc.body;
  178 +
  179 + return Math.max(html[scroll], body[scroll]) - Math.min(html[size], body[size]);
  180 + };
  181 +
  182 + function both(val) {
  183 + return $.isFunction(val) || $.isPlainObject(val) ? val : { top:val, left:val };
  184 + }
  185 +
  186 + // Add special hooks so that window scroll properties can be animated
  187 + $.Tween.propHooks.scrollLeft =
  188 + $.Tween.propHooks.scrollTop = {
  189 + get: function(t) {
  190 + return $(t.elem)[t.prop]();
  191 + },
  192 + set: function(t) {
  193 + var curr = this.get(t);
  194 + // If interrupt is true and user scrolled, stop animating
  195 + if (t.options.interrupt && t._last && t._last !== curr) {
  196 + return $(t.elem).stop();
  197 + }
  198 + var next = Math.round(t.now);
  199 + // Don't waste CPU
  200 + // Browsers don't render floating point scroll
  201 + if (curr !== next) {
  202 + $(t.elem)[t.prop](next);
  203 + t._last = this.get(t);
  204 + }
  205 + }
  206 + };
  207 +
  208 + // AMD requirement
  209 + return $scrollTo;
  210 +});
... ...
view/assets/js/external-libs/jquery.ui.widget.js 0 → 100755
... ... @@ -0,0 +1,572 @@
  1 +/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28
  2 +* http://jqueryui.com
  3 +* Includes: widget.js
  4 +* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
  5 +
  6 +(function( factory ) {
  7 + if ( typeof define === "function" && define.amd ) {
  8 +
  9 + // AMD. Register as an anonymous module.
  10 + define([ "jquery" ], factory );
  11 +
  12 + } else if ( typeof exports === "object" ) {
  13 +
  14 + // Node/CommonJS
  15 + factory( require( "jquery" ) );
  16 +
  17 + } else {
  18 +
  19 + // Browser globals
  20 + factory( jQuery );
  21 + }
  22 +}(function( $ ) {
  23 +/*!
  24 + * jQuery UI Widget 1.11.4
  25 + * http://jqueryui.com
  26 + *
  27 + * Copyright jQuery Foundation and other contributors
  28 + * Released under the MIT license.
  29 + * http://jquery.org/license
  30 + *
  31 + * http://api.jqueryui.com/jQuery.widget/
  32 + */
  33 +
  34 +
  35 +var widget_uuid = 0,
  36 + widget_slice = Array.prototype.slice;
  37 +
  38 +$.cleanData = (function( orig ) {
  39 + return function( elems ) {
  40 + var events, elem, i;
  41 + for ( i = 0; (elem = elems[i]) != null; i++ ) {
  42 + try {
  43 +
  44 + // Only trigger remove when necessary to save time
  45 + events = $._data( elem, "events" );
  46 + if ( events && events.remove ) {
  47 + $( elem ).triggerHandler( "remove" );
  48 + }
  49 +
  50 + // http://bugs.jquery.com/ticket/8235
  51 + } catch ( e ) {}
  52 + }
  53 + orig( elems );
  54 + };
  55 +})( $.cleanData );
  56 +
  57 +$.widget = function( name, base, prototype ) {
  58 + var fullName, existingConstructor, constructor, basePrototype,
  59 + // proxiedPrototype allows the provided prototype to remain unmodified
  60 + // so that it can be used as a mixin for multiple widgets (#8876)
  61 + proxiedPrototype = {},
  62 + namespace = name.split( "." )[ 0 ];
  63 +
  64 + name = name.split( "." )[ 1 ];
  65 + fullName = namespace + "-" + name;
  66 +
  67 + if ( !prototype ) {
  68 + prototype = base;
  69 + base = $.Widget;
  70 + }
  71 +
  72 + // create selector for plugin
  73 + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
  74 + return !!$.data( elem, fullName );
  75 + };
  76 +
  77 + $[ namespace ] = $[ namespace ] || {};
  78 + existingConstructor = $[ namespace ][ name ];
  79 + constructor = $[ namespace ][ name ] = function( options, element ) {
  80 + // allow instantiation without "new" keyword
  81 + if ( !this._createWidget ) {
  82 + return new constructor( options, element );
  83 + }
  84 +
  85 + // allow instantiation without initializing for simple inheritance
  86 + // must use "new" keyword (the code above always passes args)
  87 + if ( arguments.length ) {
  88 + this._createWidget( options, element );
  89 + }
  90 + };
  91 + // extend with the existing constructor to carry over any static properties
  92 + $.extend( constructor, existingConstructor, {
  93 + version: prototype.version,
  94 + // copy the object used to create the prototype in case we need to
  95 + // redefine the widget later
  96 + _proto: $.extend( {}, prototype ),
  97 + // track widgets that inherit from this widget in case this widget is
  98 + // redefined after a widget inherits from it
  99 + _childConstructors: []
  100 + });
  101 +
  102 + basePrototype = new base();
  103 + // we need to make the options hash a property directly on the new instance
  104 + // otherwise we'll modify the options hash on the prototype that we're
  105 + // inheriting from
  106 + basePrototype.options = $.widget.extend( {}, basePrototype.options );
  107 + $.each( prototype, function( prop, value ) {
  108 + if ( !$.isFunction( value ) ) {
  109 + proxiedPrototype[ prop ] = value;
  110 + return;
  111 + }
  112 + proxiedPrototype[ prop ] = (function() {
  113 + var _super = function() {
  114 + return base.prototype[ prop ].apply( this, arguments );
  115 + },
  116 + _superApply = function( args ) {
  117 + return base.prototype[ prop ].apply( this, args );
  118 + };
  119 + return function() {
  120 + var __super = this._super,
  121 + __superApply = this._superApply,
  122 + returnValue;
  123 +
  124 + this._super = _super;
  125 + this._superApply = _superApply;
  126 +
  127 + returnValue = value.apply( this, arguments );
  128 +
  129 + this._super = __super;
  130 + this._superApply = __superApply;
  131 +
  132 + return returnValue;
  133 + };
  134 + })();
  135 + });
  136 + constructor.prototype = $.widget.extend( basePrototype, {
  137 + // TODO: remove support for widgetEventPrefix
  138 + // always use the name + a colon as the prefix, e.g., draggable:start
  139 + // don't prefix for widgets that aren't DOM-based
  140 + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
  141 + }, proxiedPrototype, {
  142 + constructor: constructor,
  143 + namespace: namespace,
  144 + widgetName: name,
  145 + widgetFullName: fullName
  146 + });
  147 +
  148 + // If this widget is being redefined then we need to find all widgets that
  149 + // are inheriting from it and redefine all of them so that they inherit from
  150 + // the new version of this widget. We're essentially trying to replace one
  151 + // level in the prototype chain.
  152 + if ( existingConstructor ) {
  153 + $.each( existingConstructor._childConstructors, function( i, child ) {
  154 + var childPrototype = child.prototype;
  155 +
  156 + // redefine the child widget using the same prototype that was
  157 + // originally used, but inherit from the new version of the base
  158 + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
  159 + });
  160 + // remove the list of existing child constructors from the old constructor
  161 + // so the old child constructors can be garbage collected
  162 + delete existingConstructor._childConstructors;
  163 + } else {
  164 + base._childConstructors.push( constructor );
  165 + }
  166 +
  167 + $.widget.bridge( name, constructor );
  168 +
  169 + return constructor;
  170 +};
  171 +
  172 +$.widget.extend = function( target ) {
  173 + var input = widget_slice.call( arguments, 1 ),
  174 + inputIndex = 0,
  175 + inputLength = input.length,
  176 + key,
  177 + value;
  178 + for ( ; inputIndex < inputLength; inputIndex++ ) {
  179 + for ( key in input[ inputIndex ] ) {
  180 + value = input[ inputIndex ][ key ];
  181 + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
  182 + // Clone objects
  183 + if ( $.isPlainObject( value ) ) {
  184 + target[ key ] = $.isPlainObject( target[ key ] ) ?
  185 + $.widget.extend( {}, target[ key ], value ) :
  186 + // Don't extend strings, arrays, etc. with objects
  187 + $.widget.extend( {}, value );
  188 + // Copy everything else by reference
  189 + } else {
  190 + target[ key ] = value;
  191 + }
  192 + }
  193 + }
  194 + }
  195 + return target;
  196 +};
  197 +
  198 +$.widget.bridge = function( name, object ) {
  199 + var fullName = object.prototype.widgetFullName || name;
  200 + $.fn[ name ] = function( options ) {
  201 + var isMethodCall = typeof options === "string",
  202 + args = widget_slice.call( arguments, 1 ),
  203 + returnValue = this;
  204 +
  205 + if ( isMethodCall ) {
  206 + this.each(function() {
  207 + var methodValue,
  208 + instance = $.data( this, fullName );
  209 + if ( options === "instance" ) {
  210 + returnValue = instance;
  211 + return false;
  212 + }
  213 + if ( !instance ) {
  214 + return $.error( "cannot call methods on " + name + " prior to initialization; " +
  215 + "attempted to call method '" + options + "'" );
  216 + }
  217 + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
  218 + return $.error( "no such method '" + options + "' for " + name + " widget instance" );
  219 + }
  220 + methodValue = instance[ options ].apply( instance, args );
  221 + if ( methodValue !== instance && methodValue !== undefined ) {
  222 + returnValue = methodValue && methodValue.jquery ?
  223 + returnValue.pushStack( methodValue.get() ) :
  224 + methodValue;
  225 + return false;
  226 + }
  227 + });
  228 + } else {
  229 +
  230 + // Allow multiple hashes to be passed on init
  231 + if ( args.length ) {
  232 + options = $.widget.extend.apply( null, [ options ].concat(args) );
  233 + }
  234 +
  235 + this.each(function() {
  236 + var instance = $.data( this, fullName );
  237 + if ( instance ) {
  238 + instance.option( options || {} );
  239 + if ( instance._init ) {
  240 + instance._init();
  241 + }
  242 + } else {
  243 + $.data( this, fullName, new object( options, this ) );
  244 + }
  245 + });
  246 + }
  247 +
  248 + return returnValue;
  249 + };
  250 +};
  251 +
  252 +$.Widget = function( /* options, element */ ) {};
  253 +$.Widget._childConstructors = [];
  254 +
  255 +$.Widget.prototype = {
  256 + widgetName: "widget",
  257 + widgetEventPrefix: "",
  258 + defaultElement: "<div>",
  259 + options: {
  260 + disabled: false,
  261 +
  262 + // callbacks
  263 + create: null
  264 + },
  265 + _createWidget: function( options, element ) {
  266 + element = $( element || this.defaultElement || this )[ 0 ];
  267 + this.element = $( element );
  268 + this.uuid = widget_uuid++;
  269 + this.eventNamespace = "." + this.widgetName + this.uuid;
  270 +
  271 + this.bindings = $();
  272 + this.hoverable = $();
  273 + this.focusable = $();
  274 +
  275 + if ( element !== this ) {
  276 + $.data( element, this.widgetFullName, this );
  277 + this._on( true, this.element, {
  278 + remove: function( event ) {
  279 + if ( event.target === element ) {
  280 + this.destroy();
  281 + }
  282 + }
  283 + });
  284 + this.document = $( element.style ?
  285 + // element within the document
  286 + element.ownerDocument :
  287 + // element is window or document
  288 + element.document || element );
  289 + this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
  290 + }
  291 +
  292 + this.options = $.widget.extend( {},
  293 + this.options,
  294 + this._getCreateOptions(),
  295 + options );
  296 +
  297 + this._create();
  298 + this._trigger( "create", null, this._getCreateEventData() );
  299 + this._init();
  300 + },
  301 + _getCreateOptions: $.noop,
  302 + _getCreateEventData: $.noop,
  303 + _create: $.noop,
  304 + _init: $.noop,
  305 +
  306 + destroy: function() {
  307 + this._destroy();
  308 + // we can probably remove the unbind calls in 2.0
  309 + // all event bindings should go through this._on()
  310 + this.element
  311 + .unbind( this.eventNamespace )
  312 + .removeData( this.widgetFullName )
  313 + // support: jquery <1.6.3
  314 + // http://bugs.jquery.com/ticket/9413
  315 + .removeData( $.camelCase( this.widgetFullName ) );
  316 + this.widget()
  317 + .unbind( this.eventNamespace )
  318 + .removeAttr( "aria-disabled" )
  319 + .removeClass(
  320 + this.widgetFullName + "-disabled " +
  321 + "ui-state-disabled" );
  322 +
  323 + // clean up events and states
  324 + this.bindings.unbind( this.eventNamespace );
  325 + this.hoverable.removeClass( "ui-state-hover" );
  326 + this.focusable.removeClass( "ui-state-focus" );
  327 + },
  328 + _destroy: $.noop,
  329 +
  330 + widget: function() {
  331 + return this.element;
  332 + },
  333 +
  334 + option: function( key, value ) {
  335 + var options = key,
  336 + parts,
  337 + curOption,
  338 + i;
  339 +
  340 + if ( arguments.length === 0 ) {
  341 + // don't return a reference to the internal hash
  342 + return $.widget.extend( {}, this.options );
  343 + }
  344 +
  345 + if ( typeof key === "string" ) {
  346 + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
  347 + options = {};
  348 + parts = key.split( "." );
  349 + key = parts.shift();
  350 + if ( parts.length ) {
  351 + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
  352 + for ( i = 0; i < parts.length - 1; i++ ) {
  353 + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
  354 + curOption = curOption[ parts[ i ] ];
  355 + }
  356 + key = parts.pop();
  357 + if ( arguments.length === 1 ) {
  358 + return curOption[ key ] === undefined ? null : curOption[ key ];
  359 + }
  360 + curOption[ key ] = value;
  361 + } else {
  362 + if ( arguments.length === 1 ) {
  363 + return this.options[ key ] === undefined ? null : this.options[ key ];
  364 + }
  365 + options[ key ] = value;
  366 + }
  367 + }
  368 +
  369 + this._setOptions( options );
  370 +
  371 + return this;
  372 + },
  373 + _setOptions: function( options ) {
  374 + var key;
  375 +
  376 + for ( key in options ) {
  377 + this._setOption( key, options[ key ] );
  378 + }
  379 +
  380 + return this;
  381 + },
  382 + _setOption: function( key, value ) {
  383 + this.options[ key ] = value;
  384 +
  385 + if ( key === "disabled" ) {
  386 + this.widget()
  387 + .toggleClass( this.widgetFullName + "-disabled", !!value );
  388 +
  389 + // If the widget is becoming disabled, then nothing is interactive
  390 + if ( value ) {
  391 + this.hoverable.removeClass( "ui-state-hover" );
  392 + this.focusable.removeClass( "ui-state-focus" );
  393 + }
  394 + }
  395 +
  396 + return this;
  397 + },
  398 +
  399 + enable: function() {
  400 + return this._setOptions({ disabled: false });
  401 + },
  402 + disable: function() {
  403 + return this._setOptions({ disabled: true });
  404 + },
  405 +
  406 + _on: function( suppressDisabledCheck, element, handlers ) {
  407 + var delegateElement,
  408 + instance = this;
  409 +
  410 + // no suppressDisabledCheck flag, shuffle arguments
  411 + if ( typeof suppressDisabledCheck !== "boolean" ) {
  412 + handlers = element;
  413 + element = suppressDisabledCheck;
  414 + suppressDisabledCheck = false;
  415 + }
  416 +
  417 + // no element argument, shuffle and use this.element
  418 + if ( !handlers ) {
  419 + handlers = element;
  420 + element = this.element;
  421 + delegateElement = this.widget();
  422 + } else {
  423 + element = delegateElement = $( element );
  424 + this.bindings = this.bindings.add( element );
  425 + }
  426 +
  427 + $.each( handlers, function( event, handler ) {
  428 + function handlerProxy() {
  429 + // allow widgets to customize the disabled handling
  430 + // - disabled as an array instead of boolean
  431 + // - disabled class as method for disabling individual parts
  432 + if ( !suppressDisabledCheck &&
  433 + ( instance.options.disabled === true ||
  434 + $( this ).hasClass( "ui-state-disabled" ) ) ) {
  435 + return;
  436 + }
  437 + return ( typeof handler === "string" ? instance[ handler ] : handler )
  438 + .apply( instance, arguments );
  439 + }
  440 +
  441 + // copy the guid so direct unbinding works
  442 + if ( typeof handler !== "string" ) {
  443 + handlerProxy.guid = handler.guid =
  444 + handler.guid || handlerProxy.guid || $.guid++;
  445 + }
  446 +
  447 + var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
  448 + eventName = match[1] + instance.eventNamespace,
  449 + selector = match[2];
  450 + if ( selector ) {
  451 + delegateElement.delegate( selector, eventName, handlerProxy );
  452 + } else {
  453 + element.bind( eventName, handlerProxy );
  454 + }
  455 + });
  456 + },
  457 +
  458 + _off: function( element, eventName ) {
  459 + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
  460 + this.eventNamespace;
  461 + element.unbind( eventName ).undelegate( eventName );
  462 +
  463 + // Clear the stack to avoid memory leaks (#10056)
  464 + this.bindings = $( this.bindings.not( element ).get() );
  465 + this.focusable = $( this.focusable.not( element ).get() );
  466 + this.hoverable = $( this.hoverable.not( element ).get() );
  467 + },
  468 +
  469 + _delay: function( handler, delay ) {
  470 + function handlerProxy() {
  471 + return ( typeof handler === "string" ? instance[ handler ] : handler )
  472 + .apply( instance, arguments );
  473 + }
  474 + var instance = this;
  475 + return setTimeout( handlerProxy, delay || 0 );
  476 + },
  477 +
  478 + _hoverable: function( element ) {
  479 + this.hoverable = this.hoverable.add( element );
  480 + this._on( element, {
  481 + mouseenter: function( event ) {
  482 + $( event.currentTarget ).addClass( "ui-state-hover" );
  483 + },
  484 + mouseleave: function( event ) {
  485 + $( event.currentTarget ).removeClass( "ui-state-hover" );
  486 + }
  487 + });
  488 + },
  489 +
  490 + _focusable: function( element ) {
  491 + this.focusable = this.focusable.add( element );
  492 + this._on( element, {
  493 + focusin: function( event ) {
  494 + $( event.currentTarget ).addClass( "ui-state-focus" );
  495 + },
  496 + focusout: function( event ) {
  497 + $( event.currentTarget ).removeClass( "ui-state-focus" );
  498 + }
  499 + });
  500 + },
  501 +
  502 + _trigger: function( type, event, data ) {
  503 + var prop, orig,
  504 + callback = this.options[ type ];
  505 +
  506 + data = data || {};
  507 + event = $.Event( event );
  508 + event.type = ( type === this.widgetEventPrefix ?
  509 + type :
  510 + this.widgetEventPrefix + type ).toLowerCase();
  511 + // the original event may come from any element
  512 + // so we need to reset the target on the new event
  513 + event.target = this.element[ 0 ];
  514 +
  515 + // copy original event properties over to the new event
  516 + orig = event.originalEvent;
  517 + if ( orig ) {
  518 + for ( prop in orig ) {
  519 + if ( !( prop in event ) ) {
  520 + event[ prop ] = orig[ prop ];
  521 + }
  522 + }
  523 + }
  524 +
  525 + this.element.trigger( event, data );
  526 + return !( $.isFunction( callback ) &&
  527 + callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
  528 + event.isDefaultPrevented() );
  529 + }
  530 +};
  531 +
  532 +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
  533 + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
  534 + if ( typeof options === "string" ) {
  535 + options = { effect: options };
  536 + }
  537 + var hasOptions,
  538 + effectName = !options ?
  539 + method :
  540 + options === true || typeof options === "number" ?
  541 + defaultEffect :
  542 + options.effect || defaultEffect;
  543 + options = options || {};
  544 + if ( typeof options === "number" ) {
  545 + options = { duration: options };
  546 + }
  547 + hasOptions = !$.isEmptyObject( options );
  548 + options.complete = callback;
  549 + if ( options.delay ) {
  550 + element.delay( options.delay );
  551 + }
  552 + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
  553 + element[ method ]( options );
  554 + } else if ( effectName !== method && element[ effectName ] ) {
  555 + element[ effectName ]( options.duration, options.easing, callback );
  556 + } else {
  557 + element.queue(function( next ) {
  558 + $( this )[ method ]();
  559 + if ( callback ) {
  560 + callback.call( element[ 0 ] );
  561 + }
  562 + next();
  563 + });
  564 + }
  565 + };
  566 +});
  567 +
  568 +var widget = $.widget;
  569 +
  570 +
  571 +
  572 +}));
... ...
view/assets/js/external-libs/js.cookie.js 0 → 100644
... ... @@ -0,0 +1,145 @@
  1 +/*!
  2 + * JavaScript Cookie v2.0.4
  3 + * https://github.com/js-cookie/js-cookie
  4 + *
  5 + * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
  6 + * Released under the MIT license
  7 + */
  8 +(function(factory) {
  9 + if (typeof define === 'function' && define.amd) {
  10 + define(factory);
  11 + } else if (typeof exports === 'object') {
  12 + module.exports = factory();
  13 + } else {
  14 + var _OldCookies = window.Cookies;
  15 + var api = window.Cookies = factory();
  16 + api.noConflict = function() {
  17 + window.Cookies = _OldCookies;
  18 + return api;
  19 + };
  20 + }
  21 +}(function() {
  22 + function extend() {
  23 + var i = 0;
  24 + var result = {};
  25 + for (; i < arguments.length; i++) {
  26 + var attributes = arguments[ i ];
  27 + for (var key in attributes) {
  28 + result[key] = attributes[key];
  29 + }
  30 + }
  31 + return result;
  32 + }
  33 +
  34 + function init(converter) {
  35 + function api(key, value, attributes) {
  36 + var result;
  37 +
  38 + // Write
  39 +
  40 + if (arguments.length > 1) {
  41 + attributes = extend({
  42 + path: '/'
  43 + }, api.defaults, attributes);
  44 +
  45 + if (typeof attributes.expires === 'number') {
  46 + var expires = new Date();
  47 + expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
  48 + attributes.expires = expires;
  49 + }
  50 +
  51 + try {
  52 + result = JSON.stringify(value);
  53 + if (/^[\{\[]/.test(result)) {
  54 + value = result;
  55 + }
  56 + } catch (e) {}
  57 +
  58 + if (!converter.write) {
  59 + value = encodeURIComponent(String(value))
  60 + .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
  61 + } else {
  62 + value = converter.write(value, key);
  63 + }
  64 +
  65 + key = encodeURIComponent(String(key));
  66 + key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
  67 + key = key.replace(/[\(\)]/g, escape);
  68 +
  69 + return (document.cookie = [
  70 + key, '=', value,
  71 + attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
  72 + attributes.path && '; path=' + attributes.path,
  73 + attributes.domain && '; domain=' + attributes.domain,
  74 + attributes.secure ? '; secure' : ''
  75 + ].join(''));
  76 + }
  77 +
  78 + // Read
  79 +
  80 + if (!key) {
  81 + result = {};
  82 + }
  83 +
  84 + // To prevent the for loop in the first place assign an empty array
  85 + // in case there are no cookies at all. Also prevents odd result when
  86 + // calling "get()"
  87 + var cookies = document.cookie ? document.cookie.split('; ') : [];
  88 + var rdecode = /(%[0-9A-Z]{2})+/g;
  89 + var i = 0;
  90 +
  91 + for (; i < cookies.length; i++) {
  92 + var parts = cookies[i].split('=');
  93 + var name = parts[0].replace(rdecode, decodeURIComponent);
  94 + var cookie = parts.slice(1).join('=');
  95 +
  96 + if (cookie.charAt(0) === '"') {
  97 + cookie = cookie.slice(1, -1);
  98 + }
  99 +
  100 + try {
  101 + cookie = converter.read ?
  102 + converter.read(cookie, name) : converter(cookie, name) ||
  103 + cookie.replace(rdecode, decodeURIComponent);
  104 +
  105 + if (this.json) {
  106 + try {
  107 + cookie = JSON.parse(cookie);
  108 + } catch (e) {}
  109 + }
  110 +
  111 + if (key === name) {
  112 + result = cookie;
  113 + break;
  114 + }
  115 +
  116 + if (!key) {
  117 + result[name] = cookie;
  118 + }
  119 + } catch (e) {}
  120 + }
  121 +
  122 + return result;
  123 + }
  124 +
  125 + api.get = api.set = api;
  126 + api.getJSON = function() {
  127 + return api.apply({
  128 + json: true
  129 + }, [].slice.call(arguments));
  130 + };
  131 + api.defaults = {};
  132 +
  133 + api.remove = function(key, attributes) {
  134 + api(key, '', extend(attributes, {
  135 + expires: -1
  136 + }));
  137 + };
  138 +
  139 + api.withConverter = init;
  140 +
  141 + return api;
  142 + }
  143 +
  144 + return init(function() {});
  145 +}));
... ...
view/assets/js/facial.js
... ... @@ -1,21 +0,0 @@
1   -(function(facial, $, undefined) {
2   -
3   - facial.setup = function(subConfig) {
4   - var baseId = '.selection-panel-body[mainConfig=facial][subConfig='
5   - + subConfig + ']';
6   - $(baseId + ' .selection-panel-option').off('click').on('click',
7   - function() {
8   - wikilibras.selectAnOption(baseId, this);
9   - dynworkflow.userSelectedAnOption();
10   - });
11   - $(baseId + ' .video-panel-option').off('mouseenter').on('mouseenter',
12   - function(event) {
13   - $(this).addClass('video-panel-option-hover');
14   - });
15   - $(baseId + ' .video-panel-option').off('mouseleave').on('mouseleave',
16   - function(event) {
17   - $(this).removeClass('video-panel-option-hover');
18   - });
19   - };
20   -
21   -}(window.facial = window.facial || {}, jQuery));
view/assets/js/helpers/icon-helper.js 0 → 100644
... ... @@ -0,0 +1,85 @@
  1 +(function(iconHelper, $, undefined) {
  2 +
  3 + var baseUrl = '';
  4 +
  5 + function _changeImage(img, url) {
  6 + img.attr('src', url);
  7 + }
  8 +
  9 + function _enableIconHover(container, isHover) {
  10 + var img = $(container).find('img').first();
  11 + var hover_img_url = baseUrl + '/img/' + $(container).attr('name');
  12 + if (isHover) {
  13 + hover_img_url += '-icon-hover.png';
  14 + } else {
  15 + hover_img_url += '-icon.png';
  16 + }
  17 + _changeImage(img, hover_img_url);
  18 + }
  19 +
  20 + function _enableIconCheck(container, isCheck) {
  21 + var img = $(container).find('img').first();
  22 + var check_img_url = baseUrl + '/img/' + $(container).attr('name');
  23 + if (isCheck) {
  24 + check_img_url += '-icon-check.png';
  25 + } else {
  26 + check_img_url += '-icon.png';
  27 + }
  28 + _changeImage(img, check_img_url);
  29 + }
  30 +
  31 + function _selectIcon(iconName, isSelect, panel) {
  32 + panel = typeof panel == 'undefined' ? '' : '[panel=' + panel + ']';
  33 + var icon_id = '.icon_container[name=' + iconName + ']' + panel;
  34 + _enableIconHover(icon_id, isSelect);
  35 + $(icon_id).attr('select', isSelect);
  36 + }
  37 +
  38 + function _deselectIcon(iconName, parent) {
  39 + _selectIcon(iconName, false, parent);
  40 + }
  41 +
  42 + function _setupCheckIcon(option, isCheck, panel) {
  43 + panel = typeof panel == 'undefined' ? '' : '[panel=' + panel + ']';
  44 + var icon_id = '.icon_container[name=' + option + ']' + panel;
  45 + iconHelper.enableIconCheck(icon_id, isCheck);
  46 + $('.icon_container[name=' + option + ']' + panel).attr('complete',
  47 + isCheck);
  48 + }
  49 +
  50 + function _canHover(el) {
  51 + var incompleteConfig = typeof $(el).attr('complete') == 'undefined'
  52 + || $(el).attr('complete') == 'false';
  53 + return (!configurationScreen.isMenuSelected() && incompleteConfig)
  54 + || (typeof $(el).attr('select') == 'undefined' && incompleteConfig);
  55 + }
  56 +
  57 + iconHelper.enableIconHover = function(container, isHover) {
  58 + _enableIconHover(container, isHover);
  59 + }
  60 +
  61 + iconHelper.enableIconCheck = function(container, isCheck) {
  62 + _enableIconCheck(container, isCheck);
  63 + }
  64 +
  65 + iconHelper.setupCheckIcon = function(option, isCheck, panel) {
  66 + _setupCheckIcon(option, isCheck, panel);
  67 + }
  68 +
  69 + iconHelper.selectIcon = function(iconName, isSelect, panel) {
  70 + _selectIcon(iconName, isSelect, panel);
  71 + }
  72 +
  73 + iconHelper.deselectIcon = function(iconName, parent) {
  74 + _deselectIcon(iconName, parent);
  75 + }
  76 +
  77 + iconHelper.canHover = function(el) {
  78 + return _canHover(el);
  79 + }
  80 +
  81 + iconHelper.setup = function(url) {
  82 + baseUrl = url;
  83 + };
  84 +
  85 +}(window.iconHelper = window.iconHelper || {}, jQuery));
... ...
view/assets/js/helpers/tmpJSONParser.js 0 → 100644
... ... @@ -0,0 +1,124 @@
  1 +(function(tmpJSONParser, $, undefined) {
  2 +
  3 + var base_parameter_json = {};
  4 + var movement_parameter_json = {};
  5 +
  6 + function _setupBaseParameterJSON(tmpJSON) {
  7 + base_parameter_json['userId'] = tmpJSON['userId'];
  8 + base_parameter_json['sinal'] = tmpJSON['sinal'];
  9 + base_parameter_json['interpolacao'] = 'normal';
  10 + base_parameter_json['movimentos'] = [];
  11 + movement_parameter_json = {
  12 + 'facial': {},
  13 + 'mao_direita': {},
  14 + 'mao_esquerda': {}
  15 + };
  16 + base_parameter_json['movimentos'].push(movement_parameter_json);
  17 + }
  18 +
  19 + function _parseParameterValue(value) {
  20 + if (typeof value == 'string' && value.toLowerCase() == 'true') {
  21 + return true;
  22 + } else if (typeof value == 'string' && value.toLowerCase() == 'false') {
  23 + return false;
  24 + } else {
  25 + return !isNaN(value) ? parseInt(value) : value;
  26 + }
  27 + }
  28 +
  29 + function _parseTempFacialParameterJSON(tmpJSON) {
  30 + var attrs = dynworkflow.getFacialParameters();
  31 + for (var i in attrs) {
  32 + var attr = attrs[i];
  33 + parameterValue = tmpJSON['facial'][attr][0];
  34 + movement_parameter_json['facial'][attr] = _parseParameterValue(parameterValue);
  35 + }
  36 + }
  37 +
  38 + function _parseHand(hand) {
  39 + var parsedHand = hand == 'right-hand' ? 'mao_direita' : hand;
  40 + parsedHand = hand == 'left-hand' ? 'mao_esquerda' : parsedHand;
  41 + return parsedHand;
  42 + }
  43 +
  44 + // Default parser
  45 + function _defaultMovementParser(tmpJSON, movementName, hand) {
  46 + var attrs = dynworkflow.getMovementParameters(movementName);
  47 + var parsedHand = _parseHand(hand);
  48 +
  49 + for (var i in attrs) {
  50 + var attr = attrs[i];
  51 + var parameterValue = '';
  52 + if (typeof tmpJSON[hand][attr] == "undefined") {
  53 + continue;
  54 + }
  55 + if (attr == 'configuracao') {
  56 + parameterValue = tmpJSON[hand][attr][1];
  57 + } else if (attr == 'articulacao') {
  58 + parameterValue = articulation.processValue(hand, tmpJSON[hand][attr]);
  59 + } else {
  60 + parameterValue = tmpJSON[hand][attr][0];
  61 + }
  62 + movement_parameter_json[parsedHand][movementName][attr] =
  63 + _parseParameterValue(parameterValue);
  64 + }
  65 + }
  66 +
  67 + function _retilinearMovementParser(tmpJSON, movementName, hand) {
  68 + var attrs = dynworkflow.getMovementParameters(movementName);
  69 + var parsedHand = _parseHand(hand);
  70 +
  71 + for (var i in attrs) {
  72 + var attr = attrs[i];
  73 + var initParameterValue = '';
  74 + var endParameterValue = '';
  75 + if (attr == 'configuracao-retilineo') {
  76 + initParameterValue = tmpJSON[hand][attr][1];
  77 + endParameterValue = tmpJSON[hand][attr][3];
  78 + } else if (attr == 'articulacao-retilineo') {
  79 + initSlice = tmpJSON[hand][attr].slice(0, 2);
  80 + endSlice = tmpJSON[hand][attr].slice(2, 4);
  81 + initParameterValue = articulation.processValue(hand, initSlice);
  82 + endParameterValue = articulation.processValue(hand, endSlice);
  83 + } else {
  84 + initParameterValue = tmpJSON[hand][attr][0];
  85 + endParameterValue = tmpJSON[hand][attr][1];
  86 + }
  87 + attr = attr.replace('-retilineo', '');
  88 + var initAttr = attr + '_inicial';
  89 + var endAttr = attr + '_final';
  90 + movement_parameter_json[parsedHand][movementName][initAttr] =
  91 + _parseParameterValue(initParameterValue);
  92 + movement_parameter_json[parsedHand][movementName][endAttr] =
  93 + _parseParameterValue(endParameterValue);
  94 + }
  95 + }
  96 +
  97 + function _parseTempMovementParameterJSON(tmpJSON, hand) {
  98 + var movimentConfig = tmpJSON[hand]['movimento'];
  99 + if (typeof movimentConfig == 'undefined') return;
  100 +
  101 + var movementName = movimentConfig[0];
  102 + var parsedHand = _parseHand(hand);
  103 + movement_parameter_json[parsedHand][movementName] = {};
  104 +
  105 + if (movementName == 'retilineo') {
  106 + _retilinearMovementParser(tmpJSON, movementName, hand);
  107 + } else {
  108 + _defaultMovementParser(tmpJSON, movementName, hand);
  109 + }
  110 + }
  111 +
  112 + tmpJSONParser.parse = function(tmpJSON, rightHand, leftHand) {
  113 + _setupBaseParameterJSON(tmpJSON);
  114 + _parseTempFacialParameterJSON(tmpJSON);
  115 + if (rightHand) {
  116 + _parseTempMovementParameterJSON(tmpJSON, 'right-hand');
  117 + }
  118 + if (leftHand) {
  119 + _parseTempMovementParameterJSON(tmpJSON, 'left-hand');
  120 + }
  121 + return base_parameter_json;
  122 + };
  123 +
  124 +}(window.tmpJSONParser = window.tmpJSONParser || {}, jQuery));
... ...
view/assets/js/helpers/video-helper.js 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +(function(videoHelper, $, undefined) {
  2 +
  3 + function _controlVideo(elId, toPlay) {
  4 + var videoSrc = $(elId).attr("src");
  5 + if (typeof videoSrc == "undefined" ||
  6 + (typeof videoSrc != "undefined" && videoSrc === ""))
  7 + return;
  8 + if (toPlay) {
  9 + $(elId).get(0).play();
  10 + } else {
  11 + $(elId).get(0).pause();
  12 + }
  13 + }
  14 +
  15 + videoHelper.play = function(elId) {
  16 + _controlVideo(elId, true);
  17 + }
  18 +
  19 + videoHelper.pause = function(elId) {
  20 + _controlVideo(elId, false);
  21 + }
  22 +
  23 +}(window.videoHelper = window.videoHelper || {}, jQuery));
... ...
view/assets/js/jquery.fileupload.js
... ... @@ -1,1477 +0,0 @@
1   -/*
2   - * jQuery File Upload Plugin
3   - * https://github.com/blueimp/jQuery-File-Upload
4   - *
5   - * Copyright 2010, Sebastian Tschan
6   - * https://blueimp.net
7   - *
8   - * Licensed under the MIT license:
9   - * http://www.opensource.org/licenses/MIT
10   - */
11   -
12   -/* jshint nomen:false */
13   -/* global define, require, window, document, location, Blob, FormData */
14   -
15   -(function (factory) {
16   - 'use strict';
17   - if (typeof define === 'function' && define.amd) {
18   - // Register as an anonymous AMD module:
19   - define([
20   - 'jquery',
21   - 'jquery.ui.widget'
22   - ], factory);
23   - } else if (typeof exports === 'object') {
24   - // Node/CommonJS:
25   - factory(
26   - require('jquery'),
27   - require('./vendor/jquery.ui.widget')
28   - );
29   - } else {
30   - // Browser globals:
31   - factory(window.jQuery);
32   - }
33   -}(function ($) {
34   - 'use strict';
35   -
36   - // Detect file input support, based on
37   - // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
38   - $.support.fileInput = !(new RegExp(
39   - // Handle devices which give false positives for the feature detection:
40   - '(Android (1\\.[0156]|2\\.[01]))' +
41   - '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
42   - '|(w(eb)?OSBrowser)|(webOS)' +
43   - '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
44   - ).test(window.navigator.userAgent) ||
45   - // Feature detection for all other devices:
46   - $('<input type="file">').prop('disabled'));
47   -
48   - // The FileReader API is not actually used, but works as feature detection,
49   - // as some Safari versions (5?) support XHR file uploads via the FormData API,
50   - // but not non-multipart XHR file uploads.
51   - // window.XMLHttpRequestUpload is not available on IE10, so we check for
52   - // window.ProgressEvent instead to detect XHR2 file upload capability:
53   - $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader);
54   - $.support.xhrFormDataFileUpload = !!window.FormData;
55   -
56   - // Detect support for Blob slicing (required for chunked uploads):
57   - $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
58   - Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
59   -
60   - // Helper function to create drag handlers for dragover/dragenter/dragleave:
61   - function getDragHandler(type) {
62   - var isDragOver = type === 'dragover';
63   - return function (e) {
64   - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
65   - var dataTransfer = e.dataTransfer;
66   - if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 &&
67   - this._trigger(
68   - type,
69   - $.Event(type, {delegatedEvent: e})
70   - ) !== false) {
71   - e.preventDefault();
72   - if (isDragOver) {
73   - dataTransfer.dropEffect = 'copy';
74   - }
75   - }
76   - };
77   - }
78   -
79   - // The fileupload widget listens for change events on file input fields defined
80   - // via fileInput setting and paste or drop events of the given dropZone.
81   - // In addition to the default jQuery Widget methods, the fileupload widget
82   - // exposes the "add" and "send" methods, to add or directly send files using
83   - // the fileupload API.
84   - // By default, files added via file input selection, paste, drag & drop or
85   - // "add" method are uploaded immediately, but it is possible to override
86   - // the "add" callback option to queue file uploads.
87   - $.widget('blueimp.fileupload', {
88   -
89   - options: {
90   - // The drop target element(s), by the default the complete document.
91   - // Set to null to disable drag & drop support:
92   - dropZone: $(document),
93   - // The paste target element(s), by the default undefined.
94   - // Set to a DOM node or jQuery object to enable file pasting:
95   - pasteZone: undefined,
96   - // The file input field(s), that are listened to for change events.
97   - // If undefined, it is set to the file input fields inside
98   - // of the widget element on plugin initialization.
99   - // Set to null to disable the change listener.
100   - fileInput: undefined,
101   - // By default, the file input field is replaced with a clone after
102   - // each input field change event. This is required for iframe transport
103   - // queues and allows change events to be fired for the same file
104   - // selection, but can be disabled by setting the following option to false:
105   - replaceFileInput: true,
106   - // The parameter name for the file form data (the request argument name).
107   - // If undefined or empty, the name property of the file input field is
108   - // used, or "files[]" if the file input name property is also empty,
109   - // can be a string or an array of strings:
110   - paramName: undefined,
111   - // By default, each file of a selection is uploaded using an individual
112   - // request for XHR type uploads. Set to false to upload file
113   - // selections in one request each:
114   - singleFileUploads: true,
115   - // To limit the number of files uploaded with one XHR request,
116   - // set the following option to an integer greater than 0:
117   - limitMultiFileUploads: undefined,
118   - // The following option limits the number of files uploaded with one
119   - // XHR request to keep the request size under or equal to the defined
120   - // limit in bytes:
121   - limitMultiFileUploadSize: undefined,
122   - // Multipart file uploads add a number of bytes to each uploaded file,
123   - // therefore the following option adds an overhead for each file used
124   - // in the limitMultiFileUploadSize configuration:
125   - limitMultiFileUploadSizeOverhead: 512,
126   - // Set the following option to true to issue all file upload requests
127   - // in a sequential order:
128   - sequentialUploads: false,
129   - // To limit the number of concurrent uploads,
130   - // set the following option to an integer greater than 0:
131   - limitConcurrentUploads: undefined,
132   - // Set the following option to true to force iframe transport uploads:
133   - forceIframeTransport: false,
134   - // Set the following option to the location of a redirect url on the
135   - // origin server, for cross-domain iframe transport uploads:
136   - redirect: undefined,
137   - // The parameter name for the redirect url, sent as part of the form
138   - // data and set to 'redirect' if this option is empty:
139   - redirectParamName: undefined,
140   - // Set the following option to the location of a postMessage window,
141   - // to enable postMessage transport uploads:
142   - postMessage: undefined,
143   - // By default, XHR file uploads are sent as multipart/form-data.
144   - // The iframe transport is always using multipart/form-data.
145   - // Set to false to enable non-multipart XHR uploads:
146   - multipart: true,
147   - // To upload large files in smaller chunks, set the following option
148   - // to a preferred maximum chunk size. If set to 0, null or undefined,
149   - // or the browser does not support the required Blob API, files will
150   - // be uploaded as a whole.
151   - maxChunkSize: undefined,
152   - // When a non-multipart upload or a chunked multipart upload has been
153   - // aborted, this option can be used to resume the upload by setting
154   - // it to the size of the already uploaded bytes. This option is most
155   - // useful when modifying the options object inside of the "add" or
156   - // "send" callbacks, as the options are cloned for each file upload.
157   - uploadedBytes: undefined,
158   - // By default, failed (abort or error) file uploads are removed from the
159   - // global progress calculation. Set the following option to false to
160   - // prevent recalculating the global progress data:
161   - recalculateProgress: true,
162   - // Interval in milliseconds to calculate and trigger progress events:
163   - progressInterval: 100,
164   - // Interval in milliseconds to calculate progress bitrate:
165   - bitrateInterval: 500,
166   - // By default, uploads are started automatically when adding files:
167   - autoUpload: true,
168   -
169   - // Error and info messages:
170   - messages: {
171   - uploadedBytes: 'Uploaded bytes exceed file size'
172   - },
173   -
174   - // Translation function, gets the message key to be translated
175   - // and an object with context specific data as arguments:
176   - i18n: function (message, context) {
177   - message = this.messages[message] || message.toString();
178   - if (context) {
179   - $.each(context, function (key, value) {
180   - message = message.replace('{' + key + '}', value);
181   - });
182   - }
183   - return message;
184   - },
185   -
186   - // Additional form data to be sent along with the file uploads can be set
187   - // using this option, which accepts an array of objects with name and
188   - // value properties, a function returning such an array, a FormData
189   - // object (for XHR file uploads), or a simple object.
190   - // The form of the first fileInput is given as parameter to the function:
191   - formData: function (form) {
192   - return form.serializeArray();
193   - },
194   -
195   - // The add callback is invoked as soon as files are added to the fileupload
196   - // widget (via file input selection, drag & drop, paste or add API call).
197   - // If the singleFileUploads option is enabled, this callback will be
198   - // called once for each file in the selection for XHR file uploads, else
199   - // once for each file selection.
200   - //
201   - // The upload starts when the submit method is invoked on the data parameter.
202   - // The data object contains a files property holding the added files
203   - // and allows you to override plugin options as well as define ajax settings.
204   - //
205   - // Listeners for this callback can also be bound the following way:
206   - // .bind('fileuploadadd', func);
207   - //
208   - // data.submit() returns a Promise object and allows to attach additional
209   - // handlers using jQuery's Deferred callbacks:
210   - // data.submit().done(func).fail(func).always(func);
211   - add: function (e, data) {
212   - if (e.isDefaultPrevented()) {
213   - return false;
214   - }
215   - if (data.autoUpload || (data.autoUpload !== false &&
216   - $(this).fileupload('option', 'autoUpload'))) {
217   - data.process().done(function () {
218   - data.submit();
219   - });
220   - }
221   - },
222   -
223   - // Other callbacks:
224   -
225   - // Callback for the submit event of each file upload:
226   - // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
227   -
228   - // Callback for the start of each file upload request:
229   - // send: function (e, data) {}, // .bind('fileuploadsend', func);
230   -
231   - // Callback for successful uploads:
232   - // done: function (e, data) {}, // .bind('fileuploaddone', func);
233   -
234   - // Callback for failed (abort or error) uploads:
235   - // fail: function (e, data) {}, // .bind('fileuploadfail', func);
236   -
237   - // Callback for completed (success, abort or error) requests:
238   - // always: function (e, data) {}, // .bind('fileuploadalways', func);
239   -
240   - // Callback for upload progress events:
241   - // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
242   -
243   - // Callback for global upload progress events:
244   - // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
245   -
246   - // Callback for uploads start, equivalent to the global ajaxStart event:
247   - // start: function (e) {}, // .bind('fileuploadstart', func);
248   -
249   - // Callback for uploads stop, equivalent to the global ajaxStop event:
250   - // stop: function (e) {}, // .bind('fileuploadstop', func);
251   -
252   - // Callback for change events of the fileInput(s):
253   - // change: function (e, data) {}, // .bind('fileuploadchange', func);
254   -
255   - // Callback for paste events to the pasteZone(s):
256   - // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
257   -
258   - // Callback for drop events of the dropZone(s):
259   - // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
260   -
261   - // Callback for dragover events of the dropZone(s):
262   - // dragover: function (e) {}, // .bind('fileuploaddragover', func);
263   -
264   - // Callback for the start of each chunk upload request:
265   - // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
266   -
267   - // Callback for successful chunk uploads:
268   - // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
269   -
270   - // Callback for failed (abort or error) chunk uploads:
271   - // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
272   -
273   - // Callback for completed (success, abort or error) chunk upload requests:
274   - // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
275   -
276   - // The plugin options are used as settings object for the ajax calls.
277   - // The following are jQuery ajax settings required for the file uploads:
278   - processData: false,
279   - contentType: false,
280   - cache: false,
281   - timeout: 0
282   - },
283   -
284   - // A list of options that require reinitializing event listeners and/or
285   - // special initialization code:
286   - _specialOptions: [
287   - 'fileInput',
288   - 'dropZone',
289   - 'pasteZone',
290   - 'multipart',
291   - 'forceIframeTransport'
292   - ],
293   -
294   - _blobSlice: $.support.blobSlice && function () {
295   - var slice = this.slice || this.webkitSlice || this.mozSlice;
296   - return slice.apply(this, arguments);
297   - },
298   -
299   - _BitrateTimer: function () {
300   - this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
301   - this.loaded = 0;
302   - this.bitrate = 0;
303   - this.getBitrate = function (now, loaded, interval) {
304   - var timeDiff = now - this.timestamp;
305   - if (!this.bitrate || !interval || timeDiff > interval) {
306   - this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
307   - this.loaded = loaded;
308   - this.timestamp = now;
309   - }
310   - return this.bitrate;
311   - };
312   - },
313   -
314   - _isXHRUpload: function (options) {
315   - return !options.forceIframeTransport &&
316   - ((!options.multipart && $.support.xhrFileUpload) ||
317   - $.support.xhrFormDataFileUpload);
318   - },
319   -
320   - _getFormData: function (options) {
321   - var formData;
322   - if ($.type(options.formData) === 'function') {
323   - return options.formData(options.form);
324   - }
325   - if ($.isArray(options.formData)) {
326   - return options.formData;
327   - }
328   - if ($.type(options.formData) === 'object') {
329   - formData = [];
330   - $.each(options.formData, function (name, value) {
331   - formData.push({name: name, value: value});
332   - });
333   - return formData;
334   - }
335   - return [];
336   - },
337   -
338   - _getTotal: function (files) {
339   - var total = 0;
340   - $.each(files, function (index, file) {
341   - total += file.size || 1;
342   - });
343   - return total;
344   - },
345   -
346   - _initProgressObject: function (obj) {
347   - var progress = {
348   - loaded: 0,
349   - total: 0,
350   - bitrate: 0
351   - };
352   - if (obj._progress) {
353   - $.extend(obj._progress, progress);
354   - } else {
355   - obj._progress = progress;
356   - }
357   - },
358   -
359   - _initResponseObject: function (obj) {
360   - var prop;
361   - if (obj._response) {
362   - for (prop in obj._response) {
363   - if (obj._response.hasOwnProperty(prop)) {
364   - delete obj._response[prop];
365   - }
366   - }
367   - } else {
368   - obj._response = {};
369   - }
370   - },
371   -
372   - _onProgress: function (e, data) {
373   - if (e.lengthComputable) {
374   - var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
375   - loaded;
376   - if (data._time && data.progressInterval &&
377   - (now - data._time < data.progressInterval) &&
378   - e.loaded !== e.total) {
379   - return;
380   - }
381   - data._time = now;
382   - loaded = Math.floor(
383   - e.loaded / e.total * (data.chunkSize || data._progress.total)
384   - ) + (data.uploadedBytes || 0);
385   - // Add the difference from the previously loaded state
386   - // to the global loaded counter:
387   - this._progress.loaded += (loaded - data._progress.loaded);
388   - this._progress.bitrate = this._bitrateTimer.getBitrate(
389   - now,
390   - this._progress.loaded,
391   - data.bitrateInterval
392   - );
393   - data._progress.loaded = data.loaded = loaded;
394   - data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
395   - now,
396   - loaded,
397   - data.bitrateInterval
398   - );
399   - // Trigger a custom progress event with a total data property set
400   - // to the file size(s) of the current upload and a loaded data
401   - // property calculated accordingly:
402   - this._trigger(
403   - 'progress',
404   - $.Event('progress', {delegatedEvent: e}),
405   - data
406   - );
407   - // Trigger a global progress event for all current file uploads,
408   - // including ajax calls queued for sequential file uploads:
409   - this._trigger(
410   - 'progressall',
411   - $.Event('progressall', {delegatedEvent: e}),
412   - this._progress
413   - );
414   - }
415   - },
416   -
417   - _initProgressListener: function (options) {
418   - var that = this,
419   - xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
420   - // Accesss to the native XHR object is required to add event listeners
421   - // for the upload progress event:
422   - if (xhr.upload) {
423   - $(xhr.upload).bind('progress', function (e) {
424   - var oe = e.originalEvent;
425   - // Make sure the progress event properties get copied over:
426   - e.lengthComputable = oe.lengthComputable;
427   - e.loaded = oe.loaded;
428   - e.total = oe.total;
429   - that._onProgress(e, options);
430   - });
431   - options.xhr = function () {
432   - return xhr;
433   - };
434   - }
435   - },
436   -
437   - _isInstanceOf: function (type, obj) {
438   - // Cross-frame instanceof check
439   - return Object.prototype.toString.call(obj) === '[object ' + type + ']';
440   - },
441   -
442   - _initXHRData: function (options) {
443   - var that = this,
444   - formData,
445   - file = options.files[0],
446   - // Ignore non-multipart setting if not supported:
447   - multipart = options.multipart || !$.support.xhrFileUpload,
448   - paramName = $.type(options.paramName) === 'array' ?
449   - options.paramName[0] : options.paramName;
450   - options.headers = $.extend({}, options.headers);
451   - if (options.contentRange) {
452   - options.headers['Content-Range'] = options.contentRange;
453   - }
454   - if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
455   - options.headers['Content-Disposition'] = 'attachment; filename="' +
456   - encodeURI(file.name) + '"';
457   - }
458   - if (!multipart) {
459   - options.contentType = file.type || 'application/octet-stream';
460   - options.data = options.blob || file;
461   - } else if ($.support.xhrFormDataFileUpload) {
462   - if (options.postMessage) {
463   - // window.postMessage does not allow sending FormData
464   - // objects, so we just add the File/Blob objects to
465   - // the formData array and let the postMessage window
466   - // create the FormData object out of this array:
467   - formData = this._getFormData(options);
468   - if (options.blob) {
469   - formData.push({
470   - name: paramName,
471   - value: options.blob
472   - });
473   - } else {
474   - $.each(options.files, function (index, file) {
475   - formData.push({
476   - name: ($.type(options.paramName) === 'array' &&
477   - options.paramName[index]) || paramName,
478   - value: file
479   - });
480   - });
481   - }
482   - } else {
483   - if (that._isInstanceOf('FormData', options.formData)) {
484   - formData = options.formData;
485   - } else {
486   - formData = new FormData();
487   - $.each(this._getFormData(options), function (index, field) {
488   - formData.append(field.name, field.value);
489   - });
490   - }
491   - if (options.blob) {
492   - formData.append(paramName, options.blob, file.name);
493   - } else {
494   - $.each(options.files, function (index, file) {
495   - // This check allows the tests to run with
496   - // dummy objects:
497   - if (that._isInstanceOf('File', file) ||
498   - that._isInstanceOf('Blob', file)) {
499   - formData.append(
500   - ($.type(options.paramName) === 'array' &&
501   - options.paramName[index]) || paramName,
502   - file,
503   - file.uploadName || file.name
504   - );
505   - }
506   - });
507   - }
508   - }
509   - options.data = formData;
510   - }
511   - // Blob reference is not needed anymore, free memory:
512   - options.blob = null;
513   - },
514   -
515   - _initIframeSettings: function (options) {
516   - var targetHost = $('<a></a>').prop('href', options.url).prop('host');
517   - // Setting the dataType to iframe enables the iframe transport:
518   - options.dataType = 'iframe ' + (options.dataType || '');
519   - // The iframe transport accepts a serialized array as form data:
520   - options.formData = this._getFormData(options);
521   - // Add redirect url to form data on cross-domain uploads:
522   - if (options.redirect && targetHost && targetHost !== location.host) {
523   - options.formData.push({
524   - name: options.redirectParamName || 'redirect',
525   - value: options.redirect
526   - });
527   - }
528   - },
529   -
530   - _initDataSettings: function (options) {
531   - if (this._isXHRUpload(options)) {
532   - if (!this._chunkedUpload(options, true)) {
533   - if (!options.data) {
534   - this._initXHRData(options);
535   - }
536   - this._initProgressListener(options);
537   - }
538   - if (options.postMessage) {
539   - // Setting the dataType to postmessage enables the
540   - // postMessage transport:
541   - options.dataType = 'postmessage ' + (options.dataType || '');
542   - }
543   - } else {
544   - this._initIframeSettings(options);
545   - }
546   - },
547   -
548   - _getParamName: function (options) {
549   - var fileInput = $(options.fileInput),
550   - paramName = options.paramName;
551   - if (!paramName) {
552   - paramName = [];
553   - fileInput.each(function () {
554   - var input = $(this),
555   - name = input.prop('name') || 'files[]',
556   - i = (input.prop('files') || [1]).length;
557   - while (i) {
558   - paramName.push(name);
559   - i -= 1;
560   - }
561   - });
562   - if (!paramName.length) {
563   - paramName = [fileInput.prop('name') || 'files[]'];
564   - }
565   - } else if (!$.isArray(paramName)) {
566   - paramName = [paramName];
567   - }
568   - return paramName;
569   - },
570   -
571   - _initFormSettings: function (options) {
572   - // Retrieve missing options from the input field and the
573   - // associated form, if available:
574   - if (!options.form || !options.form.length) {
575   - options.form = $(options.fileInput.prop('form'));
576   - // If the given file input doesn't have an associated form,
577   - // use the default widget file input's form:
578   - if (!options.form.length) {
579   - options.form = $(this.options.fileInput.prop('form'));
580   - }
581   - }
582   - options.paramName = this._getParamName(options);
583   - if (!options.url) {
584   - options.url = options.form.prop('action') || location.href;
585   - }
586   - // The HTTP request method must be "POST" or "PUT":
587   - options.type = (options.type ||
588   - ($.type(options.form.prop('method')) === 'string' &&
589   - options.form.prop('method')) || ''
590   - ).toUpperCase();
591   - if (options.type !== 'POST' && options.type !== 'PUT' &&
592   - options.type !== 'PATCH') {
593   - options.type = 'POST';
594   - }
595   - if (!options.formAcceptCharset) {
596   - options.formAcceptCharset = options.form.attr('accept-charset');
597   - }
598   - },
599   -
600   - _getAJAXSettings: function (data) {
601   - var options = $.extend({}, this.options, data);
602   - this._initFormSettings(options);
603   - this._initDataSettings(options);
604   - return options;
605   - },
606   -
607   - // jQuery 1.6 doesn't provide .state(),
608   - // while jQuery 1.8+ removed .isRejected() and .isResolved():
609   - _getDeferredState: function (deferred) {
610   - if (deferred.state) {
611   - return deferred.state();
612   - }
613   - if (deferred.isResolved()) {
614   - return 'resolved';
615   - }
616   - if (deferred.isRejected()) {
617   - return 'rejected';
618   - }
619   - return 'pending';
620   - },
621   -
622   - // Maps jqXHR callbacks to the equivalent
623   - // methods of the given Promise object:
624   - _enhancePromise: function (promise) {
625   - promise.success = promise.done;
626   - promise.error = promise.fail;
627   - promise.complete = promise.always;
628   - return promise;
629   - },
630   -
631   - // Creates and returns a Promise object enhanced with
632   - // the jqXHR methods abort, success, error and complete:
633   - _getXHRPromise: function (resolveOrReject, context, args) {
634   - var dfd = $.Deferred(),
635   - promise = dfd.promise();
636   - context = context || this.options.context || promise;
637   - if (resolveOrReject === true) {
638   - dfd.resolveWith(context, args);
639   - } else if (resolveOrReject === false) {
640   - dfd.rejectWith(context, args);
641   - }
642   - promise.abort = dfd.promise;
643   - return this._enhancePromise(promise);
644   - },
645   -
646   - // Adds convenience methods to the data callback argument:
647   - _addConvenienceMethods: function (e, data) {
648   - var that = this,
649   - getPromise = function (args) {
650   - return $.Deferred().resolveWith(that, args).promise();
651   - };
652   - data.process = function (resolveFunc, rejectFunc) {
653   - if (resolveFunc || rejectFunc) {
654   - data._processQueue = this._processQueue =
655   - (this._processQueue || getPromise([this])).pipe(
656   - function () {
657   - if (data.errorThrown) {
658   - return $.Deferred()
659   - .rejectWith(that, [data]).promise();
660   - }
661   - return getPromise(arguments);
662   - }
663   - ).pipe(resolveFunc, rejectFunc);
664   - }
665   - return this._processQueue || getPromise([this]);
666   - };
667   - data.submit = function () {
668   - if (this.state() !== 'pending') {
669   - data.jqXHR = this.jqXHR =
670   - (that._trigger(
671   - 'submit',
672   - $.Event('submit', {delegatedEvent: e}),
673   - this
674   - ) !== false) && that._onSend(e, this);
675   - }
676   - return this.jqXHR || that._getXHRPromise();
677   - };
678   - data.abort = function () {
679   - if (this.jqXHR) {
680   - return this.jqXHR.abort();
681   - }
682   - this.errorThrown = 'abort';
683   - that._trigger('fail', null, this);
684   - return that._getXHRPromise(false);
685   - };
686   - data.state = function () {
687   - if (this.jqXHR) {
688   - return that._getDeferredState(this.jqXHR);
689   - }
690   - if (this._processQueue) {
691   - return that._getDeferredState(this._processQueue);
692   - }
693   - };
694   - data.processing = function () {
695   - return !this.jqXHR && this._processQueue && that
696   - ._getDeferredState(this._processQueue) === 'pending';
697   - };
698   - data.progress = function () {
699   - return this._progress;
700   - };
701   - data.response = function () {
702   - return this._response;
703   - };
704   - },
705   -
706   - // Parses the Range header from the server response
707   - // and returns the uploaded bytes:
708   - _getUploadedBytes: function (jqXHR) {
709   - var range = jqXHR.getResponseHeader('Range'),
710   - parts = range && range.split('-'),
711   - upperBytesPos = parts && parts.length > 1 &&
712   - parseInt(parts[1], 10);
713   - return upperBytesPos && upperBytesPos + 1;
714   - },
715   -
716   - // Uploads a file in multiple, sequential requests
717   - // by splitting the file up in multiple blob chunks.
718   - // If the second parameter is true, only tests if the file
719   - // should be uploaded in chunks, but does not invoke any
720   - // upload requests:
721   - _chunkedUpload: function (options, testOnly) {
722   - options.uploadedBytes = options.uploadedBytes || 0;
723   - var that = this,
724   - file = options.files[0],
725   - fs = file.size,
726   - ub = options.uploadedBytes,
727   - mcs = options.maxChunkSize || fs,
728   - slice = this._blobSlice,
729   - dfd = $.Deferred(),
730   - promise = dfd.promise(),
731   - jqXHR,
732   - upload;
733   - if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
734   - options.data) {
735   - return false;
736   - }
737   - if (testOnly) {
738   - return true;
739   - }
740   - if (ub >= fs) {
741   - file.error = options.i18n('uploadedBytes');
742   - return this._getXHRPromise(
743   - false,
744   - options.context,
745   - [null, 'error', file.error]
746   - );
747   - }
748   - // The chunk upload method:
749   - upload = function () {
750   - // Clone the options object for each chunk upload:
751   - var o = $.extend({}, options),
752   - currentLoaded = o._progress.loaded;
753   - o.blob = slice.call(
754   - file,
755   - ub,
756   - ub + mcs,
757   - file.type
758   - );
759   - // Store the current chunk size, as the blob itself
760   - // will be dereferenced after data processing:
761   - o.chunkSize = o.blob.size;
762   - // Expose the chunk bytes position range:
763   - o.contentRange = 'bytes ' + ub + '-' +
764   - (ub + o.chunkSize - 1) + '/' + fs;
765   - // Process the upload data (the blob and potential form data):
766   - that._initXHRData(o);
767   - // Add progress listeners for this chunk upload:
768   - that._initProgressListener(o);
769   - jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
770   - that._getXHRPromise(false, o.context))
771   - .done(function (result, textStatus, jqXHR) {
772   - ub = that._getUploadedBytes(jqXHR) ||
773   - (ub + o.chunkSize);
774   - // Create a progress event if no final progress event
775   - // with loaded equaling total has been triggered
776   - // for this chunk:
777   - if (currentLoaded + o.chunkSize - o._progress.loaded) {
778   - that._onProgress($.Event('progress', {
779   - lengthComputable: true,
780   - loaded: ub - o.uploadedBytes,
781   - total: ub - o.uploadedBytes
782   - }), o);
783   - }
784   - options.uploadedBytes = o.uploadedBytes = ub;
785   - o.result = result;
786   - o.textStatus = textStatus;
787   - o.jqXHR = jqXHR;
788   - that._trigger('chunkdone', null, o);
789   - that._trigger('chunkalways', null, o);
790   - if (ub < fs) {
791   - // File upload not yet complete,
792   - // continue with the next chunk:
793   - upload();
794   - } else {
795   - dfd.resolveWith(
796   - o.context,
797   - [result, textStatus, jqXHR]
798   - );
799   - }
800   - })
801   - .fail(function (jqXHR, textStatus, errorThrown) {
802   - o.jqXHR = jqXHR;
803   - o.textStatus = textStatus;
804   - o.errorThrown = errorThrown;
805   - that._trigger('chunkfail', null, o);
806   - that._trigger('chunkalways', null, o);
807   - dfd.rejectWith(
808   - o.context,
809   - [jqXHR, textStatus, errorThrown]
810   - );
811   - });
812   - };
813   - this._enhancePromise(promise);
814   - promise.abort = function () {
815   - return jqXHR.abort();
816   - };
817   - upload();
818   - return promise;
819   - },
820   -
821   - _beforeSend: function (e, data) {
822   - if (this._active === 0) {
823   - // the start callback is triggered when an upload starts
824   - // and no other uploads are currently running,
825   - // equivalent to the global ajaxStart event:
826   - this._trigger('start');
827   - // Set timer for global bitrate progress calculation:
828   - this._bitrateTimer = new this._BitrateTimer();
829   - // Reset the global progress values:
830   - this._progress.loaded = this._progress.total = 0;
831   - this._progress.bitrate = 0;
832   - }
833   - // Make sure the container objects for the .response() and
834   - // .progress() methods on the data object are available
835   - // and reset to their initial state:
836   - this._initResponseObject(data);
837   - this._initProgressObject(data);
838   - data._progress.loaded = data.loaded = data.uploadedBytes || 0;
839   - data._progress.total = data.total = this._getTotal(data.files) || 1;
840   - data._progress.bitrate = data.bitrate = 0;
841   - this._active += 1;
842   - // Initialize the global progress values:
843   - this._progress.loaded += data.loaded;
844   - this._progress.total += data.total;
845   - },
846   -
847   - _onDone: function (result, textStatus, jqXHR, options) {
848   - var total = options._progress.total,
849   - response = options._response;
850   - if (options._progress.loaded < total) {
851   - // Create a progress event if no final progress event
852   - // with loaded equaling total has been triggered:
853   - this._onProgress($.Event('progress', {
854   - lengthComputable: true,
855   - loaded: total,
856   - total: total
857   - }), options);
858   - }
859   - response.result = options.result = result;
860   - response.textStatus = options.textStatus = textStatus;
861   - response.jqXHR = options.jqXHR = jqXHR;
862   - this._trigger('done', null, options);
863   - },
864   -
865   - _onFail: function (jqXHR, textStatus, errorThrown, options) {
866   - var response = options._response;
867   - if (options.recalculateProgress) {
868   - // Remove the failed (error or abort) file upload from
869   - // the global progress calculation:
870   - this._progress.loaded -= options._progress.loaded;
871   - this._progress.total -= options._progress.total;
872   - }
873   - response.jqXHR = options.jqXHR = jqXHR;
874   - response.textStatus = options.textStatus = textStatus;
875   - response.errorThrown = options.errorThrown = errorThrown;
876   - this._trigger('fail', null, options);
877   - },
878   -
879   - _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
880   - // jqXHRorResult, textStatus and jqXHRorError are added to the
881   - // options object via done and fail callbacks
882   - this._trigger('always', null, options);
883   - },
884   -
885   - _onSend: function (e, data) {
886   - if (!data.submit) {
887   - this._addConvenienceMethods(e, data);
888   - }
889   - var that = this,
890   - jqXHR,
891   - aborted,
892   - slot,
893   - pipe,
894   - options = that._getAJAXSettings(data),
895   - send = function () {
896   - that._sending += 1;
897   - // Set timer for bitrate progress calculation:
898   - options._bitrateTimer = new that._BitrateTimer();
899   - jqXHR = jqXHR || (
900   - ((aborted || that._trigger(
901   - 'send',
902   - $.Event('send', {delegatedEvent: e}),
903   - options
904   - ) === false) &&
905   - that._getXHRPromise(false, options.context, aborted)) ||
906   - that._chunkedUpload(options) || $.ajax(options)
907   - ).done(function (result, textStatus, jqXHR) {
908   - that._onDone(result, textStatus, jqXHR, options);
909   - }).fail(function (jqXHR, textStatus, errorThrown) {
910   - that._onFail(jqXHR, textStatus, errorThrown, options);
911   - }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
912   - that._onAlways(
913   - jqXHRorResult,
914   - textStatus,
915   - jqXHRorError,
916   - options
917   - );
918   - that._sending -= 1;
919   - that._active -= 1;
920   - if (options.limitConcurrentUploads &&
921   - options.limitConcurrentUploads > that._sending) {
922   - // Start the next queued upload,
923   - // that has not been aborted:
924   - var nextSlot = that._slots.shift();
925   - while (nextSlot) {
926   - if (that._getDeferredState(nextSlot) === 'pending') {
927   - nextSlot.resolve();
928   - break;
929   - }
930   - nextSlot = that._slots.shift();
931   - }
932   - }
933   - if (that._active === 0) {
934   - // The stop callback is triggered when all uploads have
935   - // been completed, equivalent to the global ajaxStop event:
936   - that._trigger('stop');
937   - }
938   - });
939   - return jqXHR;
940   - };
941   - this._beforeSend(e, options);
942   - if (this.options.sequentialUploads ||
943   - (this.options.limitConcurrentUploads &&
944   - this.options.limitConcurrentUploads <= this._sending)) {
945   - if (this.options.limitConcurrentUploads > 1) {
946   - slot = $.Deferred();
947   - this._slots.push(slot);
948   - pipe = slot.pipe(send);
949   - } else {
950   - this._sequence = this._sequence.pipe(send, send);
951   - pipe = this._sequence;
952   - }
953   - // Return the piped Promise object, enhanced with an abort method,
954   - // which is delegated to the jqXHR object of the current upload,
955   - // and jqXHR callbacks mapped to the equivalent Promise methods:
956   - pipe.abort = function () {
957   - aborted = [undefined, 'abort', 'abort'];
958   - if (!jqXHR) {
959   - if (slot) {
960   - slot.rejectWith(options.context, aborted);
961   - }
962   - return send();
963   - }
964   - return jqXHR.abort();
965   - };
966   - return this._enhancePromise(pipe);
967   - }
968   - return send();
969   - },
970   -
971   - _onAdd: function (e, data) {
972   - var that = this,
973   - result = true,
974   - options = $.extend({}, this.options, data),
975   - files = data.files,
976   - filesLength = files.length,
977   - limit = options.limitMultiFileUploads,
978   - limitSize = options.limitMultiFileUploadSize,
979   - overhead = options.limitMultiFileUploadSizeOverhead,
980   - batchSize = 0,
981   - paramName = this._getParamName(options),
982   - paramNameSet,
983   - paramNameSlice,
984   - fileSet,
985   - i,
986   - j = 0;
987   - if (!filesLength) {
988   - return false;
989   - }
990   - if (limitSize && files[0].size === undefined) {
991   - limitSize = undefined;
992   - }
993   - if (!(options.singleFileUploads || limit || limitSize) ||
994   - !this._isXHRUpload(options)) {
995   - fileSet = [files];
996   - paramNameSet = [paramName];
997   - } else if (!(options.singleFileUploads || limitSize) && limit) {
998   - fileSet = [];
999   - paramNameSet = [];
1000   - for (i = 0; i < filesLength; i += limit) {
1001   - fileSet.push(files.slice(i, i + limit));
1002   - paramNameSlice = paramName.slice(i, i + limit);
1003   - if (!paramNameSlice.length) {
1004   - paramNameSlice = paramName;
1005   - }
1006   - paramNameSet.push(paramNameSlice);
1007   - }
1008   - } else if (!options.singleFileUploads && limitSize) {
1009   - fileSet = [];
1010   - paramNameSet = [];
1011   - for (i = 0; i < filesLength; i = i + 1) {
1012   - batchSize += files[i].size + overhead;
1013   - if (i + 1 === filesLength ||
1014   - ((batchSize + files[i + 1].size + overhead) > limitSize) ||
1015   - (limit && i + 1 - j >= limit)) {
1016   - fileSet.push(files.slice(j, i + 1));
1017   - paramNameSlice = paramName.slice(j, i + 1);
1018   - if (!paramNameSlice.length) {
1019   - paramNameSlice = paramName;
1020   - }
1021   - paramNameSet.push(paramNameSlice);
1022   - j = i + 1;
1023   - batchSize = 0;
1024   - }
1025   - }
1026   - } else {
1027   - paramNameSet = paramName;
1028   - }
1029   - data.originalFiles = files;
1030   - $.each(fileSet || files, function (index, element) {
1031   - var newData = $.extend({}, data);
1032   - newData.files = fileSet ? element : [element];
1033   - newData.paramName = paramNameSet[index];
1034   - that._initResponseObject(newData);
1035   - that._initProgressObject(newData);
1036   - that._addConvenienceMethods(e, newData);
1037   - result = that._trigger(
1038   - 'add',
1039   - $.Event('add', {delegatedEvent: e}),
1040   - newData
1041   - );
1042   - return result;
1043   - });
1044   - return result;
1045   - },
1046   -
1047   - _replaceFileInput: function (data) {
1048   - var input = data.fileInput,
1049   - inputClone = input.clone(true),
1050   - restoreFocus = input.is(document.activeElement);
1051   - // Add a reference for the new cloned file input to the data argument:
1052   - data.fileInputClone = inputClone;
1053   - $('<form></form>').append(inputClone)[0].reset();
1054   - // Detaching allows to insert the fileInput on another form
1055   - // without loosing the file input value:
1056   - input.after(inputClone).detach();
1057   - // If the fileInput had focus before it was detached,
1058   - // restore focus to the inputClone.
1059   - if (restoreFocus) {
1060   - inputClone.focus();
1061   - }
1062   - // Avoid memory leaks with the detached file input:
1063   - $.cleanData(input.unbind('remove'));
1064   - // Replace the original file input element in the fileInput
1065   - // elements set with the clone, which has been copied including
1066   - // event handlers:
1067   - this.options.fileInput = this.options.fileInput.map(function (i, el) {
1068   - if (el === input[0]) {
1069   - return inputClone[0];
1070   - }
1071   - return el;
1072   - });
1073   - // If the widget has been initialized on the file input itself,
1074   - // override this.element with the file input clone:
1075   - if (input[0] === this.element[0]) {
1076   - this.element = inputClone;
1077   - }
1078   - },
1079   -
1080   - _handleFileTreeEntry: function (entry, path) {
1081   - var that = this,
1082   - dfd = $.Deferred(),
1083   - errorHandler = function (e) {
1084   - if (e && !e.entry) {
1085   - e.entry = entry;
1086   - }
1087   - // Since $.when returns immediately if one
1088   - // Deferred is rejected, we use resolve instead.
1089   - // This allows valid files and invalid items
1090   - // to be returned together in one set:
1091   - dfd.resolve([e]);
1092   - },
1093   - successHandler = function (entries) {
1094   - that._handleFileTreeEntries(
1095   - entries,
1096   - path + entry.name + '/'
1097   - ).done(function (files) {
1098   - dfd.resolve(files);
1099   - }).fail(errorHandler);
1100   - },
1101   - readEntries = function () {
1102   - dirReader.readEntries(function (results) {
1103   - if (!results.length) {
1104   - successHandler(entries);
1105   - } else {
1106   - entries = entries.concat(results);
1107   - readEntries();
1108   - }
1109   - }, errorHandler);
1110   - },
1111   - dirReader, entries = [];
1112   - path = path || '';
1113   - if (entry.isFile) {
1114   - if (entry._file) {
1115   - // Workaround for Chrome bug #149735
1116   - entry._file.relativePath = path;
1117   - dfd.resolve(entry._file);
1118   - } else {
1119   - entry.file(function (file) {
1120   - file.relativePath = path;
1121   - dfd.resolve(file);
1122   - }, errorHandler);
1123   - }
1124   - } else if (entry.isDirectory) {
1125   - dirReader = entry.createReader();
1126   - readEntries();
1127   - } else {
1128   - // Return an empy list for file system items
1129   - // other than files or directories:
1130   - dfd.resolve([]);
1131   - }
1132   - return dfd.promise();
1133   - },
1134   -
1135   - _handleFileTreeEntries: function (entries, path) {
1136   - var that = this;
1137   - return $.when.apply(
1138   - $,
1139   - $.map(entries, function (entry) {
1140   - return that._handleFileTreeEntry(entry, path);
1141   - })
1142   - ).pipe(function () {
1143   - return Array.prototype.concat.apply(
1144   - [],
1145   - arguments
1146   - );
1147   - });
1148   - },
1149   -
1150   - _getDroppedFiles: function (dataTransfer) {
1151   - dataTransfer = dataTransfer || {};
1152   - var items = dataTransfer.items;
1153   - if (items && items.length && (items[0].webkitGetAsEntry ||
1154   - items[0].getAsEntry)) {
1155   - return this._handleFileTreeEntries(
1156   - $.map(items, function (item) {
1157   - var entry;
1158   - if (item.webkitGetAsEntry) {
1159   - entry = item.webkitGetAsEntry();
1160   - if (entry) {
1161   - // Workaround for Chrome bug #149735:
1162   - entry._file = item.getAsFile();
1163   - }
1164   - return entry;
1165   - }
1166   - return item.getAsEntry();
1167   - })
1168   - );
1169   - }
1170   - return $.Deferred().resolve(
1171   - $.makeArray(dataTransfer.files)
1172   - ).promise();
1173   - },
1174   -
1175   - _getSingleFileInputFiles: function (fileInput) {
1176   - fileInput = $(fileInput);
1177   - var entries = fileInput.prop('webkitEntries') ||
1178   - fileInput.prop('entries'),
1179   - files,
1180   - value;
1181   - if (entries && entries.length) {
1182   - return this._handleFileTreeEntries(entries);
1183   - }
1184   - files = $.makeArray(fileInput.prop('files'));
1185   - if (!files.length) {
1186   - value = fileInput.prop('value');
1187   - if (!value) {
1188   - return $.Deferred().resolve([]).promise();
1189   - }
1190   - // If the files property is not available, the browser does not
1191   - // support the File API and we add a pseudo File object with
1192   - // the input value as name with path information removed:
1193   - files = [{name: value.replace(/^.*\\/, '')}];
1194   - } else if (files[0].name === undefined && files[0].fileName) {
1195   - // File normalization for Safari 4 and Firefox 3:
1196   - $.each(files, function (index, file) {
1197   - file.name = file.fileName;
1198   - file.size = file.fileSize;
1199   - });
1200   - }
1201   - return $.Deferred().resolve(files).promise();
1202   - },
1203   -
1204   - _getFileInputFiles: function (fileInput) {
1205   - if (!(fileInput instanceof $) || fileInput.length === 1) {
1206   - return this._getSingleFileInputFiles(fileInput);
1207   - }
1208   - return $.when.apply(
1209   - $,
1210   - $.map(fileInput, this._getSingleFileInputFiles)
1211   - ).pipe(function () {
1212   - return Array.prototype.concat.apply(
1213   - [],
1214   - arguments
1215   - );
1216   - });
1217   - },
1218   -
1219   - _onChange: function (e) {
1220   - var that = this,
1221   - data = {
1222   - fileInput: $(e.target),
1223   - form: $(e.target.form)
1224   - };
1225   - this._getFileInputFiles(data.fileInput).always(function (files) {
1226   - data.files = files;
1227   - if (that.options.replaceFileInput) {
1228   - that._replaceFileInput(data);
1229   - }
1230   - if (that._trigger(
1231   - 'change',
1232   - $.Event('change', {delegatedEvent: e}),
1233   - data
1234   - ) !== false) {
1235   - that._onAdd(e, data);
1236   - }
1237   - });
1238   - },
1239   -
1240   - _onPaste: function (e) {
1241   - var items = e.originalEvent && e.originalEvent.clipboardData &&
1242   - e.originalEvent.clipboardData.items,
1243   - data = {files: []};
1244   - if (items && items.length) {
1245   - $.each(items, function (index, item) {
1246   - var file = item.getAsFile && item.getAsFile();
1247   - if (file) {
1248   - data.files.push(file);
1249   - }
1250   - });
1251   - if (this._trigger(
1252   - 'paste',
1253   - $.Event('paste', {delegatedEvent: e}),
1254   - data
1255   - ) !== false) {
1256   - this._onAdd(e, data);
1257   - }
1258   - }
1259   - },
1260   -
1261   - _onDrop: function (e) {
1262   - e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
1263   - var that = this,
1264   - dataTransfer = e.dataTransfer,
1265   - data = {};
1266   - if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
1267   - e.preventDefault();
1268   - this._getDroppedFiles(dataTransfer).always(function (files) {
1269   - data.files = files;
1270   - if (that._trigger(
1271   - 'drop',
1272   - $.Event('drop', {delegatedEvent: e}),
1273   - data
1274   - ) !== false) {
1275   - that._onAdd(e, data);
1276   - }
1277   - });
1278   - }
1279   - },
1280   -
1281   - _onDragOver: getDragHandler('dragover'),
1282   -
1283   - _onDragEnter: getDragHandler('dragenter'),
1284   -
1285   - _onDragLeave: getDragHandler('dragleave'),
1286   -
1287   - _initEventHandlers: function () {
1288   - if (this._isXHRUpload(this.options)) {
1289   - this._on(this.options.dropZone, {
1290   - dragover: this._onDragOver,
1291   - drop: this._onDrop,
1292   - // event.preventDefault() on dragenter is required for IE10+:
1293   - dragenter: this._onDragEnter,
1294   - // dragleave is not required, but added for completeness:
1295   - dragleave: this._onDragLeave
1296   - });
1297   - this._on(this.options.pasteZone, {
1298   - paste: this._onPaste
1299   - });
1300   - }
1301   - if ($.support.fileInput) {
1302   - this._on(this.options.fileInput, {
1303   - change: this._onChange
1304   - });
1305   - }
1306   - },
1307   -
1308   - _destroyEventHandlers: function () {
1309   - this._off(this.options.dropZone, 'dragenter dragleave dragover drop');
1310   - this._off(this.options.pasteZone, 'paste');
1311   - this._off(this.options.fileInput, 'change');
1312   - },
1313   -
1314   - _setOption: function (key, value) {
1315   - var reinit = $.inArray(key, this._specialOptions) !== -1;
1316   - if (reinit) {
1317   - this._destroyEventHandlers();
1318   - }
1319   - this._super(key, value);
1320   - if (reinit) {
1321   - this._initSpecialOptions();
1322   - this._initEventHandlers();
1323   - }
1324   - },
1325   -
1326   - _initSpecialOptions: function () {
1327   - var options = this.options;
1328   - if (options.fileInput === undefined) {
1329   - options.fileInput = this.element.is('input[type="file"]') ?
1330   - this.element : this.element.find('input[type="file"]');
1331   - } else if (!(options.fileInput instanceof $)) {
1332   - options.fileInput = $(options.fileInput);
1333   - }
1334   - if (!(options.dropZone instanceof $)) {
1335   - options.dropZone = $(options.dropZone);
1336   - }
1337   - if (!(options.pasteZone instanceof $)) {
1338   - options.pasteZone = $(options.pasteZone);
1339   - }
1340   - },
1341   -
1342   - _getRegExp: function (str) {
1343   - var parts = str.split('/'),
1344   - modifiers = parts.pop();
1345   - parts.shift();
1346   - return new RegExp(parts.join('/'), modifiers);
1347   - },
1348   -
1349   - _isRegExpOption: function (key, value) {
1350   - return key !== 'url' && $.type(value) === 'string' &&
1351   - /^\/.*\/[igm]{0,3}$/.test(value);
1352   - },
1353   -
1354   - _initDataAttributes: function () {
1355   - var that = this,
1356   - options = this.options,
1357   - data = this.element.data();
1358   - // Initialize options set via HTML5 data-attributes:
1359   - $.each(
1360   - this.element[0].attributes,
1361   - function (index, attr) {
1362   - var key = attr.name.toLowerCase(),
1363   - value;
1364   - if (/^data-/.test(key)) {
1365   - // Convert hyphen-ated key to camelCase:
1366   - key = key.slice(5).replace(/-[a-z]/g, function (str) {
1367   - return str.charAt(1).toUpperCase();
1368   - });
1369   - value = data[key];
1370   - if (that._isRegExpOption(key, value)) {
1371   - value = that._getRegExp(value);
1372   - }
1373   - options[key] = value;
1374   - }
1375   - }
1376   - );
1377   - },
1378   -
1379   - _create: function () {
1380   - this._initDataAttributes();
1381   - this._initSpecialOptions();
1382   - this._slots = [];
1383   - this._sequence = this._getXHRPromise(true);
1384   - this._sending = this._active = 0;
1385   - this._initProgressObject(this);
1386   - this._initEventHandlers();
1387   - },
1388   -
1389   - // This method is exposed to the widget API and allows to query
1390   - // the number of active uploads:
1391   - active: function () {
1392   - return this._active;
1393   - },
1394   -
1395   - // This method is exposed to the widget API and allows to query
1396   - // the widget upload progress.
1397   - // It returns an object with loaded, total and bitrate properties
1398   - // for the running uploads:
1399   - progress: function () {
1400   - return this._progress;
1401   - },
1402   -
1403   - // This method is exposed to the widget API and allows adding files
1404   - // using the fileupload API. The data parameter accepts an object which
1405   - // must have a files property and can contain additional options:
1406   - // .fileupload('add', {files: filesList});
1407   - add: function (data) {
1408   - var that = this;
1409   - if (!data || this.options.disabled) {
1410   - return;
1411   - }
1412   - if (data.fileInput && !data.files) {
1413   - this._getFileInputFiles(data.fileInput).always(function (files) {
1414   - data.files = files;
1415   - that._onAdd(null, data);
1416   - });
1417   - } else {
1418   - data.files = $.makeArray(data.files);
1419   - this._onAdd(null, data);
1420   - }
1421   - },
1422   -
1423   - // This method is exposed to the widget API and allows sending files
1424   - // using the fileupload API. The data parameter accepts an object which
1425   - // must have a files or fileInput property and can contain additional options:
1426   - // .fileupload('send', {files: filesList});
1427   - // The method returns a Promise object for the file upload call.
1428   - send: function (data) {
1429   - if (data && !this.options.disabled) {
1430   - if (data.fileInput && !data.files) {
1431   - var that = this,
1432   - dfd = $.Deferred(),
1433   - promise = dfd.promise(),
1434   - jqXHR,
1435   - aborted;
1436   - promise.abort = function () {
1437   - aborted = true;
1438   - if (jqXHR) {
1439   - return jqXHR.abort();
1440   - }
1441   - dfd.reject(null, 'abort', 'abort');
1442   - return promise;
1443   - };
1444   - this._getFileInputFiles(data.fileInput).always(
1445   - function (files) {
1446   - if (aborted) {
1447   - return;
1448   - }
1449   - if (!files.length) {
1450   - dfd.reject();
1451   - return;
1452   - }
1453   - data.files = files;
1454   - jqXHR = that._onSend(null, data);
1455   - jqXHR.then(
1456   - function (result, textStatus, jqXHR) {
1457   - dfd.resolve(result, textStatus, jqXHR);
1458   - },
1459   - function (jqXHR, textStatus, errorThrown) {
1460   - dfd.reject(jqXHR, textStatus, errorThrown);
1461   - }
1462   - );
1463   - }
1464   - );
1465   - return this._enhancePromise(promise);
1466   - }
1467   - data.files = $.makeArray(data.files);
1468   - if (data.files.length) {
1469   - return this._onSend(null, data);
1470   - }
1471   - }
1472   - return this._getXHRPromise(false, data && data.context);
1473   - }
1474   -
1475   - });
1476   -
1477   -}));
view/assets/js/jquery.iframe-transport.js
... ... @@ -1,217 +0,0 @@
1   -/*
2   - * jQuery Iframe Transport Plugin
3   - * https://github.com/blueimp/jQuery-File-Upload
4   - *
5   - * Copyright 2011, Sebastian Tschan
6   - * https://blueimp.net
7   - *
8   - * Licensed under the MIT license:
9   - * http://www.opensource.org/licenses/MIT
10   - */
11   -
12   -/* global define, require, window, document */
13   -
14   -(function (factory) {
15   - 'use strict';
16   - if (typeof define === 'function' && define.amd) {
17   - // Register as an anonymous AMD module:
18   - define(['jquery'], factory);
19   - } else if (typeof exports === 'object') {
20   - // Node/CommonJS:
21   - factory(require('jquery'));
22   - } else {
23   - // Browser globals:
24   - factory(window.jQuery);
25   - }
26   -}(function ($) {
27   - 'use strict';
28   -
29   - // Helper variable to create unique names for the transport iframes:
30   - var counter = 0;
31   -
32   - // The iframe transport accepts four additional options:
33   - // options.fileInput: a jQuery collection of file input fields
34   - // options.paramName: the parameter name for the file form data,
35   - // overrides the name property of the file input field(s),
36   - // can be a string or an array of strings.
37   - // options.formData: an array of objects with name and value properties,
38   - // equivalent to the return data of .serializeArray(), e.g.:
39   - // [{name: 'a', value: 1}, {name: 'b', value: 2}]
40   - // options.initialIframeSrc: the URL of the initial iframe src,
41   - // by default set to "javascript:false;"
42   - $.ajaxTransport('iframe', function (options) {
43   - if (options.async) {
44   - // javascript:false as initial iframe src
45   - // prevents warning popups on HTTPS in IE6:
46   - /*jshint scripturl: true */
47   - var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
48   - /*jshint scripturl: false */
49   - form,
50   - iframe,
51   - addParamChar;
52   - return {
53   - send: function (_, completeCallback) {
54   - form = $('<form style="display:none;"></form>');
55   - form.attr('accept-charset', options.formAcceptCharset);
56   - addParamChar = /\?/.test(options.url) ? '&' : '?';
57   - // XDomainRequest only supports GET and POST:
58   - if (options.type === 'DELETE') {
59   - options.url = options.url + addParamChar + '_method=DELETE';
60   - options.type = 'POST';
61   - } else if (options.type === 'PUT') {
62   - options.url = options.url + addParamChar + '_method=PUT';
63   - options.type = 'POST';
64   - } else if (options.type === 'PATCH') {
65   - options.url = options.url + addParamChar + '_method=PATCH';
66   - options.type = 'POST';
67   - }
68   - // IE versions below IE8 cannot set the name property of
69   - // elements that have already been added to the DOM,
70   - // so we set the name along with the iframe HTML markup:
71   - counter += 1;
72   - iframe = $(
73   - '<iframe src="' + initialIframeSrc +
74   - '" name="iframe-transport-' + counter + '"></iframe>'
75   - ).bind('load', function () {
76   - var fileInputClones,
77   - paramNames = $.isArray(options.paramName) ?
78   - options.paramName : [options.paramName];
79   - iframe
80   - .unbind('load')
81   - .bind('load', function () {
82   - var response;
83   - // Wrap in a try/catch block to catch exceptions thrown
84   - // when trying to access cross-domain iframe contents:
85   - try {
86   - response = iframe.contents();
87   - // Google Chrome and Firefox do not throw an
88   - // exception when calling iframe.contents() on
89   - // cross-domain requests, so we unify the response:
90   - if (!response.length || !response[0].firstChild) {
91   - throw new Error();
92   - }
93   - } catch (e) {
94   - response = undefined;
95   - }
96   - // The complete callback returns the
97   - // iframe content document as response object:
98   - completeCallback(
99   - 200,
100   - 'success',
101   - {'iframe': response}
102   - );
103   - // Fix for IE endless progress bar activity bug
104   - // (happens on form submits to iframe targets):
105   - $('<iframe src="' + initialIframeSrc + '"></iframe>')
106   - .appendTo(form);
107   - window.setTimeout(function () {
108   - // Removing the form in a setTimeout call
109   - // allows Chrome's developer tools to display
110   - // the response result
111   - form.remove();
112   - }, 0);
113   - });
114   - form
115   - .prop('target', iframe.prop('name'))
116   - .prop('action', options.url)
117   - .prop('method', options.type);
118   - if (options.formData) {
119   - $.each(options.formData, function (index, field) {
120   - $('<input type="hidden"/>')
121   - .prop('name', field.name)
122   - .val(field.value)
123   - .appendTo(form);
124   - });
125   - }
126   - if (options.fileInput && options.fileInput.length &&
127   - options.type === 'POST') {
128   - fileInputClones = options.fileInput.clone();
129   - // Insert a clone for each file input field:
130   - options.fileInput.after(function (index) {
131   - return fileInputClones[index];
132   - });
133   - if (options.paramName) {
134   - options.fileInput.each(function (index) {
135   - $(this).prop(
136   - 'name',
137   - paramNames[index] || options.paramName
138   - );
139   - });
140   - }
141   - // Appending the file input fields to the hidden form
142   - // removes them from their original location:
143   - form
144   - .append(options.fileInput)
145   - .prop('enctype', 'multipart/form-data')
146   - // enctype must be set as encoding for IE:
147   - .prop('encoding', 'multipart/form-data');
148   - // Remove the HTML5 form attribute from the input(s):
149   - options.fileInput.removeAttr('form');
150   - }
151   - form.submit();
152   - // Insert the file input fields at their original location
153   - // by replacing the clones with the originals:
154   - if (fileInputClones && fileInputClones.length) {
155   - options.fileInput.each(function (index, input) {
156   - var clone = $(fileInputClones[index]);
157   - // Restore the original name and form properties:
158   - $(input)
159   - .prop('name', clone.prop('name'))
160   - .attr('form', clone.attr('form'));
161   - clone.replaceWith(input);
162   - });
163   - }
164   - });
165   - form.append(iframe).appendTo(document.body);
166   - },
167   - abort: function () {
168   - if (iframe) {
169   - // javascript:false as iframe src aborts the request
170   - // and prevents warning popups on HTTPS in IE6.
171   - // concat is used to avoid the "Script URL" JSLint error:
172   - iframe
173   - .unbind('load')
174   - .prop('src', initialIframeSrc);
175   - }
176   - if (form) {
177   - form.remove();
178   - }
179   - }
180   - };
181   - }
182   - });
183   -
184   - // The iframe transport returns the iframe content document as response.
185   - // The following adds converters from iframe to text, json, html, xml
186   - // and script.
187   - // Please note that the Content-Type for JSON responses has to be text/plain
188   - // or text/html, if the browser doesn't include application/json in the
189   - // Accept header, else IE will show a download dialog.
190   - // The Content-Type for XML responses on the other hand has to be always
191   - // application/xml or text/xml, so IE properly parses the XML response.
192   - // See also
193   - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
194   - $.ajaxSetup({
195   - converters: {
196   - 'iframe text': function (iframe) {
197   - return iframe && $(iframe[0].body).text();
198   - },
199   - 'iframe json': function (iframe) {
200   - return iframe && $.parseJSON($(iframe[0].body).text());
201   - },
202   - 'iframe html': function (iframe) {
203   - return iframe && $(iframe[0].body).html();
204   - },
205   - 'iframe xml': function (iframe) {
206   - var xmlDoc = iframe && iframe[0];
207   - return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
208   - $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
209   - $(xmlDoc.body).html());
210   - },
211   - 'iframe script': function (iframe) {
212   - return iframe && $.globalEval($(iframe[0].body).text());
213   - }
214   - }
215   - });
216   -
217   -}));
view/assets/js/jquery.scrollTo.js
... ... @@ -1,210 +0,0 @@
1   -/*!
2   - * jQuery.scrollTo
3   - * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
4   - * Licensed under MIT
5   - * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
6   - * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery
7   - * @author Ariel Flesler
8   - * @version 2.1.2
9   - */
10   -;(function(factory) {
11   - 'use strict';
12   - if (typeof define === 'function' && define.amd) {
13   - // AMD
14   - define(['jquery'], factory);
15   - } else if (typeof module !== 'undefined' && module.exports) {
16   - // CommonJS
17   - module.exports = factory(require('jquery'));
18   - } else {
19   - // Global
20   - factory(jQuery);
21   - }
22   -})(function($) {
23   - 'use strict';
24   -
25   - var $scrollTo = $.scrollTo = function(target, duration, settings) {
26   - return $(window).scrollTo(target, duration, settings);
27   - };
28   -
29   - $scrollTo.defaults = {
30   - axis:'xy',
31   - duration: 0,
32   - limit:true
33   - };
34   -
35   - function isWin(elem) {
36   - return !elem.nodeName ||
37   - $.inArray(elem.nodeName.toLowerCase(), ['iframe','#document','html','body']) !== -1;
38   - }
39   -
40   - $.fn.scrollTo = function(target, duration, settings) {
41   - if (typeof duration === 'object') {
42   - settings = duration;
43   - duration = 0;
44   - }
45   - if (typeof settings === 'function') {
46   - settings = { onAfter:settings };
47   - }
48   - if (target === 'max') {
49   - target = 9e9;
50   - }
51   -
52   - settings = $.extend({}, $scrollTo.defaults, settings);
53   - // Speed is still recognized for backwards compatibility
54   - duration = duration || settings.duration;
55   - // Make sure the settings are given right
56   - var queue = settings.queue && settings.axis.length > 1;
57   - if (queue) {
58   - // Let's keep the overall duration
59   - duration /= 2;
60   - }
61   - settings.offset = both(settings.offset);
62   - settings.over = both(settings.over);
63   -
64   - return this.each(function() {
65   - // Null target yields nothing, just like jQuery does
66   - if (target === null) return;
67   -
68   - var win = isWin(this),
69   - elem = win ? this.contentWindow || window : this,
70   - $elem = $(elem),
71   - targ = target,
72   - attr = {},
73   - toff;
74   -
75   - switch (typeof targ) {
76   - // A number will pass the regex
77   - case 'number':
78   - case 'string':
79   - if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
80   - targ = both(targ);
81   - // We are done
82   - break;
83   - }
84   - // Relative/Absolute selector
85   - targ = win ? $(targ) : $(targ, elem);
86   - /* falls through */
87   - case 'object':
88   - if (targ.length === 0) return;
89   - // DOMElement / jQuery
90   - if (targ.is || targ.style) {
91   - // Get the real position of the target
92   - toff = (targ = $(targ)).offset();
93   - }
94   - }
95   -
96   - var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset;
97   -
98   - $.each(settings.axis.split(''), function(i, axis) {
99   - var Pos = axis === 'x' ? 'Left' : 'Top',
100   - pos = Pos.toLowerCase(),
101   - key = 'scroll' + Pos,
102   - prev = $elem[key](),
103   - max = $scrollTo.max(elem, axis);
104   -
105   - if (toff) {// jQuery / DOMElement
106   - attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]);
107   -
108   - // If it's a dom element, reduce the margin
109   - if (settings.margin) {
110   - attr[key] -= parseInt(targ.css('margin'+Pos), 10) || 0;
111   - attr[key] -= parseInt(targ.css('border'+Pos+'Width'), 10) || 0;
112   - }
113   -
114   - attr[key] += offset[pos] || 0;
115   -
116   - if (settings.over[pos]) {
117   - // Scroll to a fraction of its width/height
118   - attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos];
119   - }
120   - } else {
121   - var val = targ[pos];
122   - // Handle percentage values
123   - attr[key] = val.slice && val.slice(-1) === '%' ?
124   - parseFloat(val) / 100 * max
125   - : val;
126   - }
127   -
128   - // Number or 'number'
129   - if (settings.limit && /^\d+$/.test(attr[key])) {
130   - // Check the limits
131   - attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
132   - }
133   -
134   - // Don't waste time animating, if there's no need.
135   - if (!i && settings.axis.length > 1) {
136   - if (prev === attr[key]) {
137   - // No animation needed
138   - attr = {};
139   - } else if (queue) {
140   - // Intermediate animation
141   - animate(settings.onAfterFirst);
142   - // Don't animate this axis again in the next iteration.
143   - attr = {};
144   - }
145   - }
146   - });
147   -
148   - animate(settings.onAfter);
149   -
150   - function animate(callback) {
151   - var opts = $.extend({}, settings, {
152   - // The queue setting conflicts with animate()
153   - // Force it to always be true
154   - queue: true,
155   - duration: duration,
156   - complete: callback && function() {
157   - callback.call(elem, targ, settings);
158   - }
159   - });
160   - $elem.animate(attr, opts);
161   - }
162   - });
163   - };
164   -
165   - // Max scrolling position, works on quirks mode
166   - // It only fails (not too badly) on IE, quirks mode.
167   - $scrollTo.max = function(elem, axis) {
168   - var Dim = axis === 'x' ? 'Width' : 'Height',
169   - scroll = 'scroll'+Dim;
170   -
171   - if (!isWin(elem))
172   - return elem[scroll] - $(elem)[Dim.toLowerCase()]();
173   -
174   - var size = 'client' + Dim,
175   - doc = elem.ownerDocument || elem.document,
176   - html = doc.documentElement,
177   - body = doc.body;
178   -
179   - return Math.max(html[scroll], body[scroll]) - Math.min(html[size], body[size]);
180   - };
181   -
182   - function both(val) {
183   - return $.isFunction(val) || $.isPlainObject(val) ? val : { top:val, left:val };
184   - }
185   -
186   - // Add special hooks so that window scroll properties can be animated
187   - $.Tween.propHooks.scrollLeft =
188   - $.Tween.propHooks.scrollTop = {
189   - get: function(t) {
190   - return $(t.elem)[t.prop]();
191   - },
192   - set: function(t) {
193   - var curr = this.get(t);
194   - // If interrupt is true and user scrolled, stop animating
195   - if (t.options.interrupt && t._last && t._last !== curr) {
196   - return $(t.elem).stop();
197   - }
198   - var next = Math.round(t.now);
199   - // Don't waste CPU
200   - // Browsers don't render floating point scroll
201   - if (curr !== next) {
202   - $(t.elem)[t.prop](next);
203   - t._last = this.get(t);
204   - }
205   - }
206   - };
207   -
208   - // AMD requirement
209   - return $scrollTo;
210   -});
view/assets/js/jquery.ui.widget.js
... ... @@ -1,572 +0,0 @@
1   -/*! jQuery UI - v1.11.4+CommonJS - 2015-08-28
2   -* http://jqueryui.com
3   -* Includes: widget.js
4   -* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
5   -
6   -(function( factory ) {
7   - if ( typeof define === "function" && define.amd ) {
8   -
9   - // AMD. Register as an anonymous module.
10   - define([ "jquery" ], factory );
11   -
12   - } else if ( typeof exports === "object" ) {
13   -
14   - // Node/CommonJS
15   - factory( require( "jquery" ) );
16   -
17   - } else {
18   -
19   - // Browser globals
20   - factory( jQuery );
21   - }
22   -}(function( $ ) {
23   -/*!
24   - * jQuery UI Widget 1.11.4
25   - * http://jqueryui.com
26   - *
27   - * Copyright jQuery Foundation and other contributors
28   - * Released under the MIT license.
29   - * http://jquery.org/license
30   - *
31   - * http://api.jqueryui.com/jQuery.widget/
32   - */
33   -
34   -
35   -var widget_uuid = 0,
36   - widget_slice = Array.prototype.slice;
37   -
38   -$.cleanData = (function( orig ) {
39   - return function( elems ) {
40   - var events, elem, i;
41   - for ( i = 0; (elem = elems[i]) != null; i++ ) {
42   - try {
43   -
44   - // Only trigger remove when necessary to save time
45   - events = $._data( elem, "events" );
46   - if ( events && events.remove ) {
47   - $( elem ).triggerHandler( "remove" );
48   - }
49   -
50   - // http://bugs.jquery.com/ticket/8235
51   - } catch ( e ) {}
52   - }
53   - orig( elems );
54   - };
55   -})( $.cleanData );
56   -
57   -$.widget = function( name, base, prototype ) {
58   - var fullName, existingConstructor, constructor, basePrototype,
59   - // proxiedPrototype allows the provided prototype to remain unmodified
60   - // so that it can be used as a mixin for multiple widgets (#8876)
61   - proxiedPrototype = {},
62   - namespace = name.split( "." )[ 0 ];
63   -
64   - name = name.split( "." )[ 1 ];
65   - fullName = namespace + "-" + name;
66   -
67   - if ( !prototype ) {
68   - prototype = base;
69   - base = $.Widget;
70   - }
71   -
72   - // create selector for plugin
73   - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
74   - return !!$.data( elem, fullName );
75   - };
76   -
77   - $[ namespace ] = $[ namespace ] || {};
78   - existingConstructor = $[ namespace ][ name ];
79   - constructor = $[ namespace ][ name ] = function( options, element ) {
80   - // allow instantiation without "new" keyword
81   - if ( !this._createWidget ) {
82   - return new constructor( options, element );
83   - }
84   -
85   - // allow instantiation without initializing for simple inheritance
86   - // must use "new" keyword (the code above always passes args)
87   - if ( arguments.length ) {
88   - this._createWidget( options, element );
89   - }
90   - };
91   - // extend with the existing constructor to carry over any static properties
92   - $.extend( constructor, existingConstructor, {
93   - version: prototype.version,
94   - // copy the object used to create the prototype in case we need to
95   - // redefine the widget later
96   - _proto: $.extend( {}, prototype ),
97   - // track widgets that inherit from this widget in case this widget is
98   - // redefined after a widget inherits from it
99   - _childConstructors: []
100   - });
101   -
102   - basePrototype = new base();
103   - // we need to make the options hash a property directly on the new instance
104   - // otherwise we'll modify the options hash on the prototype that we're
105   - // inheriting from
106   - basePrototype.options = $.widget.extend( {}, basePrototype.options );
107   - $.each( prototype, function( prop, value ) {
108   - if ( !$.isFunction( value ) ) {
109   - proxiedPrototype[ prop ] = value;
110   - return;
111   - }
112   - proxiedPrototype[ prop ] = (function() {
113   - var _super = function() {
114   - return base.prototype[ prop ].apply( this, arguments );
115   - },
116   - _superApply = function( args ) {
117   - return base.prototype[ prop ].apply( this, args );
118   - };
119   - return function() {
120   - var __super = this._super,
121   - __superApply = this._superApply,
122   - returnValue;
123   -
124   - this._super = _super;
125   - this._superApply = _superApply;
126   -
127   - returnValue = value.apply( this, arguments );
128   -
129   - this._super = __super;
130   - this._superApply = __superApply;
131   -
132   - return returnValue;
133   - };
134   - })();
135   - });
136   - constructor.prototype = $.widget.extend( basePrototype, {
137   - // TODO: remove support for widgetEventPrefix
138   - // always use the name + a colon as the prefix, e.g., draggable:start
139   - // don't prefix for widgets that aren't DOM-based
140   - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
141   - }, proxiedPrototype, {
142   - constructor: constructor,
143   - namespace: namespace,
144   - widgetName: name,
145   - widgetFullName: fullName
146   - });
147   -
148   - // If this widget is being redefined then we need to find all widgets that
149   - // are inheriting from it and redefine all of them so that they inherit from
150   - // the new version of this widget. We're essentially trying to replace one
151   - // level in the prototype chain.
152   - if ( existingConstructor ) {
153   - $.each( existingConstructor._childConstructors, function( i, child ) {
154   - var childPrototype = child.prototype;
155   -
156   - // redefine the child widget using the same prototype that was
157   - // originally used, but inherit from the new version of the base
158   - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
159   - });
160   - // remove the list of existing child constructors from the old constructor
161   - // so the old child constructors can be garbage collected
162   - delete existingConstructor._childConstructors;
163   - } else {
164   - base._childConstructors.push( constructor );
165   - }
166   -
167   - $.widget.bridge( name, constructor );
168   -
169   - return constructor;
170   -};
171   -
172   -$.widget.extend = function( target ) {
173   - var input = widget_slice.call( arguments, 1 ),
174   - inputIndex = 0,
175   - inputLength = input.length,
176   - key,
177   - value;
178   - for ( ; inputIndex < inputLength; inputIndex++ ) {
179   - for ( key in input[ inputIndex ] ) {
180   - value = input[ inputIndex ][ key ];
181   - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
182   - // Clone objects
183   - if ( $.isPlainObject( value ) ) {
184   - target[ key ] = $.isPlainObject( target[ key ] ) ?
185   - $.widget.extend( {}, target[ key ], value ) :
186   - // Don't extend strings, arrays, etc. with objects
187   - $.widget.extend( {}, value );
188   - // Copy everything else by reference
189   - } else {
190   - target[ key ] = value;
191   - }
192   - }
193   - }
194   - }
195   - return target;
196   -};
197   -
198   -$.widget.bridge = function( name, object ) {
199   - var fullName = object.prototype.widgetFullName || name;
200   - $.fn[ name ] = function( options ) {
201   - var isMethodCall = typeof options === "string",
202   - args = widget_slice.call( arguments, 1 ),
203   - returnValue = this;
204   -
205   - if ( isMethodCall ) {
206   - this.each(function() {
207   - var methodValue,
208   - instance = $.data( this, fullName );
209   - if ( options === "instance" ) {
210   - returnValue = instance;
211   - return false;
212   - }
213   - if ( !instance ) {
214   - return $.error( "cannot call methods on " + name + " prior to initialization; " +
215   - "attempted to call method '" + options + "'" );
216   - }
217   - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
218   - return $.error( "no such method '" + options + "' for " + name + " widget instance" );
219   - }
220   - methodValue = instance[ options ].apply( instance, args );
221   - if ( methodValue !== instance && methodValue !== undefined ) {
222   - returnValue = methodValue && methodValue.jquery ?
223   - returnValue.pushStack( methodValue.get() ) :
224   - methodValue;
225   - return false;
226   - }
227   - });
228   - } else {
229   -
230   - // Allow multiple hashes to be passed on init
231   - if ( args.length ) {
232   - options = $.widget.extend.apply( null, [ options ].concat(args) );
233   - }
234   -
235   - this.each(function() {
236   - var instance = $.data( this, fullName );
237   - if ( instance ) {
238   - instance.option( options || {} );
239   - if ( instance._init ) {
240   - instance._init();
241   - }
242   - } else {
243   - $.data( this, fullName, new object( options, this ) );
244   - }
245   - });
246   - }
247   -
248   - return returnValue;
249   - };
250   -};
251   -
252   -$.Widget = function( /* options, element */ ) {};
253   -$.Widget._childConstructors = [];
254   -
255   -$.Widget.prototype = {
256   - widgetName: "widget",
257   - widgetEventPrefix: "",
258   - defaultElement: "<div>",
259   - options: {
260   - disabled: false,
261   -
262   - // callbacks
263   - create: null
264   - },
265   - _createWidget: function( options, element ) {
266   - element = $( element || this.defaultElement || this )[ 0 ];
267   - this.element = $( element );
268   - this.uuid = widget_uuid++;
269   - this.eventNamespace = "." + this.widgetName + this.uuid;
270   -
271   - this.bindings = $();
272   - this.hoverable = $();
273   - this.focusable = $();
274   -
275   - if ( element !== this ) {
276   - $.data( element, this.widgetFullName, this );
277   - this._on( true, this.element, {
278   - remove: function( event ) {
279   - if ( event.target === element ) {
280   - this.destroy();
281   - }
282   - }
283   - });
284   - this.document = $( element.style ?
285   - // element within the document
286   - element.ownerDocument :
287   - // element is window or document
288   - element.document || element );
289   - this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
290   - }
291   -
292   - this.options = $.widget.extend( {},
293   - this.options,
294   - this._getCreateOptions(),
295   - options );
296   -
297   - this._create();
298   - this._trigger( "create", null, this._getCreateEventData() );
299   - this._init();
300   - },
301   - _getCreateOptions: $.noop,
302   - _getCreateEventData: $.noop,
303   - _create: $.noop,
304   - _init: $.noop,
305   -
306   - destroy: function() {
307   - this._destroy();
308   - // we can probably remove the unbind calls in 2.0
309   - // all event bindings should go through this._on()
310   - this.element
311   - .unbind( this.eventNamespace )
312   - .removeData( this.widgetFullName )
313   - // support: jquery <1.6.3
314   - // http://bugs.jquery.com/ticket/9413
315   - .removeData( $.camelCase( this.widgetFullName ) );
316   - this.widget()
317   - .unbind( this.eventNamespace )
318   - .removeAttr( "aria-disabled" )
319   - .removeClass(
320   - this.widgetFullName + "-disabled " +
321   - "ui-state-disabled" );
322   -
323   - // clean up events and states
324   - this.bindings.unbind( this.eventNamespace );
325   - this.hoverable.removeClass( "ui-state-hover" );
326   - this.focusable.removeClass( "ui-state-focus" );
327   - },
328   - _destroy: $.noop,
329   -
330   - widget: function() {
331   - return this.element;
332   - },
333   -
334   - option: function( key, value ) {
335   - var options = key,
336   - parts,
337   - curOption,
338   - i;
339   -
340   - if ( arguments.length === 0 ) {
341   - // don't return a reference to the internal hash
342   - return $.widget.extend( {}, this.options );
343   - }
344   -
345   - if ( typeof key === "string" ) {
346   - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
347   - options = {};
348   - parts = key.split( "." );
349   - key = parts.shift();
350   - if ( parts.length ) {
351   - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
352   - for ( i = 0; i < parts.length - 1; i++ ) {
353   - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
354   - curOption = curOption[ parts[ i ] ];
355   - }
356   - key = parts.pop();
357   - if ( arguments.length === 1 ) {
358   - return curOption[ key ] === undefined ? null : curOption[ key ];
359   - }
360   - curOption[ key ] = value;
361   - } else {
362   - if ( arguments.length === 1 ) {
363   - return this.options[ key ] === undefined ? null : this.options[ key ];
364   - }
365   - options[ key ] = value;
366   - }
367   - }
368   -
369   - this._setOptions( options );
370   -
371   - return this;
372   - },
373   - _setOptions: function( options ) {
374   - var key;
375   -
376   - for ( key in options ) {
377   - this._setOption( key, options[ key ] );
378   - }
379   -
380   - return this;
381   - },
382   - _setOption: function( key, value ) {
383   - this.options[ key ] = value;
384   -
385   - if ( key === "disabled" ) {
386   - this.widget()
387   - .toggleClass( this.widgetFullName + "-disabled", !!value );
388   -
389   - // If the widget is becoming disabled, then nothing is interactive
390   - if ( value ) {
391   - this.hoverable.removeClass( "ui-state-hover" );
392   - this.focusable.removeClass( "ui-state-focus" );
393   - }
394   - }
395   -
396   - return this;
397   - },
398   -
399   - enable: function() {
400   - return this._setOptions({ disabled: false });
401   - },
402   - disable: function() {
403   - return this._setOptions({ disabled: true });
404   - },
405   -
406   - _on: function( suppressDisabledCheck, element, handlers ) {
407   - var delegateElement,
408   - instance = this;
409   -
410   - // no suppressDisabledCheck flag, shuffle arguments
411   - if ( typeof suppressDisabledCheck !== "boolean" ) {
412   - handlers = element;
413   - element = suppressDisabledCheck;
414   - suppressDisabledCheck = false;
415   - }
416   -
417   - // no element argument, shuffle and use this.element
418   - if ( !handlers ) {
419   - handlers = element;
420   - element = this.element;
421   - delegateElement = this.widget();
422   - } else {
423   - element = delegateElement = $( element );
424   - this.bindings = this.bindings.add( element );
425   - }
426   -
427   - $.each( handlers, function( event, handler ) {
428   - function handlerProxy() {
429   - // allow widgets to customize the disabled handling
430   - // - disabled as an array instead of boolean
431   - // - disabled class as method for disabling individual parts
432   - if ( !suppressDisabledCheck &&
433   - ( instance.options.disabled === true ||
434   - $( this ).hasClass( "ui-state-disabled" ) ) ) {
435   - return;
436   - }
437   - return ( typeof handler === "string" ? instance[ handler ] : handler )
438   - .apply( instance, arguments );
439   - }
440   -
441   - // copy the guid so direct unbinding works
442   - if ( typeof handler !== "string" ) {
443   - handlerProxy.guid = handler.guid =
444   - handler.guid || handlerProxy.guid || $.guid++;
445   - }
446   -
447   - var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
448   - eventName = match[1] + instance.eventNamespace,
449   - selector = match[2];
450   - if ( selector ) {
451   - delegateElement.delegate( selector, eventName, handlerProxy );
452   - } else {
453   - element.bind( eventName, handlerProxy );
454   - }
455   - });
456   - },
457   -
458   - _off: function( element, eventName ) {
459   - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
460   - this.eventNamespace;
461   - element.unbind( eventName ).undelegate( eventName );
462   -
463   - // Clear the stack to avoid memory leaks (#10056)
464   - this.bindings = $( this.bindings.not( element ).get() );
465   - this.focusable = $( this.focusable.not( element ).get() );
466   - this.hoverable = $( this.hoverable.not( element ).get() );
467   - },
468   -
469   - _delay: function( handler, delay ) {
470   - function handlerProxy() {
471   - return ( typeof handler === "string" ? instance[ handler ] : handler )
472   - .apply( instance, arguments );
473   - }
474   - var instance = this;
475   - return setTimeout( handlerProxy, delay || 0 );
476   - },
477   -
478   - _hoverable: function( element ) {
479   - this.hoverable = this.hoverable.add( element );
480   - this._on( element, {
481   - mouseenter: function( event ) {
482   - $( event.currentTarget ).addClass( "ui-state-hover" );
483   - },
484   - mouseleave: function( event ) {
485   - $( event.currentTarget ).removeClass( "ui-state-hover" );
486   - }
487   - });
488   - },
489   -
490   - _focusable: function( element ) {
491   - this.focusable = this.focusable.add( element );
492   - this._on( element, {
493   - focusin: function( event ) {
494   - $( event.currentTarget ).addClass( "ui-state-focus" );
495   - },
496   - focusout: function( event ) {
497   - $( event.currentTarget ).removeClass( "ui-state-focus" );
498   - }
499   - });
500   - },
501   -
502   - _trigger: function( type, event, data ) {
503   - var prop, orig,
504   - callback = this.options[ type ];
505   -
506   - data = data || {};
507   - event = $.Event( event );
508   - event.type = ( type === this.widgetEventPrefix ?
509   - type :
510   - this.widgetEventPrefix + type ).toLowerCase();
511   - // the original event may come from any element
512   - // so we need to reset the target on the new event
513   - event.target = this.element[ 0 ];
514   -
515   - // copy original event properties over to the new event
516   - orig = event.originalEvent;
517   - if ( orig ) {
518   - for ( prop in orig ) {
519   - if ( !( prop in event ) ) {
520   - event[ prop ] = orig[ prop ];
521   - }
522   - }
523   - }
524   -
525   - this.element.trigger( event, data );
526   - return !( $.isFunction( callback ) &&
527   - callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
528   - event.isDefaultPrevented() );
529   - }
530   -};
531   -
532   -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
533   - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
534   - if ( typeof options === "string" ) {
535   - options = { effect: options };
536   - }
537   - var hasOptions,
538   - effectName = !options ?
539   - method :
540   - options === true || typeof options === "number" ?
541   - defaultEffect :
542   - options.effect || defaultEffect;
543   - options = options || {};
544   - if ( typeof options === "number" ) {
545   - options = { duration: options };
546   - }
547   - hasOptions = !$.isEmptyObject( options );
548   - options.complete = callback;
549   - if ( options.delay ) {
550   - element.delay( options.delay );
551   - }
552   - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
553   - element[ method ]( options );
554   - } else if ( effectName !== method && element[ effectName ] ) {
555   - element[ effectName ]( options.duration, options.easing, callback );
556   - } else {
557   - element.queue(function( next ) {
558   - $( this )[ method ]();
559   - if ( callback ) {
560   - callback.call( element[ 0 ] );
561   - }
562   - next();
563   - });
564   - }
565   - };
566   -});
567   -
568   -var widget = $.widget;
569   -
570   -
571   -
572   -}));
view/assets/js/js.cookie.js
... ... @@ -1,145 +0,0 @@
1   -/*!
2   - * JavaScript Cookie v2.0.4
3   - * https://github.com/js-cookie/js-cookie
4   - *
5   - * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
6   - * Released under the MIT license
7   - */
8   -(function(factory) {
9   - if (typeof define === 'function' && define.amd) {
10   - define(factory);
11   - } else if (typeof exports === 'object') {
12   - module.exports = factory();
13   - } else {
14   - var _OldCookies = window.Cookies;
15   - var api = window.Cookies = factory();
16   - api.noConflict = function() {
17   - window.Cookies = _OldCookies;
18   - return api;
19   - };
20   - }
21   -}(function() {
22   - function extend() {
23   - var i = 0;
24   - var result = {};
25   - for (; i < arguments.length; i++) {
26   - var attributes = arguments[ i ];
27   - for (var key in attributes) {
28   - result[key] = attributes[key];
29   - }
30   - }
31   - return result;
32   - }
33   -
34   - function init(converter) {
35   - function api(key, value, attributes) {
36   - var result;
37   -
38   - // Write
39   -
40   - if (arguments.length > 1) {
41   - attributes = extend({
42   - path: '/'
43   - }, api.defaults, attributes);
44   -
45   - if (typeof attributes.expires === 'number') {
46   - var expires = new Date();
47   - expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
48   - attributes.expires = expires;
49   - }
50   -
51   - try {
52   - result = JSON.stringify(value);
53   - if (/^[\{\[]/.test(result)) {
54   - value = result;
55   - }
56   - } catch (e) {}
57   -
58   - if (!converter.write) {
59   - value = encodeURIComponent(String(value))
60   - .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
61   - } else {
62   - value = converter.write(value, key);
63   - }
64   -
65   - key = encodeURIComponent(String(key));
66   - key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
67   - key = key.replace(/[\(\)]/g, escape);
68   -
69   - return (document.cookie = [
70   - key, '=', value,
71   - attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
72   - attributes.path && '; path=' + attributes.path,
73   - attributes.domain && '; domain=' + attributes.domain,
74   - attributes.secure ? '; secure' : ''
75   - ].join(''));
76   - }
77   -
78   - // Read
79   -
80   - if (!key) {
81   - result = {};
82   - }
83   -
84   - // To prevent the for loop in the first place assign an empty array
85   - // in case there are no cookies at all. Also prevents odd result when
86   - // calling "get()"
87   - var cookies = document.cookie ? document.cookie.split('; ') : [];
88   - var rdecode = /(%[0-9A-Z]{2})+/g;
89   - var i = 0;
90   -
91   - for (; i < cookies.length; i++) {
92   - var parts = cookies[i].split('=');
93   - var name = parts[0].replace(rdecode, decodeURIComponent);
94   - var cookie = parts.slice(1).join('=');
95   -
96   - if (cookie.charAt(0) === '"') {
97   - cookie = cookie.slice(1, -1);
98   - }
99   -
100   - try {
101   - cookie = converter.read ?
102   - converter.read(cookie, name) : converter(cookie, name) ||
103   - cookie.replace(rdecode, decodeURIComponent);
104   -
105   - if (this.json) {
106   - try {
107   - cookie = JSON.parse(cookie);
108   - } catch (e) {}
109   - }
110   -
111   - if (key === name) {
112   - result = cookie;
113   - break;
114   - }
115   -
116   - if (!key) {
117   - result[name] = cookie;
118   - }
119   - } catch (e) {}
120   - }
121   -
122   - return result;
123   - }
124   -
125   - api.get = api.set = api;
126   - api.getJSON = function() {
127   - return api.apply({
128   - json: true
129   - }, [].slice.call(arguments));
130   - };
131   - api.defaults = {};
132   -
133   - api.remove = function(key, attributes) {
134   - api(key, '', extend(attributes, {
135   - expires: -1
136   - }));
137   - };
138   -
139   - api.withConverter = init;
140   -
141   - return api;
142   - }
143   -
144   - return init(function() {});
145   -}));
view/assets/js/movement.js
... ... @@ -1,24 +0,0 @@
1   -(function(movement, $, undefined) {
2   -
3   - movement.getPreviousSelectedMovement = function(mainConfig) {
4   - return $('.selection-panel-body[mainConfig=' + mainConfig +
5   - '][subConfig=movimento][step=1] .selection-panel-option[select=true]').attr('value');
6   - };
7   -
8   - movement.setup = function(serverhost, hand) {
9   - var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=movimento][step=1]';
10   - $(baseId + ' .selection-panel-option').off('click').on(
11   - 'click', function() {
12   - wikilibras.selectAnOption(baseId, this);
13   - dynworkflow.selectMovement($(this).attr('value'));
14   - });
15   - $(baseId + ' .video-panel-option').off('mouseenter').on('mouseenter',
16   - function(event) {
17   - $(this).addClass('video-panel-option-hover');
18   - });
19   - $(baseId + ' .video-panel-option').off('mouseleave').on('mouseleave',
20   - function(event) {
21   - $(this).removeClass('video-panel-option-hover');
22   - });
23   - };
24   -}(window.movement = window.movement || {}, jQuery));
view/assets/js/orientation.js
... ... @@ -1,13 +0,0 @@
1   -(function(orientation, $, undefined) {
2   -
3   - orientation.setup = function(hand, subConfig, step) {
4   - var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
5   - subConfig + '][step=' + step + ']';
6   - $(baseId + ' .selection-panel-option').off('click').on(
7   - 'click', function() {
8   - wikilibras.selectAnOption(baseId, this);
9   - dynworkflow.userSelectedAnOption();
10   - });
11   - };
12   -
13   -}(window.orientation = window.orientation || {}, jQuery));
view/assets/js/render-sign.js 0 → 100644
... ... @@ -0,0 +1,84 @@
  1 +(function(renderSign, $, undefined) {
  2 +
  3 + var api_url = '';
  4 +
  5 + function _submitParameterJSON(parsedParameterJSON, callback) {
  6 + console.log(parsedParameterJSON);
  7 +
  8 + $.ajax({
  9 + type : 'POST',
  10 + url : api_url + '/sign',
  11 + data : JSON.stringify(parsedParameterJSON),
  12 + contentType : 'application/json',
  13 + success : function(response) {
  14 + console.log(response);
  15 + callback(parsedParameterJSON);
  16 + },
  17 + error : function(xhr, textStatus, error) {
  18 + alert(xhr.responseText);
  19 + }
  20 + });
  21 + }
  22 +
  23 + function _showRenderedAvatar(parameterJSON) {
  24 + var userId = parameterJSON['userId'];
  25 + var signName = parameterJSON['sinal'];
  26 + $("#render-avatar video").attr("src",
  27 + _getRenderedAvatarUrl(userId, signName));
  28 + $("#render-avatar").fadeIn(300);
  29 + }
  30 +
  31 + function _showRenderScreen(toShow) {
  32 + if (toShow) {
  33 + $("#render-screen").fadeIn(300);
  34 + videoHelper.play("#render-ref video");
  35 + videoHelper.play("#render-avatar video");
  36 + } else {
  37 + $("#render-screen").hide();
  38 + videoHelper.pause("#render-ref video");
  39 + videoHelper.pause("#render-avatar video");
  40 + }
  41 + }
  42 +
  43 + function _getRenderedAvatarUrl(userId, signName) {
  44 + return api_url + '/public/' + userId + '/' + signName + ".webm";
  45 + }
  46 +
  47 + renderSign.showRenderedAvatar = function(parameterJSON) {
  48 + _showRenderedAvatar(parameterJSON);
  49 + _showRenderScreen(true);
  50 + }
  51 +
  52 + renderSign.showRenderScreen = function(toShow) {
  53 + _showRenderScreen(toShow);
  54 + }
  55 +
  56 + renderSign.getRenderedAvatarUrl = function(userId, signName) {
  57 + return _getRenderedAvatarUrl(userId, signName);
  58 + }
  59 +
  60 + renderSign.submit = function(parsedParameterJSON) {
  61 + configurationScreen.show(false);
  62 + _showRenderScreen(true);
  63 + $("#render-avatar").hide();
  64 + $("#render-loading").fadeIn(300);
  65 + $("#render-button-container .btn").hide();
  66 + $("#finish-button").addClass("disabled");
  67 + $("#finish-button").show();
  68 +
  69 + _submitParameterJSON(parsedParameterJSON, function(parsedParameterJSON) {
  70 + $("#render-loading").fadeOut(300);
  71 + $("#finish-button").removeClass("disabled");
  72 + _showRenderedAvatar(parsedParameterJSON);
  73 + });
  74 + };
  75 +
  76 + renderSign.setup = function(apiUrl) {
  77 + api_url = apiUrl;
  78 + $("#render-edit").off("click").on("click", function() {
  79 + _showRenderScreen(false);
  80 + configurationScreen.show(true);
  81 + });
  82 + }
  83 +
  84 +}(window.renderSign = window.renderSign || {}, jQuery));
... ...
view/assets/js/selection-panel/articulation.js 0 → 100644
... ... @@ -0,0 +1,143 @@
  1 +(function(articulation, $, undefined) {
  2 +
  3 + var server_host = '';
  4 + var MAX_COLUMNS = 14;
  5 +
  6 + function _updateASelector(container, ballSelector, step) {
  7 + var pointSelector = parseInt(step) == 2 ? 'A' : 'B';
  8 + $(container + ' .ball-selector.active').each(function() {
  9 + $(this).removeClass('active');
  10 + $(this).find('.point-selector').remove();
  11 + });
  12 + ballSelector.addClass('active');
  13 + ballSelector.append('<div class="point-selector"><img src="'
  14 + + server_host + '/img/pa/' + pointSelector
  15 + + '-Seletor.png" class="point-selector" alt=""></div>');
  16 + $(container + ' .selection-panel-option[select=true]').attr('select',
  17 + false);
  18 + $(ballSelector).attr('select', true);
  19 + }
  20 +
  21 + function _getSelectedY(hand, subConfig, step) {
  22 + step = parseInt(step) - 1;
  23 + var previousStepId = '.selection-panel-body[mainConfig=' + hand
  24 + + '][subConfig=' + subConfig + '][step=' + step
  25 + + '] .module-x-y';
  26 + return $(previousStepId).attr('data-y');
  27 + }
  28 +
  29 + function _setupModuleZ(hand, subConfig, step, selectedY) {
  30 + if (typeof selectedY == 'undefined' || selectedY == '')
  31 + return;
  32 +
  33 + var base_id = '.selection-panel-body[mainConfig=' + hand
  34 + + '][subConfig=' + subConfig + '][step=' + step + ']';
  35 + var articulation_z = base_id + ' .module-z';
  36 + $(articulation_z + ' .ball-selector').hide();
  37 + $(articulation_z + ' .row-number-' + selectedY + ' .ball-selector')
  38 + .show();
  39 +
  40 + var z = $(articulation_z).attr('data-z');
  41 + if (typeof z != 'undefined') {
  42 + var ball_selector = $(articulation_z + ' .row-number-' + selectedY
  43 + + ' .ball-' + z);
  44 + _updateASelector(articulation_z, ball_selector, step);
  45 + }
  46 + }
  47 +
  48 + function _setupBallSelectorXY(hand, subConfig, step) {
  49 + var base_id = '.selection-panel-body[mainConfig=' + hand
  50 + + '][subConfig=' + subConfig + '][step=' + step + ']';
  51 + var articulation_x_y = base_id + ' .module-x-y';
  52 + $(articulation_x_y + ' .ball-selector')
  53 + .off('click')
  54 + .on(
  55 + 'click',
  56 + function(a) {
  57 + var b = $(a.target);
  58 + if (!b.hasClass('ball-selector')) {
  59 + dynworkflow.userSelectedAnOption();
  60 + return;
  61 + }
  62 + var c = b.parent('.grid-row'), d = $(articulation_x_y), f = b
  63 + .attr('data-x'), g = c.attr('data-y');
  64 + d.attr('data-x', f), d.attr('data-y', g);
  65 +
  66 + var nextStep = parseInt(step) + 1;
  67 + _updateASelector(articulation_x_y, b, nextStep);
  68 + _setupModuleZ(hand, subConfig, nextStep, g);
  69 +
  70 + wikilibras.updateTempParameterJSON(hand, subConfig,
  71 + step, f + ';' + g);
  72 + dynworkflow.userSelectedAnOption();
  73 + });
  74 + }
  75 +
  76 + function _setupBallSelectorZ(hand, subConfig, step) {
  77 + var base_id = '.selection-panel-body[mainConfig=' + hand
  78 + + '][subConfig=' + subConfig + '][step=' + step + ']';
  79 + var articulation_z = base_id + ' .module-z';
  80 + $(articulation_z + ' .ball-selector').off('click').on(
  81 + 'click',
  82 + function(a) {
  83 + var b = $(a.target);
  84 + if (!b.hasClass('ball-selector')) {
  85 + dynworkflow.userSelectedAnOption();
  86 + return;
  87 + }
  88 + var c = b.parent('.grid-row'), e = $(articulation_z), h = b
  89 + .attr('data-z');
  90 + b.attr('data-z') && e.attr('data-z', h), _updateASelector(
  91 + articulation_z, b, step);
  92 +
  93 + wikilibras
  94 + .updateTempParameterJSON(hand, subConfig, step, h);
  95 + dynworkflow.userSelectedAnOption();
  96 + });
  97 + }
  98 +
  99 + function _calculateArticulationPointIndex(hand, xValue, yValue, zValue) {
  100 + var x = xValue;
  101 + var y = yValue;
  102 + var z = zValue;
  103 + if (hand == 'left-hand') {
  104 + x = MAX_COLUMNS - x + 1;
  105 + }
  106 +
  107 + var value = (z - 1) * MAX_COLUMNS + x + 3 * MAX_COLUMNS * (y - 1);
  108 + //console.log(value);
  109 + return value;
  110 + }
  111 +
  112 + articulation.processValue = function(hand, selectionArray) {
  113 + var xyValueSplit = selectionArray[0].split(';');
  114 + var xValue = parseInt(xyValueSplit[0]);
  115 + var yValue = parseInt(xyValueSplit[1]);
  116 + var zValue = parseInt(selectionArray[1]);
  117 + return _calculateArticulationPointIndex(hand, xValue, yValue, zValue);
  118 + };
  119 +
  120 + articulation.setupModuleXY = function(serverhost, hand, subConfig, step) {
  121 + server_host = serverhost;
  122 + _setupBallSelectorXY(hand, subConfig, step);
  123 + };
  124 +
  125 + articulation.setupModuleZ = function(serverhost, hand, subConfig, step) {
  126 + server_host = serverhost;
  127 + _setupBallSelectorZ(hand, subConfig, step);
  128 +
  129 + var selectedY = _getSelectedY(hand, subConfig, step);
  130 + _setupModuleZ(hand, subConfig, step, selectedY);
  131 + };
  132 +
  133 + articulation.clean = function() {
  134 + $('.ball-selector.active').each(function() {
  135 + $(this).removeClass('active');
  136 + $(this).find('.point-selector').remove();
  137 + });
  138 + $('.module-x-y').attr('data-x', '');
  139 + $('.module-x-y').attr('data-y', '');
  140 + $('.module-z').attr('data-z', '');
  141 + }
  142 +
  143 +}(window.articulation = window.articulation || {}, jQuery));
... ...
view/assets/js/selection-panel/configuration.js 0 → 100644
... ... @@ -0,0 +1,43 @@
  1 +(function(configuration, $, undefined) {
  2 +
  3 + configuration.setupFingersGroup = function(hand, subConfig, step) {
  4 + var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  5 + subConfig + '][step=' + step + ']';
  6 + $(baseId + ' .selection-panel-option'
  7 + ).off('click').on('click', function() {
  8 + selectionPanel.selectAnOption(baseId, this);
  9 + _setupFingersToShow(hand, subConfig, step);
  10 +
  11 + dynworkflow.userSelectedAnOption();
  12 + });
  13 + };
  14 +
  15 + function _setupFingersToShow(hand, subConfig, step) {
  16 + var stepOneBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  17 + subConfig + '][step=' + step + ']';
  18 + var nextStep = parseInt(step) + 1;
  19 + var stepTwoBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  20 + subConfig + '][step=' + nextStep + ']';
  21 +
  22 + var finger_group = $(stepOneBaseId + ' .selection-panel-option[select=true]').attr('value');
  23 + finger_group = typeof finger_group == 'undefined' ? '0' : finger_group;
  24 +
  25 + // clean next step
  26 + dynworkflow.cleanStep(hand, subConfig, nextStep);
  27 + $(stepTwoBaseId + ' .finger-group').hide();
  28 + $(stepTwoBaseId + ' .finger-group[group=' + finger_group + ']').show();
  29 + }
  30 +
  31 + configuration.setupFingersPosition = function(hand, subConfig, step) {
  32 + var stepTwoBaseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  33 + subConfig + '][step=' + step + ']';
  34 + $(stepTwoBaseId + ' .selection-panel-option').off('click').on(
  35 + 'click', function() {
  36 + selectionPanel.selectAnOption(stepTwoBaseId, this);
  37 + dynworkflow.userSelectedAnOption();
  38 + });
  39 + var previousStep = parseInt(step) - 1;
  40 + _setupFingersToShow(hand, subConfig, previousStep);
  41 + };
  42 +
  43 +}(window.configuration = window.configuration || {}, jQuery));
... ...
view/assets/js/selection-panel/default-configuration-handler.js 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +(function(defaultConfigurationHandler, $, undefined) {
  2 +
  3 + defaultConfigurationHandler.setup = function(hand, subConfig, step) {
  4 + var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  5 + subConfig + '][step=' + step + ']';
  6 + $(baseId + ' .selection-panel-option').off('click').on(
  7 + 'click', function() {
  8 + selectionPanel.selectAnOption(baseId, this);
  9 + dynworkflow.userSelectedAnOption();
  10 + });
  11 + };
  12 +
  13 + function _startVideoLoop(hand, subConfig, step, timeBetweenLoops) {
  14 + setTimeout(function(){
  15 + $('.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  16 + subConfig + '][step=' + step + '] video').each(function(){
  17 + videoHelper.play(this);
  18 + });
  19 + _startVideoLoop(hand, subConfig, step, timeBetweenLoops);
  20 + }, timeBetweenLoops);
  21 + }
  22 +
  23 + defaultConfigurationHandler.startVideoLoop = function(hand, subConfig, step, timeBetweenLoops) {
  24 + _startVideoLoop(hand, subConfig, step, timeBetweenLoops);
  25 + }
  26 +
  27 +}(window.defaultConfigurationHandler = window.defaultConfigurationHandler || {}, jQuery));
... ...
view/assets/js/selection-panel/dynamic-loading-engine.js 0 → 100644
... ... @@ -0,0 +1,96 @@
  1 +(function(dynengine, $, undefined) {
  2 + var setup = undefined;
  3 +
  4 + _preprocessHtml = function(data, url) {
  5 + var matchSubConfig = data.match(/sub(?:C|c)onfig="(.*?)"/);
  6 + var currentMainConfig = dynworkflow.getMainConfig(); // right-hand or left-hand
  7 + var goodData = data;
  8 +
  9 + var isRightHand = function(hand) {
  10 + return hand === 'right-hand';
  11 + };
  12 +
  13 + var replaceConfigurationTag = function(data, mainConfig) {
  14 + if (isRightHand(mainConfig)) {
  15 + return data.replace(/{{ configuracao }}/g, 'cmd');
  16 + } else {
  17 + return data.replace(/{{ configuracao }}/g, 'cme');
  18 + }
  19 + }
  20 +
  21 + var replaceOrientationTag = function(data, mainConfig) {
  22 + if (isRightHand(mainConfig)) {
  23 + return data.replace(/{{ orientacao }}/g, 'ord');
  24 + } else {
  25 + return data.replace(/{{ orientacao }}/g, 'ore');
  26 + }
  27 + }
  28 +
  29 + var replaceHandFolderTag = function(data, mainConfig) {
  30 + if (isRightHand(mainConfig)) {
  31 + return data.replace(/{{ hand-folder }}/g, 'md');
  32 + } else {
  33 + return data.replace(/{{ hand-folder }}/g, 'me');
  34 + }
  35 + }
  36 +
  37 + var replaceMovementNameTag = function(data, mainConfig) {
  38 + var selectedMovement = movement.getPreviousSelectedMovement(mainConfig);
  39 + if (typeof selectedMovement != "undefined") {
  40 + return data.replace(/{{ movement-name }}/g, selectedMovement);
  41 + }
  42 + return data
  43 + }
  44 +
  45 + if (matchSubConfig) { // case defined
  46 + // There is no specific(right or left hand dependent) assets for: articulacao, duracao, expressao, movimento, transicao
  47 + // Specific configurations: configuracao, orientacao
  48 + // possible values on the side as comment
  49 + var subConfig = matchSubConfig[1]; // articulacao | configuracao | duracao | expressao | movimento | orientacao | transicao
  50 +
  51 + // possible subconfigs that need changing
  52 + switch (subConfig) {
  53 + case 'configuracao':
  54 + goodData = replaceConfigurationTag(data, currentMainConfig);
  55 + break;
  56 + case 'configuracao-retilineo':
  57 + goodData = replaceConfigurationTag(data, currentMainConfig);
  58 + break;
  59 + case 'orientacao':
  60 + goodData = replaceOrientationTag(data, currentMainConfig);
  61 + break;
  62 + case 'orientacao-retilineo':
  63 + goodData = replaceOrientationTag(data, currentMainConfig);
  64 + break;
  65 + }
  66 + }
  67 + goodData = replaceHandFolderTag(goodData, currentMainConfig);
  68 + goodData = replaceMovementNameTag(goodData, currentMainConfig);
  69 + goodData = goodData.replace(/{{ hand }}/g, currentMainConfig);
  70 + return goodData.replace(/{{ server }}/g, url);
  71 + };
  72 +
  73 + dynengine.render = function(serverUrl, templatePath, target, prepend, callback) {
  74 + var url = serverUrl + templatePath;
  75 + $.get(url, function(data) {
  76 + var processedHtml = _preprocessHtml(data, serverUrl);
  77 + if (prepend) {
  78 + $(target).prepend(processedHtml);
  79 + } else {
  80 + $(target).append(processedHtml);
  81 + }
  82 + })
  83 + .done(function() {
  84 + callback && callback(); // call if defined
  85 + });
  86 + };
  87 +
  88 + dynengine.clean = function(target) {
  89 + $(target).html('');
  90 + };
  91 +
  92 + dynengine.load = function() {
  93 + var url = $('#server-url').data('url');
  94 + };
  95 +
  96 +}(window.dynengine = window.dynengine || {}, jQuery));
... ...
view/assets/js/selection-panel/dynamic-selection-workflow.js 0 → 100644
... ... @@ -0,0 +1,369 @@
  1 +(function(dynworkflow, $, undefined) {
  2 +
  3 + // Workflow configuration
  4 + var jsonWF = {};
  5 + var baseUrl = '';
  6 +
  7 + // Main configurations: right-hand, left-hand and facial
  8 + var mainConfig = '';
  9 + // The converted Main Config (right/left-hand) to hand for using the same configuration
  10 + var preprocessedMainConfig = '';
  11 + // Subconfigurations: movimento, articulacao, configuracao, orientacao, etc
  12 + var currentSubconfig = '';
  13 + var currentSubConfigName = '';
  14 + var currentSubconfigParent = '';
  15 + var currentStep = 0;
  16 +
  17 + function _preprocessMainConfig(config) {
  18 + config = config.replace('right-hand', 'hand');
  19 + config = config.replace('left-hand', 'hand');
  20 + return config;
  21 + }
  22 +
  23 + function _getFirstKey(json) {
  24 + var first_key = undefined;
  25 + for (first_key in json)
  26 + break;
  27 + return first_key;
  28 + }
  29 +
  30 + function _getAttributes(json) {
  31 + var result = [];
  32 + for (attr in json) {
  33 + result.push(attr);
  34 + }
  35 + return result;
  36 + }
  37 +
  38 + function _updateAndGetFirstMovementSubConfig() {
  39 + var selectedMovement = movement.getPreviousSelectedMovement(mainConfig);
  40 + if (typeof selectedMovement == 'undefined')
  41 + return -1;
  42 +
  43 + currentSubconfigParent = jsonWF[preprocessedMainConfig]['movimento'][selectedMovement];
  44 + currentSubConfigName = _getFirstKey(currentSubconfigParent);
  45 + return currentSubConfigName;
  46 + }
  47 +
  48 + function _updateAndGetMovementConfig() {
  49 + currentSubconfigParent = jsonWF[preprocessedMainConfig];
  50 + currentSubConfigName = _getFirstKey(currentSubconfigParent);
  51 + return currentSubConfigName;
  52 + }
  53 +
  54 + function _getNextSubConfig(toForward) {
  55 + var attrs = _getAttributes(currentSubconfigParent);
  56 + for (var i = 0; i < attrs.length; i++) {
  57 + if (toForward && attrs[i] == currentSubConfigName
  58 + && i < attrs.length - 1) {
  59 + return attrs[i + 1];
  60 + } else if (!toForward && attrs[i] == currentSubConfigName && i >= 1) {
  61 + return attrs[i - 1];
  62 + }
  63 + }
  64 + if (toForward && currentSubConfigName == 'movimento') {
  65 + return _updateAndGetFirstMovementSubConfig();
  66 + } else if (!toForward && preprocessedMainConfig == 'hand') {
  67 + return _updateAndGetMovementConfig();
  68 + } else if (!toForward) {
  69 + return currentSubConfigName;
  70 + } else {
  71 + return -1;
  72 + }
  73 + }
  74 +
  75 + function _showCurrentSubconfig() {
  76 + _showSubconfiguration(mainConfig, currentSubConfigName, currentStep);
  77 + }
  78 +
  79 + // It checks if a selection panel is already loaded
  80 + function _isSubconfigurationPanelLoaded(mainConfig, subConfig, stepNumber) {
  81 + var stepNumber = stepNumber + 1;
  82 + return $('.selection-panel-body[mainConfig=' + mainConfig
  83 + + '][subConfig=' + subConfig + '][step=' + stepNumber + ']').length > 0;
  84 + }
  85 +
  86 + function _showLoadedSubconfigurationPanel(mainConfig, subConfig, stepNumber) {
  87 + var stepNumber = stepNumber + 1;
  88 + return $(
  89 + '.selection-panel-body[mainConfig=' + mainConfig
  90 + + '][subConfig=' + subConfig + '][step=' + stepNumber
  91 + + ']').show();
  92 + }
  93 +
  94 + // It renders or shows the requested selection panel
  95 + function _showSubconfiguration(mainConfig, subConfig, stepNumber) {
  96 + $('.selection-panel-body').hide();
  97 + if (_isSubconfigurationPanelLoaded(mainConfig, subConfig, stepNumber)) {
  98 + _showLoadedSubconfigurationPanel(mainConfig, subConfig, stepNumber);
  99 + } else {
  100 + var step = currentSubconfig[stepNumber];
  101 + step = typeof step == 'undefined' ? 'passo-1' : step;
  102 + dynengine.render(baseUrl, '/' + preprocessedMainConfig + '/'
  103 + + subConfig + '/' + step + '.html', '#selection-panel',
  104 + true);
  105 + }
  106 + _selectTimelineIcon(mainConfig, subConfig, true);
  107 + }
  108 +
  109 + function _selectSubConfig(subConfig) {
  110 + if (subConfig == 'movimento') {
  111 + _updateAndGetMovementConfig();
  112 + } else if (currentSubConfigName == 'movimento') {
  113 + _updateAndGetFirstMovementSubConfig();
  114 + }
  115 + currentSubConfigName = subConfig;
  116 + currentSubconfig = currentSubconfigParent[currentSubConfigName];
  117 + currentStep = 0;
  118 + _showCurrentSubconfig();
  119 + }
  120 +
  121 + // It shows the next selection panel on the workflow
  122 + function _showNextSubConfig() {
  123 + _walkOnTheWorkflow(true);
  124 + }
  125 +
  126 + function _showPreviousSubConfig() {
  127 + _walkOnTheWorkflow(false);
  128 + }
  129 +
  130 + function _walkOnTheWorkflow(toForward) {
  131 + currentStep = toForward ? currentStep + 1 : currentStep - 1;
  132 +
  133 + if (currentStep >= 0 && currentStep < currentSubconfig.length) {
  134 + _showCurrentSubconfig();
  135 + } else {
  136 + var nextSubConfig = _getNextSubConfig(toForward);
  137 + if (nextSubConfig != -1) {
  138 + _selectSubConfig(nextSubConfig);
  139 + } else {
  140 + selectionPanel.hide();
  141 + }
  142 + }
  143 + }
  144 +
  145 + function _checkIfFinished(mainConfig, currentSubConfigName) {
  146 + var numberOfSteps = currentSubconfig.length;
  147 + var completedSteps = $('.selection-panel-body[mainConfig=' + mainConfig
  148 + + '][subConfig=' + currentSubConfigName
  149 + + '] .selection-panel-option[select=true]').length;
  150 + return completedSteps != 0 && completedSteps == numberOfSteps;
  151 + }
  152 +
  153 + // A callback function to be called when the user selects a option on a panel
  154 + function _userSelectedAnOption() {
  155 + if (_checkIfFinished(mainConfig, currentSubConfigName)) {
  156 + _setupCheckIcon(mainConfig, currentSubConfigName);
  157 + }
  158 + _showNextSubConfig();
  159 + }
  160 +
  161 + function _cleanStep(mainConfig, subConfig, step) {
  162 + var baseId = '.selection-panel-body[mainConfig=' + mainConfig
  163 + + '][subConfig=' + subConfig + '][step=' + step + ']';
  164 + $(baseId + ' .selection-panel-option').removeAttr('select');
  165 + var icon_id = '.subconfiguration-panel[mainConfig=' + mainConfig
  166 + + '] .icon_container[json_name=' + subConfig + ']';
  167 + $(icon_id).removeAttr('complete');
  168 + }
  169 +
  170 + // Timeline functions
  171 + function _selectTimelineIcon(mainConfig, subConfig) {
  172 + var baseId = '.subconfiguration-panel[mainConfig=' + mainConfig
  173 + + '] .subconfiguration-options';
  174 + var iconContainer = '.icon_container[json_name=' + subConfig + ']';
  175 + var iconId = baseId + ' ' + iconContainer;
  176 +
  177 + var previousSelected = $(baseId + ' .icon_container[select=true]')
  178 + .attr('json_name');
  179 + if (typeof previousSelected != 'undefined') {
  180 + _deselectTimelineIcon(mainConfig, previousSelected);
  181 + }
  182 +
  183 + iconHelper.enableIconHover($(iconId), true);
  184 + $(iconId).attr('select', true);
  185 + $(baseId).scrollTo(iconContainer, {
  186 + 'offset' : -60,
  187 + 'duration' : 750
  188 + });
  189 + }
  190 +
  191 + function _deselectTimelineIcon(mainConfig, subConfig) {
  192 + var icon_id = '.subconfiguration-panel[mainConfig=' + mainConfig
  193 + + '] .icon_container[json_name=' + subConfig + ']';
  194 +
  195 + if ($(icon_id + '[complete=true]').length > 0) {
  196 + _setupCheckIcon(mainConfig, subConfig);
  197 + } else {
  198 + iconHelper.enableIconHover($(icon_id), false);
  199 + $(icon_id).removeAttr('select');
  200 + }
  201 + }
  202 +
  203 + function _setupCheckIcon(mainConfig, subConfig) {
  204 + var icon_id = $('.subconfiguration-panel[mainConfig=' + mainConfig
  205 + + '] .icon_container[json_name=' + subConfig + ']');
  206 + iconHelper.enableIconCheck(icon_id, true);
  207 + $(icon_id).attr('complete', true);
  208 + $(icon_id).attr('select', false);
  209 + }
  210 +
  211 + function _isTimelineLoaded() {
  212 + return $('.subconfiguration-panel[mainConfig=' + mainConfig + ']').length > 0;
  213 + }
  214 +
  215 + function _setupTimelineListeners(timelineBaseId) {
  216 + $(timelineBaseId + ' .icon_container[json_name]').off('click').on(
  217 + 'click', function() {
  218 + var subConfig = $(this).attr('json_name');
  219 + _selectSubConfig(subConfig);
  220 + });
  221 + $(timelineBaseId + ' .icon_container[json_name]').off('mouseover').on(
  222 + 'mouseover', function() {
  223 + if (iconHelper.canHover(this)) {
  224 + iconHelper.enableIconHover(this, true);
  225 + }
  226 + });
  227 + $(timelineBaseId + ' .icon_container[json_name]').off('mouseout').on(
  228 + 'mouseout', function() {
  229 + if (iconHelper.canHover(this)) {
  230 + iconHelper.enableIconHover(this, false);
  231 + }
  232 + });
  233 + $(timelineBaseId + ' .arrow[name=right-arrow]').off('click').on(
  234 + 'click', function() {
  235 + _showNextSubConfig();
  236 + });
  237 + $(timelineBaseId + ' .arrow[name=left-arrow]').off('click').on('click',
  238 + function() {
  239 + _showPreviousSubConfig();
  240 + });
  241 + }
  242 +
  243 + function _setupTimelineIcons(timelineBaseId, toUpdate) {
  244 + if (!toUpdate) {
  245 + $(timelineBaseId).show();
  246 + $(timelineBaseId + " .subconfiguration-options").scrollTo(0, 0);
  247 + return;
  248 + }
  249 +
  250 + $(timelineBaseId + ' .icon_container[json_name]').attr("active",
  251 + "false");
  252 + for ( var name in currentSubconfigParent) {
  253 + $(timelineBaseId + ' .icon_container[json_name=' + name + ']')
  254 + .attr("active", "true");
  255 + }
  256 +
  257 + if (preprocessedMainConfig == 'hand') {
  258 + $(timelineBaseId + ' .icon_container[json_name=movimento]').attr(
  259 + "active", "true");
  260 + _setupCheckIcon(mainConfig, 'movimento');
  261 + }
  262 + _selectTimelineIcon(mainConfig, currentSubConfigName);
  263 + _setupTimelineListeners(timelineBaseId);
  264 + $(timelineBaseId).show();
  265 + }
  266 +
  267 + function _setupTimeline(toUpdate) {
  268 + var timelineBaseId = '.subconfiguration-panel[mainConfig=' + mainConfig
  269 + + ']';
  270 + if (_isTimelineLoaded()) {
  271 + _setupTimelineIcons(timelineBaseId, toUpdate);
  272 + } else {
  273 + dynengine.render(baseUrl, '/' + preprocessedMainConfig
  274 + + '/timeline.html', '#selection-panel', false, function() {
  275 + _setupTimelineIcons(timelineBaseId, true);
  276 + });
  277 + }
  278 + }
  279 +
  280 + function _initTimeline() {
  281 + if (preprocessedMainConfig != 'hand' || _isTimelineLoaded()) {
  282 + _setupTimeline(false);
  283 + }
  284 + }
  285 +
  286 + function _cleanTimeline() {
  287 + $(".subconfiguration-panel").remove();
  288 + }
  289 +
  290 + function _cleanPreviousLoadedPanel() {
  291 + $('.selection-panel-body[mainConfig=' + mainConfig + ']').each(
  292 + function() {
  293 + var subConfigName = $(this).attr("subConfig");
  294 + if (subConfigName.indexOf("articulacao") != -1
  295 + || subConfigName.indexOf("configuracao") != -1
  296 + || subConfigName.indexOf("orientacao") != -1
  297 + || subConfigName.indexOf("movimento") != -1) {
  298 + return;
  299 + }
  300 + $(
  301 + '.selection-panel-body[mainConfig=' + mainConfig
  302 + + '][subConfig=' + subConfigName + ']')
  303 + .remove();
  304 + });
  305 + }
  306 +
  307 + // Public methods
  308 + dynworkflow.selectMainConfig = function(config) {
  309 + mainConfig = config;
  310 + preprocessedMainConfig = _preprocessMainConfig(mainConfig);
  311 + currentSubconfigParent = jsonWF[preprocessedMainConfig];
  312 + currentSubConfigName = _getFirstKey(currentSubconfigParent);
  313 + currentSubconfig = currentSubconfigParent[currentSubConfigName];
  314 + currentStep = 0;
  315 +
  316 + _showCurrentSubconfig();
  317 + };
  318 +
  319 + dynworkflow.selectMovement = function(movement) {
  320 + var subconfigJSON = currentSubconfig[movement];
  321 + currentSubConfigName = _getFirstKey(subconfigJSON);
  322 + currentSubconfigParent = subconfigJSON;
  323 + currentSubconfig = subconfigJSON[currentSubConfigName];
  324 + currentStep = 0;
  325 +
  326 + _cleanPreviousLoadedPanel();
  327 + _showCurrentSubconfig();
  328 + _setupTimeline(true);
  329 + };
  330 +
  331 + dynworkflow.selectSubConfig = function(subConfig) {
  332 + _selectSubConfig(subConfig);
  333 + };
  334 +
  335 + dynworkflow.userSelectedAnOption = function() {
  336 + _userSelectedAnOption();
  337 + };
  338 +
  339 + dynworkflow.cleanStep = function(mainConfig, subConfig, step) {
  340 + _cleanStep(mainConfig, subConfig, step);
  341 + };
  342 +
  343 + dynworkflow.getFacialParameters = function() {
  344 + return _getAttributes(jsonWF['facial']);
  345 + };
  346 +
  347 + dynworkflow.getMovementParameters = function(movementName) {
  348 + return _getAttributes(jsonWF['hand']['movimento'][movementName]);
  349 + };
  350 +
  351 + dynworkflow.getMainConfig = function() {
  352 + return mainConfig;
  353 + };
  354 +
  355 + dynworkflow.initTimeline = function() {
  356 + _initTimeline();
  357 + };
  358 +
  359 + dynworkflow.load = function() {
  360 + baseUrl = $('#server-url').data('url');
  361 + $.get(baseUrl + '/conf/selection-workflow-json', function(result) {
  362 + jsonWF = $.parseJSON(result);
  363 + }).fail(function() {
  364 + console.log('Failed to load the workflow configuration');
  365 + });
  366 + _cleanTimeline();
  367 + };
  368 +
  369 +}(window.dynworkflow = window.dynworkflow || {}, jQuery));
... ...
view/assets/js/selection-panel/facial.js 0 → 100644
... ... @@ -0,0 +1,21 @@
  1 +(function(facial, $, undefined) {
  2 +
  3 + facial.setup = function(subConfig) {
  4 + var baseId = '.selection-panel-body[mainConfig=facial][subConfig='
  5 + + subConfig + ']';
  6 + $(baseId + ' .selection-panel-option').off('click').on('click',
  7 + function() {
  8 + selectionPanel.selectAnOption(baseId, this);
  9 + dynworkflow.userSelectedAnOption();
  10 + });
  11 + $(baseId + ' .video-panel-option').off('mouseenter').on('mouseenter',
  12 + function(event) {
  13 + $(this).addClass('video-panel-option-hover');
  14 + });
  15 + $(baseId + ' .video-panel-option').off('mouseleave').on('mouseleave',
  16 + function(event) {
  17 + $(this).removeClass('video-panel-option-hover');
  18 + });
  19 + };
  20 +
  21 +}(window.facial = window.facial || {}, jQuery));
... ...
view/assets/js/selection-panel/movement.js 0 → 100644
... ... @@ -0,0 +1,24 @@
  1 +(function(movement, $, undefined) {
  2 +
  3 + movement.getPreviousSelectedMovement = function(mainConfig) {
  4 + return $('.selection-panel-body[mainConfig=' + mainConfig +
  5 + '][subConfig=movimento][step=1] .selection-panel-option[select=true]').attr('value');
  6 + };
  7 +
  8 + movement.setup = function(serverhost, hand) {
  9 + var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=movimento][step=1]';
  10 + $(baseId + ' .selection-panel-option').off('click').on(
  11 + 'click', function() {
  12 + selectionPanel.selectAnOption(baseId, this);
  13 + dynworkflow.selectMovement($(this).attr('value'));
  14 + });
  15 + $(baseId + ' .video-panel-option').off('mouseenter').on('mouseenter',
  16 + function(event) {
  17 + $(this).addClass('video-panel-option-hover');
  18 + });
  19 + $(baseId + ' .video-panel-option').off('mouseleave').on('mouseleave',
  20 + function(event) {
  21 + $(this).removeClass('video-panel-option-hover');
  22 + });
  23 + };
  24 +}(window.movement = window.movement || {}, jQuery));
... ...
view/assets/js/selection-panel/orientation.js 0 → 100644
... ... @@ -0,0 +1,13 @@
  1 +(function(orientation, $, undefined) {
  2 +
  3 + orientation.setup = function(hand, subConfig, step) {
  4 + var baseId = '.selection-panel-body[mainConfig=' + hand + '][subConfig=' +
  5 + subConfig + '][step=' + step + ']';
  6 + $(baseId + ' .selection-panel-option').off('click').on(
  7 + 'click', function() {
  8 + selectionPanel.selectAnOption(baseId, this);
  9 + dynworkflow.userSelectedAnOption();
  10 + });
  11 + };
  12 +
  13 +}(window.orientation = window.orientation || {}, jQuery));
... ...
view/assets/js/selection-panel/selection-panel.js 0 → 100644
... ... @@ -0,0 +1,194 @@
  1 +(function(selectionPanel, $, undefined) {
  2 +
  3 + function _selectAnOption(parentId, el) {
  4 + $(parentId + ' .selection-panel-option[select=true]').removeAttr(
  5 + 'select');
  6 + $(el).attr('select', true);
  7 +
  8 + var mainConfig = $(parentId).attr('mainConfig');
  9 + var subConfig = $(parentId).attr('subConfig');
  10 + var step = $(parentId).attr('step');
  11 + wikilibras.updateTempParameterJSON(mainConfig, subConfig, step, $(el).attr(
  12 + 'value'));
  13 + }
  14 +
  15 + function _canRenderSignVideo() {
  16 + return _isConfigurationComplete('facial') &&
  17 + (_isConfigurationComplete('right-hand') || _isConfigurationComplete('left-hand'));
  18 + }
  19 +
  20 + function _isConfigurationComplete(config) {
  21 + var baseId = '.subconfiguration-panel[mainConfig=' + config + ']';
  22 + var total_config = $(baseId
  23 + + ' .icon_container[json_name][active=true]').length;
  24 + var completed_config = $(baseId
  25 + + ' .icon_container[active=true][complete=true]').length;
  26 + return completed_config != 0 && total_config == completed_config;
  27 + }
  28 +
  29 + function _clearPreviousSelection() {
  30 + $('.selection-panel-body').hide();
  31 + $('.subconfiguration-panel').hide();
  32 +
  33 + if (configurationScreen.isMenuSelected()) {
  34 + var current_option = configurationScreen.getCurrentMainConfiguration();
  35 + iconHelper.selectIcon(current_option, false);
  36 + if (_isConfigurationComplete(current_option)) {
  37 + iconHelper.setupCheckIcon(current_option, true);
  38 + }
  39 + $('#avatar-' + current_option).fadeOut(500);
  40 + }
  41 + }
  42 +
  43 + function _finishConfiguration(config, toFinish) {
  44 + iconHelper.setupCheckIcon(config, toFinish);
  45 + iconHelper.setupCheckIcon('avatar-' + config, toFinish);
  46 +
  47 + if (toFinish) {
  48 + $('#' + config + '-edit .check-icon').show();
  49 + } else {
  50 + $('#' + config + '-edit .check-icon').hide();
  51 + }
  52 + if (_canRenderSignVideo()) {
  53 + $('#ready-button').removeClass('disabled');
  54 + } else {
  55 + $('#ready-button').addClass('disabled');
  56 + }
  57 + }
  58 +
  59 + function _unfinishConfiguration(config, panel) {
  60 + iconHelper.setupCheckIcon(config, false, panel);
  61 + iconHelper.setupCheckIcon('avatar-' + config, false, panel);
  62 + $('#' + config + '-edit .check-icon').hide();
  63 +
  64 + if (!_canRenderSignVideo()) {
  65 + $('#ready-button').addClass('disabled');
  66 + }
  67 + }
  68 +
  69 + function _addZoomInToAvatar(option, callback) {
  70 + $('#avatar-default')
  71 + .fadeOut(
  72 + 500,
  73 + function() {
  74 + $('#avatar-container').removeClass('col-sm-7');
  75 + $('#avatar-container').addClass('col-sm-5');
  76 + $('#selection-container').removeClass('col-sm-2');
  77 + $('#selection-container').addClass('col-sm-4');
  78 + $('#avatar-container').removeClass(
  79 + 'avatar-container-zoom-out');
  80 + $('#avatar-container').addClass(
  81 + 'avatar-container-zoom-in');
  82 + $('#avatar-' + option).removeClass(
  83 + 'avatar-img-zoom-out');
  84 + $('#avatar-' + option).fadeIn(
  85 + 500,
  86 + function() {
  87 + $('#avatar-' + option).addClass(
  88 + 'avatar-' + option
  89 + + '-img-zoom-in');
  90 + callback();
  91 + });
  92 + });
  93 + }
  94 +
  95 + function _addZoomOutToAvatar(option, callback) {
  96 + $('#avatar-' + option).fadeOut(
  97 + 500,
  98 + function() {
  99 + $('#selection-container').removeClass('col-sm-4');
  100 + $('#selection-container').addClass('col-sm-2');
  101 + $('#avatar-container').removeClass('col-sm-5');
  102 + $('#avatar-container').addClass('col-sm-7');
  103 + $('#avatar-container').removeClass(
  104 + 'avatar-container-zoom-in');
  105 + $('#avatar-container')
  106 + .addClass('avatar-container-zoom-out');
  107 + $('#avatar-default').fadeIn(
  108 + 500,
  109 + function() {
  110 + $('#avatar-' + option).removeClass(
  111 + 'avatar-' + option + '-img-zoom-in');
  112 + $('#avatar-' + option).addClass(
  113 + 'avatar-img-zoom-out');
  114 + callback();
  115 + });
  116 + });
  117 + }
  118 +
  119 + function _hide() {
  120 + var config = configurationScreen.getCurrentMainConfiguration();
  121 + if (config === '') return;
  122 +
  123 + iconHelper.deselectIcon(config);
  124 + if (_isConfigurationComplete(config)) {
  125 + _finishConfiguration(config, true);
  126 + } else {
  127 + _finishConfiguration(config, false);
  128 + }
  129 +
  130 + _addZoomOutToAvatar(config, function() {
  131 + $('#ready-button').fadeIn(300);
  132 + $('.edit-container').fadeIn(300);
  133 + });
  134 + $('#selection-panel').fadeOut(300);
  135 + }
  136 +
  137 + function _setupGUIOnSelection(option, finishCallback) {
  138 + $('#ready-button').fadeOut(300);
  139 + $('.edit-container').fadeOut(300);
  140 + _addZoomInToAvatar(option, function() {
  141 + $('#selection-panel').fadeIn(300, function() {
  142 + finishCallback();
  143 + });
  144 + });
  145 + }
  146 +
  147 + function _show(option) {
  148 + _clearPreviousSelection();
  149 + iconHelper.selectIcon(option, true);
  150 + dynworkflow.selectMainConfig(option);
  151 + _setupGUIOnSelection(option, function() {
  152 + dynworkflow.initTimeline();
  153 + });
  154 + }
  155 +
  156 + selectionPanel.selectAnOption = function (parentId, el) {
  157 + _selectAnOption(parentId, el);
  158 + }
  159 +
  160 + selectionPanel.unfinishConfiguration = function(config, panel) {
  161 + return _unfinishConfiguration(config, panel);
  162 + }
  163 +
  164 + selectionPanel.isConfigurationComplete = function(config) {
  165 + return _isConfigurationComplete(config);
  166 + }
  167 +
  168 + selectionPanel.hide = function() {
  169 + return _hide();
  170 + }
  171 +
  172 + selectionPanel.show = function(option) {
  173 + _show(option);
  174 + }
  175 +
  176 + selectionPanel.clean = function() {
  177 + articulation.clean();
  178 + $(".selection-panel-option").removeAttr('select');
  179 + $(".icon_container").removeAttr("select");
  180 + $(".icon_container[complete=true]").each(
  181 + function() {
  182 + _unfinishConfiguration($(this).attr("name"), $(this).attr(
  183 + "panel"));
  184 + });
  185 + }
  186 +
  187 + selectionPanel.setup = function(url) {
  188 + $('#selection-panel .x').off('click').on('click', function() {
  189 + _hide();
  190 + });
  191 + selectionPanel.clean();
  192 + };
  193 +
  194 +}(window.selectionPanel = window.selectionPanel || {}, jQuery));
... ...
view/assets/js/submit-sign.js
... ... @@ -32,6 +32,11 @@
32 32 $('#upload-progress-container').hide();
33 33 $('#input-sign-upload').show();
34 34 }
  35 +
  36 + submitSign.show = function() {
  37 + $(".sub-main-container").hide();
  38 + $("#submit-sign-container").show();
  39 + }
35 40  
36 41 submitSign.setup = function(uploadSignHost) {
37 42 submitUrl = uploadSignHost;
... ...
view/assets/js/teached-signs.js
... ... @@ -51,7 +51,7 @@
51 51 function _addSign(answer) {
52 52 var signName = answer.parameter_json.sinal;
53 53 var apiUserId = answer.parameter_json.userId;
54   - var videoUrl = wikilibras.getRenderedAvatarUrl(apiUserId, signName);
  54 + var videoUrl = renderSign.getRenderedAvatarUrl(apiUserId, signName);
55 55 $("#signs-list-container").append(
56 56 '<div class="col-btn col-xs-6 col-sm-3 col-md-2" sign-name="'
57 57 + signName
... ... @@ -77,6 +77,11 @@
77 77 _createSigns(answers);
78 78 });
79 79 }
  80 +
  81 + teachedSigns.show = function() {
  82 + $(".sub-main-container").hide();
  83 + $("#teached-signs-container").show();
  84 + }
80 85  
81 86 teachedSigns.setup = function() {
82 87 _getProjectId().done(function(response) {
... ...
view/assets/js/tmpJSONParser.js
... ... @@ -1,118 +0,0 @@
1   -(function(tmpJSONParser, $, undefined) {
2   -
3   - var base_parameter_json = {};
4   - var movement_parameter_json = {};
5   -
6   - function _setupBaseParameterJSON(tmpJSON) {
7   - base_parameter_json['userId'] = tmpJSON['userId'];
8   - base_parameter_json['sinal'] = tmpJSON['sinal'];
9   - base_parameter_json['interpolacao'] = 'normal';
10   - base_parameter_json['movimentos'] = [];
11   - movement_parameter_json = {
12   - 'facial': {},
13   - 'mao_direita': {},
14   - 'mao_esquerda': {}
15   - };
16   - base_parameter_json['movimentos'].push(movement_parameter_json);
17   - }
18   -
19   - function _parseParameterValue(value) {
20   - if (typeof value == 'string' && value.toLowerCase() == 'true') {
21   - return true;
22   - } else if (typeof value == 'string' && value.toLowerCase() == 'false') {
23   - return false;
24   - } else {
25   - return !isNaN(value) ? parseInt(value) : value;
26   - }
27   - }
28   -
29   - function _parseTempFacialParameterJSON(tmpJSON) {
30   - var attrs = dynworkflow.getFacialParameters();
31   - for (var i in attrs) {
32   - var attr = attrs[i];
33   - parameterValue = tmpJSON['facial'][attr][0];
34   - movement_parameter_json['facial'][attr] = _parseParameterValue(parameterValue);
35   - }
36   - }
37   -
38   - function _parseHand(hand) {
39   - var parsedHand = hand == 'right-hand' ? 'mao_direita' : hand;
40   - parsedHand = hand == 'left-hand' ? 'mao_esquerda' : parsedHand;
41   - return parsedHand;
42   - }
43   -
44   - // Default parser
45   - function _defaultMovementParser(tmpJSON, movementName, hand) {
46   - var attrs = dynworkflow.getMovementParameters(movementName);
47   - var parsedHand = _parseHand(hand);
48   -
49   - for (var i in attrs) {
50   - var attr = attrs[i];
51   - var parameterValue = '';
52   - if (attr == 'configuracao') {
53   - parameterValue = tmpJSON[hand][attr][1];
54   - } else if (attr == 'articulacao') {
55   - parameterValue = articulation.processValue(hand,
56   - tmpJSON[hand][attr]);
57   - } else {
58   - parameterValue = tmpJSON[hand][attr][0];
59   - }
60   - movement_parameter_json[parsedHand][movementName][attr] =
61   - _parseParameterValue(parameterValue);
62   - }
63   - }
64   -
65   - function _retilinearMovementParser(tmpJSON, movementName, hand) {
66   - var attrs = dynworkflow.getMovementParameters(movementName);
67   - var parsedHand = _parseHand(hand);
68   -
69   - for (var i in attrs) {
70   - var attr = attrs[i];
71   - var initParameterValue = '';
72   - var endParameterValue = '';
73   - if (attr == 'configuracao-retilineo') {
74   - initParameterValue = tmpJSON[hand][attr][1];
75   - endParameterValue = tmpJSON[hand][attr][3];
76   - } else if (attr == 'articulacao-retilineo') {
77   - initSlice = tmpJSON[hand][attr].slice(0, 2);
78   - endSlice = tmpJSON[hand][attr].slice(2, 4);
79   - initParameterValue = articulation.processValue(hand, initSlice);
80   - endParameterValue = articulation.processValue(hand, endSlice);
81   - } else {
82   - initParameterValue = tmpJSON[hand][attr][0];
83   - endParameterValue = tmpJSON[hand][attr][1];
84   - }
85   - attr = attr.replace('-retilineo', '');
86   - var initAttr = attr + '_inicial';
87   - var endAttr = attr + '_final';
88   - movement_parameter_json[parsedHand][movementName][initAttr] =
89   - _parseParameterValue(initParameterValue);
90   - movement_parameter_json[parsedHand][movementName][endAttr] =
91   - _parseParameterValue(endParameterValue);
92   - }
93   - }
94   -
95   - function _parseTempMovementParameterJSON(tmpJSON, hand) {
96   - var movimentConfig = tmpJSON[hand]['movimento'];
97   - if (typeof movimentConfig == 'undefined') return;
98   -
99   - var movementName = movimentConfig[0];
100   - var parsedHand = _parseHand(hand);
101   - movement_parameter_json[parsedHand][movementName] = {};
102   -
103   - if (movementName == 'retilineo') {
104   - _retilinearMovementParser(tmpJSON, movementName, hand);
105   - } else {
106   - _defaultMovementParser(tmpJSON, movementName, hand);
107   - }
108   - }
109   -
110   - tmpJSONParser.parse = function(tmpJSON) {
111   - _setupBaseParameterJSON(tmpJSON);
112   - _parseTempFacialParameterJSON(tmpJSON);
113   - _parseTempMovementParameterJSON(tmpJSON, 'right-hand');
114   - _parseTempMovementParameterJSON(tmpJSON, 'left-hand');
115   - return base_parameter_json;
116   - };
117   -
118   -}(window.tmpJSONParser = window.tmpJSONParser || {}, jQuery));
view/assets/js/wikilibras.js
... ... @@ -37,234 +37,6 @@
37 37 _setupTmpParameterJSON(task.info.sign_name);
38 38 }
39 39  
40   - function _changeImage(img, url) {
41   - img.attr('src', url);
42   - }
43   -
44   - function _enableIconHover(container, isHover) {
45   - var img = $(container).find('img').first();
46   - var hover_img_url = base_url + '/img/' + $(container).attr('name');
47   - if (isHover) {
48   - hover_img_url += '-icon-hover.png';
49   - } else {
50   - hover_img_url += '-icon.png';
51   - }
52   - _changeImage(img, hover_img_url);
53   - }
54   -
55   - function _selectIcon(iconName, isSelect, panel) {
56   - panel = typeof panel == 'undefined' ? '' : '[panel=' + panel + ']';
57   - var icon_id = '.icon_container[name=' + iconName + ']' + panel;
58   - _enableIconHover(icon_id, isSelect);
59   - $(icon_id).attr('select', isSelect);
60   - }
61   -
62   - function _deselectIcon(iconName, parent) {
63   - _selectIcon(iconName, false, parent);
64   - }
65   -
66   - function _enableIconCheck(container, isCheck) {
67   - var img = $(container).find('img').first();
68   - var check_img_url = base_url + '/img/' + $(container).attr('name');
69   -
70   - if (isCheck) {
71   - check_img_url += '-icon-check.png';
72   - } else {
73   - check_img_url += '-icon.png';
74   - }
75   - _changeImage(img, check_img_url);
76   - }
77   -
78   - function _setupCheckIcon(option, isCheck, panel) {
79   - panel = typeof panel == 'undefined' ? '' : '[panel=' + panel + ']';
80   - var icon_id = '.icon_container[name=' + option + ']' + panel;
81   - _enableIconCheck(icon_id, isCheck);
82   - $('.icon_container[name=' + option + ']' + panel).attr('complete',
83   - isCheck);
84   - }
85   -
86   - function _isSelectingState() {
87   - return $('#configuration-panel .icon_container[select=true]').length > 0;
88   - }
89   -
90   - function _isConfigurationComplete(config) {
91   - var baseId = '.subconfiguration-panel[mainConfig=' + config + ']';
92   - var total_config = $(baseId
93   - + ' .icon_container[json_name][active=true]').length;
94   - var completed_config = $(baseId
95   - + ' .icon_container[active=true][complete=true]').length;
96   - return completed_config != 0 && total_config == completed_config;
97   - }
98   -
99   - function _canHover(el) {
100   - var incompleteConfig = typeof $(el).attr('complete') == 'undefined'
101   - || $(el).attr('complete') == 'false';
102   - return (!_isSelectingState() && incompleteConfig)
103   - || (typeof $(el).attr('select') == 'undefined' && incompleteConfig);
104   - }
105   -
106   - function _getCurrentMainConfiguration() {
107   - return _isSelectingState() ? $(
108   - '#configuration-panel .icon_container[select=true]').attr(
109   - 'name') : '';
110   - }
111   -
112   - function _addZoomInToAvatar(option, callback) {
113   - $('#avatar-default')
114   - .fadeOut(
115   - 500,
116   - function() {
117   - $('#avatar-container').removeClass('col-sm-7');
118   - $('#avatar-container').addClass('col-sm-5');
119   - $('#selection-container').removeClass('col-sm-2');
120   - $('#selection-container').addClass('col-sm-4');
121   - $('#avatar-container').removeClass(
122   - 'avatar-container-zoom-out');
123   - $('#avatar-container').addClass(
124   - 'avatar-container-zoom-in');
125   - $('#avatar-' + option).removeClass(
126   - 'avatar-img-zoom-out');
127   - $('#avatar-' + option).fadeIn(
128   - 500,
129   - function() {
130   - $('#avatar-' + option).addClass(
131   - 'avatar-' + option
132   - + '-img-zoom-in');
133   - callback();
134   - });
135   - });
136   - }
137   -
138   - function _addZoomOutToAvatar(option, callback) {
139   - $('#avatar-' + option).fadeOut(
140   - 500,
141   - function() {
142   - $('#selection-container').removeClass('col-sm-4');
143   - $('#selection-container').addClass('col-sm-2');
144   - $('#avatar-container').removeClass('col-sm-5');
145   - $('#avatar-container').addClass('col-sm-7');
146   - $('#avatar-container').removeClass(
147   - 'avatar-container-zoom-in');
148   - $('#avatar-container')
149   - .addClass('avatar-container-zoom-out');
150   - $('#avatar-default').fadeIn(
151   - 500,
152   - function() {
153   - $('#avatar-' + option).removeClass(
154   - 'avatar-' + option + '-img-zoom-in');
155   - $('#avatar-' + option).addClass(
156   - 'avatar-img-zoom-out');
157   - callback();
158   - });
159   - });
160   - }
161   -
162   - function _clearPreviousSelection() {
163   - $('.selection-panel-body').hide();
164   - $('.subconfiguration-panel').hide();
165   -
166   - if (_isSelectingState()) {
167   - var current_option = _getCurrentMainConfiguration();
168   - _selectIcon(current_option, false);
169   - if (_isConfigurationComplete(current_option)) {
170   - _setupCheckIcon(current_option, true);
171   - }
172   - $('#avatar-' + current_option).fadeOut(500);
173   - }
174   - }
175   -
176   - function _showSelectionPanel(option) {
177   - _clearPreviousSelection();
178   - _selectIcon(option, true);
179   - dynworkflow.selectMainConfig(option);
180   - _setupGUIOnSelection(option, function() {
181   - dynworkflow.initTimeline();
182   - });
183   - }
184   -
185   - function _hideSelectionPanel() {
186   - var config = _getCurrentMainConfiguration();
187   - _deselectIcon(config);
188   - if (_isConfigurationComplete(config)) {
189   - _finishConfiguration(config, true);
190   - } else {
191   - _finishConfiguration(config, false);
192   - }
193   -
194   - _addZoomOutToAvatar(config, function() {
195   - $('#ready-button').fadeIn(300);
196   - $('.edit-container').fadeIn(300);
197   - });
198   - $('#selection-panel').fadeOut(300);
199   - }
200   -
201   - function _canRenderSignVideo() {
202   - return _isConfigurationComplete('facial')
203   - && (_isConfigurationComplete('right-hand') || _isConfigurationComplete('left-hand'));
204   - }
205   -
206   - function _finishConfiguration(config, toFinish) {
207   - _setupCheckIcon(config, toFinish);
208   - _setupCheckIcon('avatar-' + config, toFinish);
209   -
210   - if (toFinish) {
211   - $('#' + config + '-edit .check-icon').show();
212   - } else {
213   - $('#' + config + '-edit .check-icon').hide();
214   - }
215   - if (_canRenderSignVideo()) {
216   - $('#ready-button').removeClass('disabled');
217   - } else {
218   - $('#ready-button').addClass('disabled');
219   - }
220   - }
221   -
222   - function _unfinishConfiguration(config, panel) {
223   - _setupCheckIcon(config, false, panel);
224   - _setupCheckIcon('avatar-' + config, false, panel);
225   - $('#' + config + '-edit .check-icon').hide();
226   -
227   - if (!_canRenderSignVideo()) {
228   - $('#ready-button').addClass('disabled');
229   - }
230   - }
231   -
232   - function _setupGUIOnSelection(option, finishCallback) {
233   - $('#ready-button').fadeOut(300);
234   - $('.edit-container').fadeOut(300);
235   - _addZoomInToAvatar(option, function() {
236   - $('#selection-panel').fadeIn(300, function() {
237   - finishCallback();
238   - });
239   - });
240   - }
241   -
242   - function _setupConfigurationPanel() {
243   - $('.icon_container').off('mouseover').on('mouseover', function() {
244   - if (_canHover(this)) {
245   - _enableIconHover(this, true);
246   - }
247   - });
248   - $('.icon_container').off('mouseout').on('mouseout', function() {
249   - if (_canHover(this)) {
250   - _enableIconHover(this, false);
251   - }
252   - });
253   - $('.config-panel-option').off('click').on('click', function() {
254   - _showSelectionPanel($(this).attr('panel'));
255   - });
256   - $('#minimize-icon-container').off('click').on('click', function() {
257   - $('#ref-video-container').hide();
258   - $('#minimize-icon-container').hide();
259   - $('#maximize-icon-container').show();
260   - });
261   - $('#maximize-icon-container').off('click').on('click', function() {
262   - $('#ref-video-container').show();
263   - $('#maximize-icon-container').hide();
264   - $('#minimize-icon-container').show();
265   - });
266   - }
267   -
268 40 function _updateTempParameterJSON(mainConfig, subConfig, step, value) {
269 41 var subConfigJSON = tmpParameterJSON[mainConfig][subConfig];
270 42 if (typeof subConfigJSON == 'undefined') {
... ... @@ -275,132 +47,34 @@
275 47 subConfigJSON[parseInt(step) - 1] = value;
276 48 }
277 49  
278   - function _selectAnOption(parentId, el) {
279   - $(parentId + ' .selection-panel-option[select=true]').removeAttr(
280   - 'select');
281   - $(el).attr('select', true);
282   -
283   - var mainConfig = $(parentId).attr('mainConfig');
284   - var subConfig = $(parentId).attr('subConfig');
285   - var step = $(parentId).attr('step');
286   - _updateTempParameterJSON(mainConfig, subConfig, step, $(el).attr(
287   - 'value'));
288   - }
289   -
290   - function _setupSelectionPanel() {
291   - $('#selection-panel .x').off('click').on('click', function() {
292   - _hideSelectionPanel();
293   - });
294   - }
295   -
296   - // Render Screen
297   - function _submitParameterJSON(callback) {
298   - parsedParameterJSON = tmpJSONParser.parse(tmpParameterJSON);
299   - console.log(parsedParameterJSON);
300   -
301   - $.ajax({
302   - type : 'POST',
303   - url : api_url + '/sign',
304   - data : JSON.stringify(parsedParameterJSON),
305   - contentType : 'application/json',
306   - success : function(response) {
307   - console.log(response);
308   - callback();
309   - },
310   - error : function(xhr, textStatus, error) {
311   - alert(xhr.responseText);
312   - }
313   - });
314   - }
315   -
316   - function _getRenderedAvatarUrl(userId, signName) {
317   - return api_url + '/public/' + userId + '/' + signName + ".webm";
  50 + function _parseTmpParameterJSON() {
  51 + parsedParameterJSON = tmpJSONParser.parse(tmpParameterJSON,
  52 + selectionPanel.isConfigurationComplete('right-hand'),
  53 + selectionPanel.isConfigurationComplete('left-hand'));
  54 + return parsedParameterJSON;
318 55 }
319 56  
320   - function _showRenderedAvatar(parameterJSON) {
321   - var userId = parameterJSON['userId'];
322   - var signName = parameterJSON['sinal'];
323   - $("#render-avatar video").attr("src",
324   - _getRenderedAvatarUrl(userId, signName));
325   - $("#render-avatar").fadeIn(300);
326   - }
327   -
328   - function _controlVideo(elId, toPlay) {
329   - var videoSrc = $(elId).attr("src");
330   - if (typeof videoSrc == "undefined" ||
331   - (typeof videoSrc != "undefined" && videoSrc === ""))
332   - return;
333   - if (toPlay) {
334   - $(elId).get(0).play();
335   - } else {
336   - $(elId).get(0).pause();
337   - }
338   - }
339   -
340   - function _playVideo(elId) {
341   - _controlVideo(elId, true);
342   - }
343   -
344   - function _pauseVideo(elId) {
345   - _controlVideo(elId, false);
346   - }
347   -
348 57 function _showInitialScreen(toShow) {
349 58 if (toShow) {
350 59 $("#initial-screen").fadeIn(300);
351   - _playVideo("#initial-screen video");
  60 + videoHelper.play("#initial-screen video");
352 61 } else {
353 62 $("#initial-screen").hide();
354   - _pauseVideo("#initial-screen video");
  63 + videoHelper.pause("#initial-screen video");
355 64 }
356 65 }
357 66  
358   - function _showConfigurationScreen(toShow) {
  67 + function _showApprovalScreen(toShow, parameterJSON) {
359 68 if (toShow) {
360   - $("#configuration-screen").show();
361   - _playVideo("#ref-video-container video");
  69 + $("#render-button-container .btn").hide();
  70 + $("#approval-button").show();
  71 + $("#approval-msg").show();
  72 + renderSign.showRenderedAvatar(parameterJSON);
362 73 } else {
363   - $("#configuration-screen").hide();
364   - _pauseVideo("#ref-video-container video");
  74 + $("#approval-button").hide();
  75 + $("#approval-msg").hide();
365 76 }
366 77 }
367   -
368   - function _showRenderScreen(toShow) {
369   - if (toShow) {
370   - $("#render-screen").fadeIn(300);
371   - _playVideo("#render-ref video");
372   - _playVideo("#render-avatar video");
373   - } else {
374   - $("#render-screen").hide();
375   - _pauseVideo("#render-ref video");
376   - _pauseVideo("#render-avatar video");
377   - }
378   - }
379   -
380   - function _setupRenderScreen() {
381   - _showConfigurationScreen(false);
382   - _showRenderScreen(true);
383   - $("#render-avatar").hide();
384   - $("#render-loading").fadeIn(300);
385   - $("#render-button-container .btn").hide();
386   - $("#finish-button").addClass("disabled");
387   - $("#finish-button").show();
388   -
389   - _submitParameterJSON(function() {
390   - $("#render-loading").fadeOut(300);
391   - $("#finish-button").removeClass("disabled");
392   - _showRenderedAvatar(parsedParameterJSON);
393   - });
394   - }
395   -
396   - function _setupApprovalScreen(parameterJSON) {
397   - $("#render-button-container .btn").hide();
398   - $("#approval-button").show();
399   - $("#approval-msg").show();
400   -
401   - _showRenderedAvatar(parameterJSON);
402   - _showRenderScreen(true);
403   - }
404 78  
405 79 function _submitAnswer(task, deferred, status) {
406 80 var answer = _createAnswer(task, status);
... ... @@ -409,44 +83,29 @@
409 83 } else {
410 84 _saveAnswer(task, deferred, answer);
411 85 }
412   - _showRenderScreen(false);
  86 + renderSign.showRenderScreen(false);
413 87 $("#thanks-screen").show();
414 88 }
415 89  
416   - function _clearGUI() {
417   - articulation.clean();
418   - $(".selection-panel-option").removeAttr('select');
419   - $(".icon_container").removeAttr("select");
420   - $(".icon_container[complete=true]").each(
421   - function() {
422   - _unfinishConfiguration($(this).attr("name"), $(this).attr(
423   - "panel"));
424   - });
425   - }
426   -
427 90 function _setupMainScreen(task, deferred) {
428 91 var last_answer = task.info.last_answer;
429 92 var hasLastAnswer = typeof last_answer != "undefined";
430 93 if (hasLastAnswer) {
431   - _setupApprovalScreen(last_answer.parameter_json);
  94 + _showApprovalScreen(true, last_answer.parameter_json);
432 95 } else {
  96 + _showApprovalScreen(false);
433 97 _showInitialScreen(true);
434 98 }
435   -
436 99 $("#start-button").off("click").on("click", function() {
437 100 _showInitialScreen(false);
438   - _showConfigurationScreen(true);
  101 + configurationScreen.show(true);
439 102 });
440 103 $("#ready-button").off("click").on("click", function() {
441 104 if ($(this).hasClass('disabled')) {
442 105 event.preventDefault();
443 106 return;
444 107 }
445   - _setupRenderScreen();
446   - });
447   - $("#render-edit").off("click").on("click", function() {
448   - _showRenderScreen(false);
449   - _showConfigurationScreen(true);
  108 + renderSign.submit(_parseTmpParameterJSON());
450 109 });
451 110 $("#finish-button").off("click").on("click", function() {
452 111 if ($(this).hasClass('disabled')) {
... ... @@ -461,9 +120,7 @@
461 120 }
462 121  
463 122 function _setupGUI(task, deferred) {
464   - _clearGUI();
465   - _setupConfigurationPanel();
466   - _setupSelectionPanel();
  123 + configurationScreen.setup();
467 124 _setupMainScreen(task, deferred);
468 125 }
469 126  
... ... @@ -532,10 +189,12 @@
532 189 }
533 190  
534 191 function _loadMainComponents() {
  192 + iconHelper.setup(base_url);
535 193 dynengine.load();
536 194 dynworkflow.load();
537 195 submitSign.setup(upload_signs_url);
538 196 teachedSigns.setup();
  197 + renderSign.setup(api_url);
539 198 _setupLoginContainer();
540 199 }
541 200  
... ... @@ -572,45 +231,11 @@
572 231 _updateTempParameterJSON(mainConfig, subConfig, step, value);
573 232 }
574 233  
575   - wikilibras.hideSelectionPanel = function() {
576   - _hideSelectionPanel();
577   - }
578   -
579   - wikilibras.selectAnOption = function(parentId, el) {
580   - _selectAnOption(parentId, el);
581   - }
582   -
583   - wikilibras.enableIconCheck = function(container, isHover) {
584   - _enableIconCheck(container, isHover);
585   - }
586   -
587   - wikilibras.canHover = function(container) {
588   - return _canHover(container);
589   - }
590   -
591   - wikilibras.enableIconHover = function(container, isHover) {
592   - _enableIconHover(container, isHover);
593   - }
594   -
595   - wikilibras.getRenderedAvatarUrl = function(userId, signName) {
596   - return _getRenderedAvatarUrl(userId, signName);
597   - }
598   -
599 234 wikilibras.showTeachContainer = function() {
600 235 $(".sub-main-container").hide();
601 236 $("#teach-container").show();
602 237 }
603 238  
604   - wikilibras.showSubmitSignContainer = function() {
605   - $(".sub-main-container").hide();
606   - $("#submit-sign-container").show();
607   - }
608   -
609   - wikilibras.showTeachedSignsContainer = function() {
610   - $(".sub-main-container").hide();
611   - $("#teached-signs-container").show();
612   - }
613   -
614 239 wikilibras.showTutorialContainer = function() {
615 240 $(".sub-main-container").hide();
616 241 $("#tutorial-container").show();
... ...
view/template.html
... ... @@ -23,9 +23,9 @@
23 23 <li><a href="javascript:void(0);"
24 24 onclick="wikilibras.showTeachContainer()">Ensinar</a></li>
25 25 <li><a href="javascript:void(0);"
26   - onclick="wikilibras.showSubmitSignContainer()">Enviar sinal</a></li>
  26 + onclick="submitSign.show()">Enviar sinal</a></li>
27 27 <li><a href="javascript:void(0);"
28   - onclick="wikilibras.showTeachedSignsContainer()">Sinais
  28 + onclick="teachedSigns.show()">Sinais
29 29 ensinados</a></li>
30 30 <li><a href="javascript:void(0);"
31 31 onclick="wikilibras.showTutorialContainer()">Tutorial</a></li>
... ... @@ -76,21 +76,21 @@
76 76 <img id="maximize-icon" src="{{ server }}/img/maximize-icon.png"></img>
77 77 </div>
78 78 </div>
79   - <div id="configuration-panel" class="col-sm-8">
80   - <div class="icon_container config-panel-option" name="facial"
  79 + <div id="configuration-menu" class="col-sm-8">
  80 + <div class="icon_container config-menu-option" name="facial"
81 81 panel="facial">
82 82 <img src="{{ server }}/img/facial-icon.png"</img> <span
83   - class="configuration-panel-label">Expressão</span>
  83 + class="configuration-menu-label">Expressão</span>
84 84 </div>
85   - <div class="icon_container config-panel-option" name="right-hand"
  85 + <div class="icon_container config-menu-option" name="right-hand"
86 86 panel="right-hand">
87 87 <img src="{{ server }}/img/right-hand-icon.png"></img> <span
88   - class="configuration-panel-label">Mão direita</span>
  88 + class="configuration-menu-label">Mão direita</span>
89 89 </div>
90   - <div class="icon_container config-panel-option" name="left-hand"
  90 + <div class="icon_container config-menu-option" name="left-hand"
91 91 panel="left-hand">
92 92 <img src="{{ server }}/img/left-hand-icon.png"></img> <span
93   - class="configuration-panel-label">Mão esquerda</span>
  93 + class="configuration-menu-label">Mão esquerda</span>
94 94 </div>
95 95 </div>
96 96 </div>
... ... @@ -98,38 +98,38 @@
98 98 class="col-sm-7 avatar-container-zoom-out">
99 99 <div id="facial-edit" class="edit-container">
100 100 <img class="check-icon" src="{{ server }}/img/check-icon.png"></img>
101   - <div class="icon_container config-panel-option" name="edit"
  101 + <div class="icon_container config-menu-option" name="edit"
102 102 panel="facial">
103 103 <img src="{{ server }}/img/edit-icon.png"></img>
104 104 </div>
105 105 </div>
106 106 <div id="right-hand-edit" class="edit-container">
107 107 <img class="check-icon" src="{{ server }}/img/check-icon.png"></img>
108   - <div class="icon_container config-panel-option" name="edit"
  108 + <div class="icon_container config-menu-option" name="edit"
109 109 panel="right-hand">
110 110 <img src="{{ server }}/img/edit-icon.png"></img>
111 111 </div>
112 112 </div>
113 113 <div id="left-hand-edit" class="edit-container">
114 114 <img class="check-icon" src="{{ server }}/img/check-icon.png"></img>
115   - <div class="icon_container config-panel-option" name="edit"
  115 + <div class="icon_container config-menu-option" name="edit"
116 116 panel="left-hand">
117 117 <img src="{{ server }}/img/edit-icon.png"></img>
118 118 </div>
119 119 </div>
120 120 <div id="avatar-default" class="avatar-img">
121 121 <div id="avatar-body-face"
122   - class="icon_container config-panel-option" name="avatar-facial"
  122 + class="icon_container config-menu-option" name="avatar-facial"
123 123 panel="facial">
124 124 <img src="{{ server }}/img/avatar-facial-icon.png"></img>
125 125 </div>
126 126 <div id="avatar-body-right-hand"
127   - class="icon_container config-panel-option"
  127 + class="icon_container config-menu-option"
128 128 name="avatar-right-hand" panel="right-hand">
129 129 <img src="{{ server }}/img/avatar-right-hand-icon.png"></img>
130 130 </div>
131 131 <div id="avatar-body-left-hand"
132   - class="icon_container config-panel-option"
  132 + class="icon_container config-menu-option"
133 133 name="avatar-left-hand" panel="left-hand">
134 134 <img src="{{ server }}/img/avatar-left-hand-icon.png"></img>
135 135 </div>
... ... @@ -328,23 +328,33 @@
328 328 </div>
329 329 </div>
330 330  
331   -<script src="{{ server }}/assets/js/jquery.scrollTo.js"></script>
332   -<script src="{{ server }}/assets/js/js.cookie.js"></script>
333   -<script src="{{ server }}/assets/js/jquery.ui.widget.js"></script>
334   -<script src="{{ server }}/assets/js/jquery.iframe-transport.js"></script>
335   -<script src="{{ server }}/assets/js/jquery.fileupload.js"></script>
  331 +<!-- External Libs -->
  332 +<script src="{{ server }}/assets/js/external-libs/jquery.scrollTo.js"></script>
  333 +<script src="{{ server }}/assets/js/external-libs/js.cookie.js"></script>
  334 +<script src="{{ server }}/assets/js/external-libs/jquery.ui.widget.js"></script>
  335 +<script src="{{ server }}/assets/js/external-libs/jquery.iframe-transport.js"></script>
  336 +<script src="{{ server }}/assets/js/external-libs/jquery.fileupload.js"></script>
  337 +
  338 +<!-- Selection Panel -->
  339 +<script src="{{ server }}/assets/js/selection-panel/facial.js"></script>
  340 +<script src="{{ server }}/assets/js/selection-panel/movement.js"></script>
  341 +<script src="{{ server }}/assets/js/selection-panel/articulation.js"></script>
  342 +<script src="{{ server }}/assets/js/selection-panel/configuration.js"></script>
  343 +<script src="{{ server }}/assets/js/selection-panel/orientation.js"></script>
  344 +<script src="{{ server }}/assets/js/selection-panel/default-configuration-handler.js"></script>
  345 +<script src="{{ server }}/assets/js/selection-panel/dynamic-loading-engine.js"></script>
  346 +<script src="{{ server }}/assets/js/selection-panel/dynamic-selection-workflow.js"></script>
  347 +<script src="{{ server }}/assets/js/selection-panel/selection-panel.js"></script>
  348 +
  349 +<!-- Helpers -->
  350 +<script src="{{ server }}/assets/js/helpers/video-helper.js"></script>
  351 +<script src="{{ server }}/assets/js/helpers/icon-helper.js"></script>
  352 +<script src="{{ server }}/assets/js/helpers/tmpJSONParser.js"></script>
336 353  
337 354 <script src="{{ server }}/assets/js/teached-signs.js"></script>
338 355 <script src="{{ server }}/assets/js/submit-sign.js"></script>
339   -<script src="{{ server }}/assets/js/facial.js"></script>
340   -<script src="{{ server }}/assets/js/movement.js"></script>
341   -<script src="{{ server }}/assets/js/articulation.js"></script>
342   -<script src="{{ server }}/assets/js/configuration.js"></script>
343   -<script src="{{ server }}/assets/js/orientation.js"></script>
344   -<script src="{{ server }}/assets/js/defaultConfigurationHandler.js"></script>
345   -<script src="{{ server }}/assets/js/dynamic-loading-engine.js"></script>
346   -<script src="{{ server }}/assets/js/dynamic-selection-workflow.js"></script>
347   -<script src="{{ server }}/assets/js/tmpJSONParser.js"></script>
  356 +<script src="{{ server }}/assets/js/configuration-screen.js"></script>
  357 +<script src="{{ server }}/assets/js/render-sign.js"></script>
348 358 <script src="{{ server }}/assets/js/wikilibras.js"></script>
349 359  
350 360 <script type="text/javascript">
... ...