@@ -33,7 +33,7 @@ class RequestBuilder {
3333 fetchOptions . headers = {
3434 Accept : 'application/vnd.live-component+html' ,
3535 'X-Requested-With' : 'XMLHttpRequest' ,
36- 'X-Live-Url' : window . location . pathname + window . location . search
36+ 'X-Live-Url' : window . location . pathname + window . location . search ,
3737 } ;
3838 const totalFiles = Object . entries ( files ) . reduce ( ( total , current ) => total + current . length , 0 ) ;
3939 const hasFingerprints = Object . keys ( children ) . length > 0 ;
@@ -1797,6 +1797,110 @@ function executeMorphdom(rootFromElement, rootToElement, modifiedFieldElements,
17971797 } ) ;
17981798}
17991799
1800+ function isValueEmpty ( value ) {
1801+ if ( null === value || value === '' || undefined === value || ( Array . isArray ( value ) && value . length === 0 ) ) {
1802+ return true ;
1803+ }
1804+ if ( typeof value !== 'object' ) {
1805+ return false ;
1806+ }
1807+ for ( const key of Object . keys ( value ) ) {
1808+ if ( ! isValueEmpty ( value [ key ] ) ) {
1809+ return false ;
1810+ }
1811+ }
1812+ return true ;
1813+ }
1814+ function toQueryString ( data ) {
1815+ const buildQueryStringEntries = ( data , entries = { } , baseKey = '' ) => {
1816+ Object . entries ( data ) . forEach ( ( [ iKey , iValue ] ) => {
1817+ const key = baseKey === '' ? iKey : `${ baseKey } [${ iKey } ]` ;
1818+ if ( '' === baseKey && isValueEmpty ( iValue ) ) {
1819+ entries [ key ] = '' ;
1820+ }
1821+ else if ( null !== iValue ) {
1822+ if ( typeof iValue === 'object' ) {
1823+ entries = { ...entries , ...buildQueryStringEntries ( iValue , entries , key ) } ;
1824+ }
1825+ else {
1826+ entries [ key ] = encodeURIComponent ( iValue )
1827+ . replace ( / % 2 0 / g, '+' )
1828+ . replace ( / % 2 C / g, ',' ) ;
1829+ }
1830+ }
1831+ } ) ;
1832+ return entries ;
1833+ } ;
1834+ const entries = buildQueryStringEntries ( data ) ;
1835+ return Object . entries ( entries )
1836+ . map ( ( [ key , value ] ) => `${ key } =${ value } ` )
1837+ . join ( '&' ) ;
1838+ }
1839+ function fromQueryString ( search ) {
1840+ search = search . replace ( '?' , '' ) ;
1841+ if ( search === '' )
1842+ return { } ;
1843+ const insertDotNotatedValueIntoData = ( key , value , data ) => {
1844+ const [ first , second , ...rest ] = key . split ( '.' ) ;
1845+ if ( ! second ) {
1846+ data [ key ] = value ;
1847+ return value ;
1848+ }
1849+ if ( data [ first ] === undefined ) {
1850+ data [ first ] = Number . isNaN ( Number . parseInt ( second ) ) ? { } : [ ] ;
1851+ }
1852+ insertDotNotatedValueIntoData ( [ second , ...rest ] . join ( '.' ) , value , data [ first ] ) ;
1853+ } ;
1854+ const entries = search . split ( '&' ) . map ( ( i ) => i . split ( '=' ) ) ;
1855+ const data = { } ;
1856+ entries . forEach ( ( [ key , value ] ) => {
1857+ value = decodeURIComponent ( value . replace ( / \+ / g, '%20' ) ) ;
1858+ if ( ! key . includes ( '[' ) ) {
1859+ data [ key ] = value ;
1860+ }
1861+ else {
1862+ if ( '' === value )
1863+ return ;
1864+ const dotNotatedKey = key . replace ( / \[ / g, '.' ) . replace ( / ] / g, '' ) ;
1865+ insertDotNotatedValueIntoData ( dotNotatedKey , value , data ) ;
1866+ }
1867+ } ) ;
1868+ return data ;
1869+ }
1870+ class UrlUtils extends URL {
1871+ has ( key ) {
1872+ const data = this . getData ( ) ;
1873+ return Object . keys ( data ) . includes ( key ) ;
1874+ }
1875+ set ( key , value ) {
1876+ const data = this . getData ( ) ;
1877+ data [ key ] = value ;
1878+ this . setData ( data ) ;
1879+ }
1880+ get ( key ) {
1881+ return this . getData ( ) [ key ] ;
1882+ }
1883+ remove ( key ) {
1884+ const data = this . getData ( ) ;
1885+ delete data [ key ] ;
1886+ this . setData ( data ) ;
1887+ }
1888+ getData ( ) {
1889+ if ( ! this . search ) {
1890+ return { } ;
1891+ }
1892+ return fromQueryString ( this . search ) ;
1893+ }
1894+ setData ( data ) {
1895+ this . search = toQueryString ( data ) ;
1896+ }
1897+ }
1898+ class HistoryStrategy {
1899+ static replace ( url ) {
1900+ history . replaceState ( history . state , '' , url ) ;
1901+ }
1902+ }
1903+
18001904class UnsyncedInputsTracker {
18011905 constructor ( component , modelElementResolver ) {
18021906 this . elementEventListeners = [
@@ -1975,110 +2079,6 @@ class ValueStore {
19752079 }
19762080}
19772081
1978- function isValueEmpty ( value ) {
1979- if ( null === value || value === '' || undefined === value || ( Array . isArray ( value ) && value . length === 0 ) ) {
1980- return true ;
1981- }
1982- if ( typeof value !== 'object' ) {
1983- return false ;
1984- }
1985- for ( const key of Object . keys ( value ) ) {
1986- if ( ! isValueEmpty ( value [ key ] ) ) {
1987- return false ;
1988- }
1989- }
1990- return true ;
1991- }
1992- function toQueryString ( data ) {
1993- const buildQueryStringEntries = ( data , entries = { } , baseKey = '' ) => {
1994- Object . entries ( data ) . forEach ( ( [ iKey , iValue ] ) => {
1995- const key = baseKey === '' ? iKey : `${ baseKey } [${ iKey } ]` ;
1996- if ( '' === baseKey && isValueEmpty ( iValue ) ) {
1997- entries [ key ] = '' ;
1998- }
1999- else if ( null !== iValue ) {
2000- if ( typeof iValue === 'object' ) {
2001- entries = { ...entries , ...buildQueryStringEntries ( iValue , entries , key ) } ;
2002- }
2003- else {
2004- entries [ key ] = encodeURIComponent ( iValue )
2005- . replace ( / % 2 0 / g, '+' )
2006- . replace ( / % 2 C / g, ',' ) ;
2007- }
2008- }
2009- } ) ;
2010- return entries ;
2011- } ;
2012- const entries = buildQueryStringEntries ( data ) ;
2013- return Object . entries ( entries )
2014- . map ( ( [ key , value ] ) => `${ key } =${ value } ` )
2015- . join ( '&' ) ;
2016- }
2017- function fromQueryString ( search ) {
2018- search = search . replace ( '?' , '' ) ;
2019- if ( search === '' )
2020- return { } ;
2021- const insertDotNotatedValueIntoData = ( key , value , data ) => {
2022- const [ first , second , ...rest ] = key . split ( '.' ) ;
2023- if ( ! second ) {
2024- data [ key ] = value ;
2025- return value ;
2026- }
2027- if ( data [ first ] === undefined ) {
2028- data [ first ] = Number . isNaN ( Number . parseInt ( second ) ) ? { } : [ ] ;
2029- }
2030- insertDotNotatedValueIntoData ( [ second , ...rest ] . join ( '.' ) , value , data [ first ] ) ;
2031- } ;
2032- const entries = search . split ( '&' ) . map ( ( i ) => i . split ( '=' ) ) ;
2033- const data = { } ;
2034- entries . forEach ( ( [ key , value ] ) => {
2035- value = decodeURIComponent ( value . replace ( / \+ / g, '%20' ) ) ;
2036- if ( ! key . includes ( '[' ) ) {
2037- data [ key ] = value ;
2038- }
2039- else {
2040- if ( '' === value )
2041- return ;
2042- const dotNotatedKey = key . replace ( / \[ / g, '.' ) . replace ( / ] / g, '' ) ;
2043- insertDotNotatedValueIntoData ( dotNotatedKey , value , data ) ;
2044- }
2045- } ) ;
2046- return data ;
2047- }
2048- class UrlUtils extends URL {
2049- has ( key ) {
2050- const data = this . getData ( ) ;
2051- return Object . keys ( data ) . includes ( key ) ;
2052- }
2053- set ( key , value ) {
2054- const data = this . getData ( ) ;
2055- data [ key ] = value ;
2056- this . setData ( data ) ;
2057- }
2058- get ( key ) {
2059- return this . getData ( ) [ key ] ;
2060- }
2061- remove ( key ) {
2062- const data = this . getData ( ) ;
2063- delete data [ key ] ;
2064- this . setData ( data ) ;
2065- }
2066- getData ( ) {
2067- if ( ! this . search ) {
2068- return { } ;
2069- }
2070- return fromQueryString ( this . search ) ;
2071- }
2072- setData ( data ) {
2073- this . search = toQueryString ( data ) ;
2074- }
2075- }
2076- class HistoryStrategy {
2077- static replace ( url ) {
2078- history . replaceState ( history . state , '' , url ) ;
2079- }
2080- }
2081-
20822082class Component {
20832083 constructor ( element , name , props , listeners , id , backend , elementDriver ) {
20842084 this . fingerprint = '' ;
@@ -2856,25 +2856,6 @@ class PollingPlugin {
28562856 }
28572857}
28582858
2859- class QueryStringPlugin {
2860- constructor ( mapping ) {
2861- this . mapping = mapping ;
2862- }
2863- attachToComponent ( component ) {
2864- component . on ( 'render:finished' , ( component ) => {
2865- const urlUtils = new UrlUtils ( window . location . href ) ;
2866- const currentUrl = urlUtils . toString ( ) ;
2867- Object . entries ( this . mapping ) . forEach ( ( [ prop , mapping ] ) => {
2868- const value = component . valueStore . get ( prop ) ;
2869- urlUtils . set ( mapping . name , value ) ;
2870- } ) ;
2871- if ( currentUrl !== urlUtils . toString ( ) ) {
2872- HistoryStrategy . replace ( new UrlUtils ( currentUrl ) ) ;
2873- }
2874- } ) ;
2875- }
2876- }
2877-
28782859class SetValueOntoModelFieldsPlugin {
28792860 attachToComponent ( component ) {
28802861 this . synchronizeValueOfModelFields ( component ) ;
@@ -3084,7 +3065,6 @@ class LiveControllerDefault extends Controller {
30843065 new PageUnloadingPlugin ( ) ,
30853066 new PollingPlugin ( ) ,
30863067 new SetValueOntoModelFieldsPlugin ( ) ,
3087- new QueryStringPlugin ( this . queryMappingValue ) ,
30883068 new ChildComponentPlugin ( this . component ) ,
30893069 ] ;
30903070 plugins . forEach ( ( plugin ) => {
@@ -3194,7 +3174,6 @@ LiveControllerDefault.values = {
31943174 debounce : { type : Number , default : 150 } ,
31953175 fingerprint : { type : String , default : '' } ,
31963176 requestMethod : { type : String , default : 'post' } ,
3197- queryMapping : { type : Object , default : { } } ,
31983177} ;
31993178LiveControllerDefault . backendFactory = ( controller ) => new Backend ( controller . urlValue , controller . requestMethodValue ) ;
32003179
0 commit comments