@@ -33,6 +33,7 @@ class RequestBuilder {
33
33
fetchOptions . headers = {
34
34
Accept : 'application/vnd.live-component+html' ,
35
35
'X-Requested-With' : 'XMLHttpRequest' ,
36
+ 'X-Live-Url' : window . location . pathname + window . location . search ,
36
37
} ;
37
38
const totalFiles = Object . entries ( files ) . reduce ( ( total , current ) => total + current . length , 0 ) ;
38
39
const hasFingerprints = Object . keys ( children ) . length > 0 ;
@@ -111,6 +112,12 @@ class BackendResponse {
111
112
}
112
113
return this . body ;
113
114
}
115
+ getLiveUrl ( ) {
116
+ if ( undefined === this . liveUrl ) {
117
+ this . liveUrl = this . response . headers . get ( 'X-Live-Url' ) ;
118
+ }
119
+ return this . liveUrl ;
120
+ }
114
121
}
115
122
116
123
function getElementAsTagText ( element ) {
@@ -2146,6 +2153,10 @@ class Component {
2146
2153
return response ;
2147
2154
}
2148
2155
this . processRerender ( html , backendResponse ) ;
2156
+ const liveUrl = backendResponse . getLiveUrl ( ) ;
2157
+ if ( liveUrl ) {
2158
+ history . replaceState ( history . state , '' , new URL ( liveUrl + window . location . hash , window . location . origin ) ) ;
2159
+ }
2149
2160
this . backendRequest = null ;
2150
2161
thisPromiseResolve ( backendResponse ) ;
2151
2162
if ( this . isRequestPending ) {
@@ -2770,129 +2781,6 @@ class PollingPlugin {
2770
2781
}
2771
2782
}
2772
2783
2773
- function isValueEmpty ( value ) {
2774
- if ( null === value || value === '' || undefined === value || ( Array . isArray ( value ) && value . length === 0 ) ) {
2775
- return true ;
2776
- }
2777
- if ( typeof value !== 'object' ) {
2778
- return false ;
2779
- }
2780
- for ( const key of Object . keys ( value ) ) {
2781
- if ( ! isValueEmpty ( value [ key ] ) ) {
2782
- return false ;
2783
- }
2784
- }
2785
- return true ;
2786
- }
2787
- function toQueryString ( data ) {
2788
- const buildQueryStringEntries = ( data , entries = { } , baseKey = '' ) => {
2789
- Object . entries ( data ) . forEach ( ( [ iKey , iValue ] ) => {
2790
- const key = baseKey === '' ? iKey : `${ baseKey } [${ iKey } ]` ;
2791
- if ( '' === baseKey && isValueEmpty ( iValue ) ) {
2792
- entries [ key ] = '' ;
2793
- }
2794
- else if ( null !== iValue ) {
2795
- if ( typeof iValue === 'object' ) {
2796
- entries = { ...entries , ...buildQueryStringEntries ( iValue , entries , key ) } ;
2797
- }
2798
- else {
2799
- entries [ key ] = encodeURIComponent ( iValue )
2800
- . replace ( / % 2 0 / g, '+' )
2801
- . replace ( / % 2 C / g, ',' ) ;
2802
- }
2803
- }
2804
- } ) ;
2805
- return entries ;
2806
- } ;
2807
- const entries = buildQueryStringEntries ( data ) ;
2808
- return Object . entries ( entries )
2809
- . map ( ( [ key , value ] ) => `${ key } =${ value } ` )
2810
- . join ( '&' ) ;
2811
- }
2812
- function fromQueryString ( search ) {
2813
- search = search . replace ( '?' , '' ) ;
2814
- if ( search === '' )
2815
- return { } ;
2816
- const insertDotNotatedValueIntoData = ( key , value , data ) => {
2817
- const [ first , second , ...rest ] = key . split ( '.' ) ;
2818
- if ( ! second ) {
2819
- data [ key ] = value ;
2820
- return value ;
2821
- }
2822
- if ( data [ first ] === undefined ) {
2823
- data [ first ] = Number . isNaN ( Number . parseInt ( second ) ) ? { } : [ ] ;
2824
- }
2825
- insertDotNotatedValueIntoData ( [ second , ...rest ] . join ( '.' ) , value , data [ first ] ) ;
2826
- } ;
2827
- const entries = search . split ( '&' ) . map ( ( i ) => i . split ( '=' ) ) ;
2828
- const data = { } ;
2829
- entries . forEach ( ( [ key , value ] ) => {
2830
- value = decodeURIComponent ( String ( value || '' ) . replace ( / \+ / g, '%20' ) ) ;
2831
- if ( ! key . includes ( '[' ) ) {
2832
- data [ key ] = value ;
2833
- }
2834
- else {
2835
- if ( '' === value )
2836
- return ;
2837
- const dotNotatedKey = key . replace ( / \[ / g, '.' ) . replace ( / ] / g, '' ) ;
2838
- insertDotNotatedValueIntoData ( dotNotatedKey , value , data ) ;
2839
- }
2840
- } ) ;
2841
- return data ;
2842
- }
2843
- class UrlUtils extends URL {
2844
- has ( key ) {
2845
- const data = this . getData ( ) ;
2846
- return Object . keys ( data ) . includes ( key ) ;
2847
- }
2848
- set ( key , value ) {
2849
- const data = this . getData ( ) ;
2850
- data [ key ] = value ;
2851
- this . setData ( data ) ;
2852
- }
2853
- get ( key ) {
2854
- return this . getData ( ) [ key ] ;
2855
- }
2856
- remove ( key ) {
2857
- const data = this . getData ( ) ;
2858
- delete data [ key ] ;
2859
- this . setData ( data ) ;
2860
- }
2861
- getData ( ) {
2862
- if ( ! this . search ) {
2863
- return { } ;
2864
- }
2865
- return fromQueryString ( this . search ) ;
2866
- }
2867
- setData ( data ) {
2868
- this . search = toQueryString ( data ) ;
2869
- }
2870
- }
2871
- class HistoryStrategy {
2872
- static replace ( url ) {
2873
- history . replaceState ( history . state , '' , url ) ;
2874
- }
2875
- }
2876
-
2877
- class QueryStringPlugin {
2878
- constructor ( mapping ) {
2879
- this . mapping = mapping ;
2880
- }
2881
- attachToComponent ( component ) {
2882
- component . on ( 'render:finished' , ( component ) => {
2883
- const urlUtils = new UrlUtils ( window . location . href ) ;
2884
- const currentUrl = urlUtils . toString ( ) ;
2885
- Object . entries ( this . mapping ) . forEach ( ( [ prop , mapping ] ) => {
2886
- const value = component . valueStore . get ( prop ) ;
2887
- urlUtils . set ( mapping . name , value ) ;
2888
- } ) ;
2889
- if ( currentUrl !== urlUtils . toString ( ) ) {
2890
- HistoryStrategy . replace ( urlUtils ) ;
2891
- }
2892
- } ) ;
2893
- }
2894
- }
2895
-
2896
2784
class SetValueOntoModelFieldsPlugin {
2897
2785
attachToComponent ( component ) {
2898
2786
this . synchronizeValueOfModelFields ( component ) ;
@@ -3102,7 +2990,6 @@ class LiveControllerDefault extends Controller {
3102
2990
new PageUnloadingPlugin ( ) ,
3103
2991
new PollingPlugin ( ) ,
3104
2992
new SetValueOntoModelFieldsPlugin ( ) ,
3105
- new QueryStringPlugin ( this . queryMappingValue ) ,
3106
2993
new ChildComponentPlugin ( this . component ) ,
3107
2994
] ;
3108
2995
plugins . forEach ( ( plugin ) => {
@@ -3233,7 +3120,6 @@ LiveControllerDefault.values = {
3233
3120
debounce : { type : Number , default : 150 } ,
3234
3121
fingerprint : { type : String , default : '' } ,
3235
3122
requestMethod : { type : String , default : 'post' } ,
3236
- queryMapping : { type : Object , default : { } } ,
3237
3123
} ;
3238
3124
LiveControllerDefault . backendFactory = ( controller ) => new Backend ( controller . urlValue , controller . requestMethodValue ) ;
3239
3125
0 commit comments