Skip to content

Commit

Permalink
feat: init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dfdgsdfg committed Nov 14, 2018
0 parents commit 39ed4df
Show file tree
Hide file tree
Showing 12 changed files with 5,326 additions and 0 deletions.
83 changes: 83 additions & 0 deletions .gitignore
@@ -0,0 +1,83 @@

# Created by https://www.gitignore.io/api/node
# Edit at https://www.gitignore.io/?templates=node

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

# FuseBox cache
.fusebox/

# End of https://www.gitignore.io/api/node
45 changes: 45 additions & 0 deletions README.md
@@ -0,0 +1,45 @@
# Webflow Multilingual
Fork from http://multilinguale.webflow.io

Only support modern browsers

## Install
```
<script src="https://unpkg.com/webflow-multilingual/webflow-multilingual.js"></script>
```

## Usage
### Text node
```
<p>[[ko]] 안녕 [[en]]hello</p>
```

### Class
```
<p class="wm-ko">안녕</p>
<p class="wm-en">hello</p>
```

### Attribute (not yet)
```
<p data-wm-lang="ko">안녕</p>
<p data-wm-lang="en">hello</p>
```

### Select language by URL query string parameters
```
https://your-awesome-site.site?lang=ko
https://your-awesome-site.site?lang=en
```

### Select language by button
```
<button data-wm-sel="ko">한국어</button>
<button data-wm-sel="en">English</button>
```

### Switch language
```
<button data-wm-switch>Switch</button>
```

24 changes: 24 additions & 0 deletions index.html
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h3>class feature</h3>
<p class="wm-ko">한국어</p>
<p class="wm-en">English</p>
<hr>
<h3>text content feature</h3>
<p>[[ko]]한국어 [[en]]English</p>
<p>[[ko]]한국어 <br> 한국어[[en]]English <br> English</p>
<p>[[ko]]한국어
한국어
[[en]]English
English</p>
<button data-wm-sel="ko">한국어</button>
<button data-wm-sel="en">English</button>
<button data-wm-switch>Switch</button>
<script src="webflow-multilingual.js"></script>
</body>

</html>
124 changes: 124 additions & 0 deletions index.js
@@ -0,0 +1,124 @@
// http://multilinguale.webflow.io
import ISO6391 from 'iso-639-1'

const defaultLang = 'en'
const langRegExp = /\[\[([a-z]{2})\]\]([^\[]+)/g
const isStorageEnabled = ! (typeof localStorage == 'undefined')
let userLang = (navigator.userLanguage||navigator.browserLanguage||navigator.language||defaultLang).substr(0,2)
let documentLang = new Set()
let documentLangIter

function getLangParam() {
const arr = /lang=([a-z]{2})/g.exec(location.search)
return arr ? arr[1] : null
}

function getLangFromStorage() {
return isStorageEnabled ? localStorage.getItem('lang') : undefined
}

function setLang(lang) {
userLang = lang
if(isStorageEnabled){
localStorage.setItem('lang', userLang)
}
console.log('[wm] setLang:', lang, userLang)
applyLang()
}

function applyLang() {
textDict.forEach((o) => {
o.el.textContent = o.dict[userLang]
})

ISO6391.getAllCodes().forEach(lang => {
lang === userLang
? document.querySelectorAll(`.wm-${lang}`).forEach(el => el.style.display = el.dataset.wmDisplay)
: document.querySelectorAll(`.wm-${lang}`).forEach(el => el.style.display = 'none')
})
}

function textNodesUnder(el) {
let node
const nodes = []
const walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false)

while (node=walk.nextNode()) {
nodes.push(node)
}

return nodes
}

const textDict = []

// https://medium.com/@roxeteer/javascript-one-liner-to-get-elements-text-content-without-its-child-nodes-8e59269d1e71
function parentElTextOnly(el) {
return Array.from(el.childNodes).reduce((acc, node) => {
return acc + (node.nodeType === 3 ? node.textContent : '')
}, '')
}

window.addEventListener('DOMContentLoaded', () => {
userLang = getLangParam() || getLangFromStorage() || userLang
if(isStorageEnabled) {
localStorage.setItem('lang', userLang);
}

ISO6391.getAllCodes().forEach(lang => {
document.querySelectorAll(`.wm-${lang}`).forEach(el => el.dataset.wmDisplay = el.style.display)
})

textNodesUnder(document).filter((node) => {
return langRegExp.test(parentElTextOnly(node.parentElement))
}).forEach((node, i) => {
const dict = {}
let arr
while((arr = langRegExp.exec(parentElTextOnly(node.parentElement))) != null) {
dict[arr[1]] = arr[2]
documentLang.add(arr[1])
}
textDict.push({
el: node.parentElement,
dict
})
})
console.log('[wm] documentLang:', documentLang)
documentLangIter = documentLang[Symbol.iterator]()
applyLang()
});


/////////////////////////

window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-wm-sel]').forEach((el) => {
el.addEventListener('click', (evt) => {
evt.stopPropagation()
evt.preventDefault()
console.log('[wm] click:', el.dataset.wmSel)
setLang(el.dataset.wmSel)
})
})
})

///////////////////////////

window.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-wm-switch]').forEach((el) => {
el.addEventListener('click', (evt) => {
evt.stopPropagation()
evt.preventDefault()
let nextLang = documentLangIter.next().value
if (nextLang === userLang) {
nextLang = documentLangIter.next().value
}
if (!nextLang) {
documentLangIter = documentLang[Symbol.iterator]()
nextLang = documentLangIter.next().value
}
setLang(nextLang)
console.log('[wm] switch:', nextLang)
})
})
})

0 comments on commit 39ed4df

Please sign in to comment.