UNPKG

jsf.js_next_gen

Version:

A next generation typescript reimplementation of jsf.js

163 lines 6.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XhrFormData = void 0; /*! Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to you under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const mona_dish_1 = require("mona-dish"); const Const_1 = require("../core/Const"); const FileUtils_1 = require("../util/FileUtils"); const Lang_1 = require("../util/Lang"); var ofAssoc = Lang_1.ExtLang.ofAssoc; const mona_dish_2 = require("mona-dish"); const defaultParamsMapper = (key, item) => [key, item]; /** * A unified form data class * which builds upon our configuration. * * We cannot use standard html5 forms everywhere * due to api constraints on the HTML Form object in IE11 * and due to the url encoding constraint given by the faces.js spec * * * internal storage format * every value is stored as an array * even scalar ones! */ class XhrFormData extends mona_dish_1.Config { /** * data collector from a given form * * @param dataSource either a form as DomQuery object or an encoded url string * @param paramsMapper a remapper for the params keys and values * @param executes the executes id list for the elements to being processed * @param partialIds partial ids to collect, to reduce the data sent down */ constructor(dataSource, paramsMapper = defaultParamsMapper, executes, partialIds) { super({}); this.dataSource = dataSource; this.paramsMapper = paramsMapper; this.partialIds = partialIds; /** * Checks if the given datasource is a multipart request source * multipart is only needed if one of the executes is a file input * since file inputs are stateless, they fall out of the view state * and need special handling. With file submits we have to send a formData object * instead of an encoded string files cannot be sent that way */ this.isMultipartRequest = false; //encode and append the issuing item if not a partial ids array of ids is passed /* * Spec. 13.3.1 * Collect and encode input elements. * Additionally the hidden element jakarta.faces.ViewState * Enhancement partial page submit */ this.resolveRequestType(this.dataSource, executes); this.encodeSubmittableFields(this.dataSource, this.partialIds); this.applyViewState(this.dataSource); } /** * @returns a Form data representation, this is needed for file submits */ toFormData() { /* * expands key: [item1, item2] * to: [{key: key, value: item1}, {key: key, value: item2}] */ let expandValueArrays = ([key, item]) => { if (Array.isArray(item)) { return new mona_dish_2.Es2019Array(...item).map(value => { return { key, value }; }); } return [{ key, value: item }]; }; /* * remaps the incoming {key, value} tuples * to naming container prefixed keys and values */ let remapForNamingContainer = ({ key, value }) => { key = this.remapKeyForNamingContainer(key); return { key, value }; }; /* * collects everything into a FormData object */ return ofAssoc(this.value) .flatMap(expandValueArrays) .map(remapForNamingContainer) .reduce((formData, { key, value }) => { formData.append(key, value); return formData; }, new FormData()); } /** * returns an encoded string representation of our xhr form data * * @param defaultStr optional default value if nothing is there to encode */ toString(defaultStr = Const_1.EMPTY_STR) { return (0, FileUtils_1.encodeFormData)(this, this.paramsMapper, defaultStr); } /** * generic post init code, for now, this performs some post assign data post-processing * @param rootElement the root element which knows the request type (usually a form) * @param executes the executable dom nodes which need to be processed into the form data, which we can send * in our ajax request */ resolveRequestType(rootElement, executes) { if (!executes || executes.indexOf(Const_1.IDENT_NONE) != -1) { return; } this.isMultipartRequest = rootElement.isMultipartCandidate(true); } /** * special case view state handling * * @param form the form holding the view state value */ applyViewState(form) { if (this.getIf((0, Const_1.$nsp)(Const_1.P_VIEWSTATE)).isPresent()) { return; } let viewStateElement = form.querySelectorAllDeep(`[name*='${(0, Const_1.$nsp)(Const_1.P_VIEWSTATE)}'`); let viewState = viewStateElement.inputValue; this.appendIf(viewState.isPresent(), this.remapKeyForNamingContainer(viewStateElement.name.value)).value = viewState.value; } /** * determines fields to submit * @param {Node} parentItem - form element item is nested in * @param {Array} partialIds - ids fo PPS */ encodeSubmittableFields(parentItem, partialIds = []) { const mergeIntoThis = ([key, value]) => this.append(key).value = value; const namingContainerRemap = ([key, value]) => this.paramsMapper(key, value); const remappedPartialIds = partialIds.map(partialId => this.remapKeyForNamingContainer(partialId)); const partialIdsFilter = ([key, value]) => (!remappedPartialIds.length || key.indexOf("@") == 0) ? true : remappedPartialIds.indexOf(key) != -1; let inputs = (0, FileUtils_1.getFormInputsAsArr)(parentItem); inputs .map(FileUtils_1.fixEmptyParameters) .map(namingContainerRemap) .filter(partialIdsFilter) .forEach(mergeIntoThis); } remapKeyForNamingContainer(key) { return this.paramsMapper(key, "")[0]; } } exports.XhrFormData = XhrFormData; //# sourceMappingURL=XhrFormData.js.map