mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Fix date rendering by adding <gitea-absolute-date> (#29725)
				
					
				
			Alternative to: https://github.com/go-gitea/gitea/pull/29698 Fixes: https://github.com/go-gitea/gitea/issues/29034 <img width="278" alt="image" src="https://github.com/go-gitea/gitea/assets/115237/12ecd967-2723-410d-8a28-a1b0f41b7bba"> It also fixes a secondary issue that we were showing timestamp tooltips over date, which makes no sense, so these are now gone as well: <img width="284" alt="image" src="https://github.com/go-gitea/gitea/assets/115237/a70432f3-97b6-41e6-b202-b53b76924a66">
This commit is contained in:
		| @@ -51,18 +51,16 @@ func DateTime(format string, datetime any, extraAttrs ...string) template.HTML { | ||||
|  | ||||
| 	attrs := make([]string, 0, 10+len(extraAttrs)) | ||||
| 	attrs = append(attrs, extraAttrs...) | ||||
| 	attrs = append(attrs, `data-tooltip-content`, `data-tooltip-interactive="true"`) | ||||
| 	attrs = append(attrs, `format="datetime"`, `weekday=""`, `year="numeric"`) | ||||
| 	attrs = append(attrs, `weekday=""`, `year="numeric"`) | ||||
|  | ||||
| 	switch format { | ||||
| 	case "short": | ||||
| 		attrs = append(attrs, `month="short"`, `day="numeric"`) | ||||
| 	case "long": | ||||
| 		attrs = append(attrs, `month="long"`, `day="numeric"`) | ||||
| 	case "full": | ||||
| 		attrs = append(attrs, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`) | ||||
| 	case "short", "long": // date only | ||||
| 		attrs = append(attrs, `month="`+format+`"`, `day="numeric"`) | ||||
| 		return template.HTML(fmt.Sprintf(`<gitea-absolute-date %s date="%s">%s</gitea-absolute-date>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) | ||||
| 	case "full": // full date including time | ||||
| 		attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`) | ||||
| 		return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) | ||||
| 	default: | ||||
| 		panic(fmt.Sprintf("Unsupported format %s", format)) | ||||
| 	} | ||||
| 	return template.HTML(fmt.Sprintf(`<relative-time %s datetime="%s">%s</relative-time>`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) | ||||
| } | ||||
|   | ||||
| @@ -18,6 +18,7 @@ func TestDateTime(t *testing.T) { | ||||
| 	defer test.MockVariableValue(&setting.DefaultUILocation, testTz)() | ||||
|  | ||||
| 	refTimeStr := "2018-01-01T00:00:00Z" | ||||
| 	refDateStr := "2018-01-01" | ||||
| 	refTime, _ := time.Parse(time.RFC3339, refTimeStr) | ||||
| 	refTimeStamp := TimeStamp(refTime.Unix()) | ||||
|  | ||||
| @@ -27,17 +28,20 @@ func TestDateTime(t *testing.T) { | ||||
| 	assert.EqualValues(t, "-", DateTime("short", TimeStamp(0))) | ||||
|  | ||||
| 	actual := DateTime("short", "invalid") | ||||
| 	assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="invalid">invalid</relative-time>`, actual) | ||||
| 	assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="invalid">invalid</gitea-absolute-date>`, actual) | ||||
|  | ||||
| 	actual = DateTime("short", refTimeStr) | ||||
| 	assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</relative-time>`, actual) | ||||
| 	assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01T00:00:00Z</gitea-absolute-date>`, actual) | ||||
|  | ||||
| 	actual = DateTime("short", refTime) | ||||
| 	assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2018-01-01T00:00:00Z">2018-01-01</relative-time>`, actual) | ||||
| 	assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01T00:00:00Z">2018-01-01</gitea-absolute-date>`, actual) | ||||
|  | ||||
| 	actual = DateTime("short", refDateStr) | ||||
| 	assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2018-01-01">2018-01-01</gitea-absolute-date>`, actual) | ||||
|  | ||||
| 	actual = DateTime("short", refTimeStamp) | ||||
| 	assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" datetime="2017-12-31T19:00:00-05:00">2017-12-31</relative-time>`, actual) | ||||
| 	assert.EqualValues(t, `<gitea-absolute-date weekday="" year="numeric" month="short" day="numeric" date="2017-12-31T19:00:00-05:00">2017-12-31</gitea-absolute-date>`, actual) | ||||
|  | ||||
| 	actual = DateTime("full", refTimeStamp) | ||||
| 	assert.EqualValues(t, `<relative-time data-tooltip-content data-tooltip-interactive="true" format="datetime" weekday="" year="numeric" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual) | ||||
| 	assert.EqualValues(t, `<relative-time weekday="" year="numeric" format="datetime" month="short" day="numeric" hour="numeric" minute="numeric" second="numeric" data-tooltip-content data-tooltip-interactive="true" datetime="2017-12-31T19:00:00-05:00">2017-12-31 19:00:00 -05:00</relative-time>`, actual) | ||||
| } | ||||
|   | ||||
| @@ -110,6 +110,16 @@ | ||||
| 		<div><gitea-origin-url data-url="/test/url"></gitea-origin-url></div> | ||||
| 	</div> | ||||
|  | ||||
| 	<div> | ||||
| 		<h1>GiteaAbsoluteDate</h1> | ||||
| 		<div><gitea-absolute-date date="2024-03-11" year="numeric" day="numeric" month="short"></gitea-absolute-date></div> | ||||
| 		<div><gitea-absolute-date date="2024-03-11" year="numeric" day="numeric" month="long"></gitea-absolute-date></div> | ||||
| 		<div><gitea-absolute-date date="2024-03-11" year="" day="numeric" month="numeric"></gitea-absolute-date></div> | ||||
| 		<div><gitea-absolute-date date="2024-03-11" year="" day="numeric" month="numeric" weekday="long"></gitea-absolute-date></div> | ||||
| 		<div><gitea-absolute-date date="2024-03-11T19:00:00-05:00" year="" day="numeric" month="numeric" weekday="long"></gitea-absolute-date></div> | ||||
| 		<div class="tw-text-text-light-2">relative-time: <relative-time format="datetime" datetime="2024-03-11" year="" day="numeric" month="numeric"></relative-time></div> | ||||
| 	</div> | ||||
|  | ||||
| 	<div> | ||||
| 		<h1>LocaleNumber</h1> | ||||
| 		<div>{{ctx.Locale.PrettyNumber 1}}</div> | ||||
|   | ||||
							
								
								
									
										40
									
								
								web_src/js/webcomponents/GiteaAbsoluteDate.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								web_src/js/webcomponents/GiteaAbsoluteDate.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| window.customElements.define('gitea-absolute-date', class extends HTMLElement { | ||||
|   static observedAttributes = ['date', 'year', 'month', 'weekday', 'day']; | ||||
|  | ||||
|   update = () => { | ||||
|     const year = this.getAttribute('year') ?? ''; | ||||
|     const month = this.getAttribute('month') ?? ''; | ||||
|     const weekday = this.getAttribute('weekday') ?? ''; | ||||
|     const day = this.getAttribute('day') ?? ''; | ||||
|     const lang = this.closest('[lang]')?.getAttribute('lang') || | ||||
|       this.ownerDocument.documentElement.getAttribute('lang') || | ||||
|       ''; | ||||
|  | ||||
|     // only extract the `yyyy-mm-dd` part. When converting to Date, it will become midnight UTC and when rendered | ||||
|     // as localized date, will have a offset towards UTC, which we remove to shift the timestamp to midnight in the | ||||
|     // localized date. We should eventually use `Temporal.PlainDate` which will make the correction unnecessary. | ||||
|     // - https://stackoverflow.com/a/14569783/808699 | ||||
|     // - https://tc39.es/proposal-temporal/docs/plaindate.html | ||||
|     const date = new Date(this.getAttribute('date').substring(0, 10)); | ||||
|     const correctedDate = new Date(date.getTime() - date.getTimezoneOffset() * -60000); | ||||
|  | ||||
|     if (!this.shadowRoot) this.attachShadow({mode: 'open'}); | ||||
|     this.shadowRoot.textContent = correctedDate.toLocaleString(lang ?? [], { | ||||
|       ...(year && {year}), | ||||
|       ...(month && {month}), | ||||
|       ...(weekday && {weekday}), | ||||
|       ...(day && {day}), | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   attributeChangedCallback(_name, oldValue, newValue) { | ||||
|     if (!this.initialized || oldValue === newValue) return; | ||||
|     this.update(); | ||||
|   } | ||||
|  | ||||
|   connectedCallback() { | ||||
|     this.initialized = false; | ||||
|     this.update(); | ||||
|     this.initialized = true; | ||||
|   } | ||||
| }); | ||||
| @@ -3,3 +3,4 @@ import './polyfill.js'; | ||||
|  | ||||
| import '@github/relative-time-element'; | ||||
| import './GiteaOriginUrl.js'; | ||||
| import './GiteaAbsoluteDate.js'; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user