-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from spilpind/intial_logic
Intial logic
- Loading branch information
Showing
41 changed files
with
1,897 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#Taken from here: https://github.com/Kotlin/kmm-sample/blob/master/.gitignore | ||
|
||
*.iml | ||
.gradle/ | ||
build/ | ||
.idea/ | ||
.DS_STORE | ||
local.properties |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
allprojects { | ||
repositories { | ||
mavenCentral() | ||
maven { setUrl("https://kotlin.bintray.com/kotlinx/") } | ||
maven { setUrl("https://dl.bintray.com/kotlin/kotlin-js-wrappers") } | ||
} | ||
} | ||
|
||
plugins { | ||
kotlin("multiplatform") version "1.4.32" apply false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
plugins { | ||
kotlin("js") | ||
} | ||
|
||
dependencies { | ||
implementation(project(":common")) | ||
|
||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.1.1") | ||
} | ||
|
||
kotlin { | ||
js(LEGACY) { | ||
browser{ | ||
commonWebpackConfig{ | ||
outputFileName = "stick-calendar.js" | ||
} | ||
} | ||
binaries.executable() | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import dk.spilpind.stickcalendar.StickCalendar.toStickDate | ||
import kotlinx.datetime.* | ||
import org.w3c.dom.* | ||
|
||
/** | ||
* Replaces all gregorian dates of [document] by with their corresponding stick date. Any dates added later to the | ||
* document are also replaced, this is done by the observing relevant mutations | ||
*/ | ||
class DomDateReplacer(private val document: Document) { | ||
|
||
private val mutationObserverOptions = MutationObserverInit( | ||
subtree = true, | ||
childList = true, | ||
attributes = true, | ||
attributeFilter = arrayOf("style"), | ||
attributeOldValue = true, | ||
characterData = true, | ||
) | ||
|
||
private val mutationObserver = MutationObserver { mutations, _ -> | ||
mutations.forEach { mutationRecord -> | ||
handleMutation(mutationRecord) | ||
} | ||
} | ||
|
||
init { | ||
mutationObserver.observe(document, mutationObserverOptions) | ||
|
||
replaceDatesInTree(document) | ||
} | ||
|
||
private fun handleMutation(mutationRecord: MutationRecord) { | ||
if (mutationRecord.type == "childlist") { | ||
val nodes = mutationRecord.addedNodes | ||
for (index in 0.until(nodes.length)) { | ||
nodes[index]?.let { node -> | ||
replaceDatesInTree(node) | ||
} | ||
} | ||
|
||
return | ||
} | ||
|
||
val element = mutationRecord.target as? HTMLElement | ||
if (element?.style?.display == "none") { | ||
return | ||
} | ||
|
||
replaceDatesInTree(mutationRecord.target) | ||
} | ||
|
||
private fun replaceDatesInTree(root: Node) { | ||
val treeWalker = document.createTreeWalker(root, whatToShow = NodeFilter.SHOW_TEXT) { node -> | ||
if (node.isChildOfMetaTag) { | ||
NodeFilter.FILTER_REJECT | ||
} else { | ||
NodeFilter.FILTER_ACCEPT | ||
} | ||
} | ||
|
||
var currentNode: Node? = treeWalker.currentNode | ||
while (currentNode != null) { | ||
replaceDates(currentNode) | ||
currentNode = treeWalker.nextNode() | ||
} | ||
} | ||
|
||
private fun replaceDates(node: Node) { | ||
if (node.nodeType != Node.TEXT_NODE || node.isChildOfMetaTag) { | ||
return | ||
} | ||
|
||
val text = node.nodeValue ?: return | ||
|
||
val newText = text.replaceExtendedDates().replaceSimpleDates() | ||
|
||
if (text != newText) { | ||
node.nodeValue = newText | ||
} | ||
} | ||
|
||
private fun String.replaceExtendedDates(): String { | ||
val regex = Regex( | ||
"([0-9]+)\\. (januar|jan\\.?|februar|feb\\.?|marts|mar\\.?|april|apr\\.?|maj|juni|jun\\.?|juli|jul\\.?|august|aug\\.?|september|sept\\.?|sep\\.?|oktober|okt\\.?|november|nov\\.?|december|dec\\.?)(?: ([0-9]+))?", | ||
RegexOption.IGNORE_CASE | ||
) | ||
|
||
return regex.replace(this) { matchResult -> | ||
val dayOfMonth = matchResult.groupValues.getOrNull(1)?.toIntOrNull() ?: return@replace matchResult.value | ||
|
||
val month = matchResult.groupValues.getOrNull(2).let { month -> | ||
when (month?.removeSuffix(".")) { | ||
"jan", "januar" -> Month.JANUARY | ||
"feb", "februar" -> Month.FEBRUARY | ||
"mar", "marts" -> Month.MARCH | ||
"apr", "april" -> Month.APRIL | ||
"maj" -> Month.MAY | ||
"jun", "juni" -> Month.JUNE | ||
"jul", "juli" -> Month.JULY | ||
"aug", "august" -> Month.AUGUST | ||
"sep", "sept", "september" -> Month.SEPTEMBER | ||
"okt", "oktober" -> Month.OCTOBER | ||
"nov", "november" -> Month.NOVEMBER | ||
"dec", "december" -> Month.DECEMBER | ||
else -> { | ||
return@replace matchResult.value | ||
} | ||
} | ||
} | ||
|
||
val year = matchResult.groupValues.getOrNull(3)?.toIntOrNull().let { year -> | ||
when { | ||
year == null -> null | ||
year < 100 -> year + 2000 | ||
else -> year | ||
} | ||
} | ||
|
||
try { | ||
val today = Clock.System.todayAt(TimeZone.currentSystemDefault()) | ||
|
||
val stickDate = LocalDate( | ||
year = year ?: today.year, | ||
month = month, | ||
dayOfMonth = dayOfMonth | ||
).toStickDate() | ||
|
||
if (year == null && stickDate.year == today.toStickDate().year) { | ||
// We just assume a date without a year is for the current year and if that's the same for the stick | ||
// date there's no reason to include the stick date year | ||
stickDate.toExtendedDayString() | ||
} else { | ||
stickDate.toExtendedFullString() | ||
} | ||
} catch (exception: IllegalArgumentException) { | ||
matchResult.value | ||
} | ||
} | ||
} | ||
|
||
private fun String.replaceSimpleDates(): String { | ||
val regex = Regex( | ||
"(?:(d\\.|den) )?([0-9]+)[.\\-/]([0-9]+)(?:[.\\-/ ]([0-9]+))?", | ||
RegexOption.IGNORE_CASE | ||
) | ||
|
||
return regex.replace(this) { matchResult -> | ||
val prefix = matchResult.groupValues.getOrNull(1) | ||
|
||
val datesParts = matchResult.groupValues.subList(2, matchResult.groupValues.size).map { datePart -> | ||
datePart.toIntOrNull() ?: return@replace matchResult.value | ||
} | ||
|
||
val monthNumber = datesParts[1] | ||
val (dayOfMonth, year) = when { | ||
datesParts.size < 2 -> Pair(datesParts[1], Clock.System.todayAt(TimeZone.currentSystemDefault()).year) | ||
datesParts.size > 3 -> return@replace matchResult.value | ||
datesParts[0] > 31 -> Pair(datesParts[2], datesParts[0]) | ||
else -> Pair(datesParts[0], datesParts[2]) | ||
}.let { (dayOfMonth, year) -> | ||
if (year < 100) { | ||
Pair(dayOfMonth, year + 2000) | ||
} else { | ||
Pair(dayOfMonth, year) | ||
} | ||
} | ||
|
||
try { | ||
val localDate = LocalDate( | ||
year = year, | ||
monthNumber = monthNumber, | ||
dayOfMonth = dayOfMonth | ||
) | ||
|
||
"${ | ||
if (prefix != null) { | ||
"$prefix " | ||
} else { | ||
"" | ||
} | ||
}${localDate.toStickDate().toSimplifiedString()}" | ||
} catch (exception: IllegalArgumentException) { | ||
matchResult.value | ||
} | ||
} | ||
} | ||
|
||
private val Node.isChildOfMetaTag: Boolean | ||
get() = when (parentNode?.nodeName?.toLowerCase()) { | ||
"script" -> true | ||
"style" -> true | ||
else -> false | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import kotlinx.browser.document | ||
|
||
fun main() { | ||
DomDateReplacer(document = document) | ||
} |
8 changes: 8 additions & 0 deletions
8
chrome-extension/src/main/resources/_locales/da/messages.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"application_name": { | ||
"message": "Pindsekalenderen" | ||
}, | ||
"application_description": { | ||
"message": "Erstatter gregorianske datoer (som 29. marts 2021 og 21/3-21) på alle hjemmesider til deres repræsentation i pindsekalenderen." | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
chrome-extension/src/main/resources/_locales/en/messages.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"application_name": { | ||
"message": "Stick Calendar", | ||
"description": "The title of the application, displayed in the web store." | ||
}, | ||
"application_description": { | ||
"message": "Replaces gregorian calendar dates (29/3-2021) in all websites to dates of the stick calendar. Mostly just makes sense in Danish.", | ||
"description": "The description of the application, displayed in the web store." | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "__MSG_application_name__", | ||
"description": "__MSG_application_description__", | ||
"version": "0.1.0", | ||
"manifest_version": 3, | ||
"default_locale": "en", | ||
"icons": { | ||
"16": "icons/dpu16.png", | ||
"32": "icons/dpu32.png", | ||
"48": "icons/dpu48.png", | ||
"72": "icons/dpu72.png", | ||
"128": "icons/dpu128.png", | ||
"256": "icons/dpu256.png" | ||
}, | ||
"content_scripts": [ | ||
{ | ||
"matches": [ | ||
"<all_urls>" | ||
], | ||
"exclude_matches": [ | ||
"http://*.spilpind.dk/*", | ||
"https://*.spilpind.dk/*" | ||
], | ||
"run_at": "document_idle", | ||
"js": [ | ||
"stick-calendar.js" | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
plugins { | ||
kotlin("multiplatform") | ||
} | ||
|
||
kotlin { | ||
jvm { | ||
compilations.all { | ||
kotlinOptions.jvmTarget = "1.8" | ||
} | ||
testRuns["test"].executionTask.configure { | ||
useJUnit() | ||
} | ||
} | ||
|
||
js(LEGACY) { | ||
browser { | ||
commonWebpackConfig { | ||
cssSupport.enabled = true | ||
} | ||
|
||
testTask { | ||
useKarma { | ||
useChromeHeadless() | ||
} | ||
} | ||
} | ||
binaries.executable() | ||
} | ||
|
||
val hostOs = System.getProperty("os.name") | ||
val isMingwX64 = hostOs.startsWith("Windows") | ||
when { | ||
hostOs == "Mac OS X" -> macosX64("native") | ||
hostOs == "Linux" -> linuxX64("native") | ||
isMingwX64 -> mingwX64("native") | ||
else -> throw GradleException("Host OS is not supported in Kotlin/Native.") | ||
} | ||
|
||
sourceSets { | ||
|
||
@Suppress("UNUSED_VARIABLE") | ||
val commonMain by getting { | ||
dependencies { | ||
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.1.1") | ||
} | ||
} | ||
|
||
@Suppress("UNUSED_VARIABLE") | ||
val commonTest by getting { | ||
dependencies { | ||
implementation(kotlin("test-common")) | ||
implementation(kotlin("test-annotations-common")) | ||
} | ||
} | ||
|
||
@Suppress("UNUSED_VARIABLE") | ||
val jvmTest by getting { | ||
dependencies { | ||
implementation(kotlin("test-junit")) | ||
} | ||
} | ||
|
||
@Suppress("UNUSED_VARIABLE") | ||
val jsTest by getting { | ||
dependencies { | ||
implementation(kotlin("test-js")) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.