/** * @requires javelin-stratcom * javelin-request * javelin-dom * javelin-vector * javelin-install * javelin-util * javelin-mask * javelin-uri * javelin-routable * @provides javelin-workflow * @javelin */ JX.install('Workflow', { construct : function(uri, data) { if (__DEV__) { if (!uri || uri == '#') { JX.$E( 'new JX.Workflow(, ...): '+ 'bogus URI provided when creating workflow.'); } } this.setURI(uri); this.setData(data || {}); }, events : ['error', 'finally', 'submit', 'start'], statics : { _stack : [], newFromForm : function(form, data, keep_enabled) { var pairs = JX.DOM.convertFormToListOfPairs(form); for (var k in data) { pairs.push([k, data[k]]); } var inputs; if (keep_enabled) { inputs = []; } else { // Disable form elements during the request inputs = [].concat( JX.DOM.scry(form, 'input'), JX.DOM.scry(form, 'button'), JX.DOM.scry(form, 'textarea')); for (var ii = 0; ii < inputs.length; ii++) { if (inputs[ii].disabled) { delete inputs[ii]; } else { inputs[ii].disabled = true; } } } var workflow = new JX.Workflow(form.getAttribute('action'), {}); workflow._form = form; workflow.setDataWithListOfPairs(pairs); workflow.setMethod(form.getAttribute('method')); var onfinally = JX.bind(workflow, function() { if (!this._keepControlsDisabled) { for (var ii = 0; ii < inputs.length; ii++) { inputs[ii] && (inputs[ii].disabled = false); } } }); workflow.listen('finally', onfinally); return workflow; }, newFromLink : function(link) { var workflow = new JX.Workflow(link.href); return workflow; }, _push : function(workflow) { JX.Mask.show(); JX.Workflow._stack.push(workflow); }, _pop : function() { var dialog = JX.Workflow._stack.pop(); (dialog.getCloseHandler() || JX.bag)(); dialog._destroy(); JX.Mask.hide(); }, _onlink: function(event) { // See T13302. When a user clicks a link in a dialog and that link // triggers a navigation event, we want to close the dialog as though // they had pressed a button. // When Quicksand is enabled, this is particularly relevant because // the dialog will stay in the foreground while the page content changes // in the background if we do not dismiss the dialog. // If this is a Command-Click, the link will open in a new window. var is_command = !!event.getRawEvent().metaKey; if (is_command) { return; } var link = event.getNode('tag:a'); // If the link is an anchor, or does not go anywhere, ignore the event. var href = link.getAttribute('href'); if (typeof href !== 'string') { return; } if (!href.length || href[0] === '#') { return; } // This link will open in a new window. if (link.target === '_blank') { return; } // This link is really a dialog button which we'll handle elsewhere. if (JX.Stratcom.hasSigil(link, 'jx-workflow-button')) { return; } // Close the dialog. JX.Workflow._pop(); }, _onbutton : function(event) { if (JX.Stratcom.pass()) { return; } // Get the button (which is sometimes actually another tag, like an ) // which triggered the event. In particular, this makes sure we get the // right node if there is a