Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] converte JS to vanilla.js that does not rely on jQuery #26

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions assets/javascripts/i18n_viz_new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
class I18nVizTooltip {
constructor () {
this.element = document.createElement('div')
this.element.className = 'i18n_viz_tooltip'
this.hide()

document.body.appendChild(this.element)
}

moveTo (elementPosition) {
var top = elementPosition.top - this.element.offsetHeight
if (top < 0) {
top = elementPosition.top + elementPosition.height + 10
}
this.element.style.top = parseInt(top, 10).toString()+'px'
this.element.style.left = parseInt(elementPosition.left, 10).toString()+'px'
}

setI18nKeys (i18nKeys) {
this.i18nKeys = i18nKeys
}

show () {
this._clearContent()
this._renderContent()
this.element.style.display = 'block'
}

hide () {
this.element.style.display = 'none'
}

_clearContent () {
this.element.innerHTML = ''
}

_renderContent () {
this.i18nKeys.forEach((key) => {
var keyElement
if (window.I18nViz.external_tool_url) {
keyElement = document.createElement('a')
keyElement.setAttribute('href', window.I18nViz.external_tool_url + key)
keyElement.setAttribute('target', '_blank')
} else {
keyElement = document.createElement('span')
}
keyElement.textContent = key
this.element.appendChild(keyElement)
})
}
}

class I18nVizElement {
constructor (element, options) {
this.element = element
this.matchesIn = options.matchesIn
this.tooltip = window.I18nViz.tooltip
this.i18nKeys = this._extractI18nKeys()
this._handleMouseEnter = this._handleMouseEnter.bind(this)
this._style()
this.element.addEventListener('mouseenter', this._handleMouseEnter)
}

_style () {
this.element.className = [this.element.className, 'i18n-viz'].join(' ')
}

_dimensions () {
var rect = this.element.getBoundingClientRect()
return {
top: rect.top,
left: rect.left,
height: this.element.offsetHeight
}
}

_handleMouseEnter (event) {
this.tooltip.setI18nKeys(this.i18nKeys)
this.tooltip.moveTo(this._dimensions())
this.tooltip.show()
}

_elementText () {
if (this.type === 'input') {
return this.element.value + this.element.getAttribute('placeholder')
} else {
return this.element.textContent
}
}

// receives text and returns extracted i18n keys as array
_extractI18nKeys () {
let keys = this._elementText().match(window.I18nViz.global_regex)
if (keys) {
keys.forEach(function(value, index) {
return keys[index] = value.replace(/--/g, "")
})
return keys
} else {
return null
}
}

_clear () {
if (this.type === 'input') {
this.element.value = this._replaceI18nTextIn(this.element.value)
this.element.setAttribute('placeholder', this._replaceI18nTextIn(this.element.getAttribute('placeholder')))
}

_replaceI18nTextIn (text) {
return text.replace(window.I18nViz.global_regex, '')
}
}

class I18nVizInitializer {
constructor () {
this.elements = []
this.instances = []
}

init () {
var elements = document.body.getElementsByTagName('*')

for (var i = 0; i < elements.length; ++i) {
const matchesIn = {
value: window.I18nViz.regex.test(elements[i].value),
placeholder: window.I18nViz.regex.test(elements[i].getAttribute('placeholder')),
textContent: window.I18nViz.regex.test(elements[i].textContent)
}

// reduce?
let matchesArray = []
matchesIn.forEach((key, value) => { matchesArray.push(key) })

if (any(matchesArray)) {
this.elements.push(elements[i])
this.instances.push(new I18nVizElement(element, {matchesIn: matchesArray}))
}
}
}

clearAllI18nText () {
var textNodesIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_TEXT // Only consider nodes that are text nodes (nodeType 3)
)
var currentNode
while (currentNode = textNodesIterator.nextNode()) {
currentNode.textContent = currentNode.textContent.replace(window.I18nViz.global_regex, '')
}
}
}

document.addEventListener('DOMContentLoaded', (_event) => {
window.I18nViz.tooltip = new I18nVizTooltip
const initializer = new I18nVizInitializer
initializer.init()
window.I18nViz.initializer = initializer
})
6 changes: 3 additions & 3 deletions assets/stylesheets/i18n_viz.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#i18n_viz_tooltip {
.i18n_viz_tooltip {
display: none;
position: absolute;
top: 100px;
Expand All @@ -18,13 +18,13 @@
padding: 10px;
z-index: 999;
}
#i18n_viz_tooltip a, #i18n_viz_tooltip span {
.i18n_viz_tooltip a, #i18n_viz_tooltip span {
margin-right: 10px;
color: #111111;
font-family: "Helvetica Neue", Arial, sans-serif;
font-size: 12px;
}
#i18n_viz_tooltip a:last-child, #i18n_viz_tooltip span:last-child {
.i18n_viz_tooltip a:last-child, .i18n_viz_tooltip span:last-child {
margin-right: 0;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/generators/i18n_viz/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ module I18nViz
module Generators
class InstallGenerator < Rails::Generators::Base
source_root File.expand_path("../../../../app/assets/", __FILE__)

def copy_assets
copy_file "javascripts/i18n_viz.js", "public/javascripts/i18n_viz.js"
copy_file "stylesheets/i18n_viz.css", "public/stylesheets/i18n_viz.css"
end

def create_initializer
initializer "i18n_viz.rb", %Q{
I18nViz.enabled = !Rails.env.production?
Expand Down
6 changes: 5 additions & 1 deletion lib/i18n_viz/middleware.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ def call(env)

private

def javascript_code
File.read(File.join(File.dirname(__FILE__), '..', '..', 'assets', 'javascripts', 'i18n_viz_new.js' ))
end

def html?; @headers['Content-Type'] =~ /html/; end

def inject(env, response)
Expand All @@ -36,7 +40,7 @@ def inject(env, response)
global_regex: new RegExp(/--([a-z0-9_\.]+)--/gi),
external_tool_url: '#{external_tool_url}'
}
#{JS}
#{javascript_code}
</script>

<style>
Expand Down
4 changes: 4 additions & 0 deletions test/dummy/app/views/test/test.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
<%= t("hello") %>
<span><%= translate("bar", :scope => :scope) %></span>
</h1>

<input value="<%= t("input_value") %>" />

<textarea placeholder="<%= t("textarea_placeholder") %>"></textarea>
2 changes: 2 additions & 0 deletions test/dummy/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ en:
foo: "bar"
scope:
bar: "foo"
input_value: "Valuable"
textarea_placeholder: "Placeholda"