mirror of
https://github.com/moebooru/moebooru
synced 2025-08-22 09:57:31 +00:00
Migrate related_tags to jquery.
Now with more coffeescript since debugging is now fun. Many thanks to coffee-rails-source-maps and related projects.
This commit is contained in:
parent
649403948e
commit
2bea765b5e
7
Gemfile
7
Gemfile
@ -2,11 +2,14 @@ source "https://rubygems.org"
|
||||
|
||||
gem "rails", "~> 4.0.0"
|
||||
gem "rails-observers"
|
||||
|
||||
gem "coffee-rails", "~> 4.0.0"
|
||||
gem "coffee-rails-source-maps", :group => :development
|
||||
gem "jquery-rails"
|
||||
gem "jquery-ui-rails"
|
||||
gem "uglifier"
|
||||
|
||||
gem "sass-rails"
|
||||
gem "uglifier"
|
||||
gem "jquery-ui-rails"
|
||||
|
||||
gem "pg", :platforms => [:ruby, :mswin, :mingw]
|
||||
gem "activerecord-jdbcpostgresql-adapter", "~> 1.3.0.rc1", :platforms => :jruby
|
||||
|
11
Gemfile.lock
11
Gemfile.lock
@ -42,6 +42,15 @@ GEM
|
||||
cache_digests (0.3.1)
|
||||
actionpack (>= 3.2)
|
||||
thread_safe
|
||||
coffee-rails (4.0.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
coffee-rails-source-maps (1.4.0)
|
||||
coffee-script-source (>= 1.6.1)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.7.0)
|
||||
daemons (1.1.9)
|
||||
dalli (2.7.0)
|
||||
diff-lcs (1.2.5)
|
||||
@ -178,6 +187,8 @@ DEPENDENCIES
|
||||
acts_as_versioned_rails3
|
||||
addressable
|
||||
cache_digests
|
||||
coffee-rails (~> 4.0.0)
|
||||
coffee-rails-source-maps
|
||||
daemons
|
||||
dalli
|
||||
diff-lcs
|
||||
|
4
app/assets/javascripts/boot.js.coffee
Normal file
4
app/assets/javascripts/boot.js.coffee
Normal file
@ -0,0 +1,4 @@
|
||||
#= require moebooru
|
||||
#= require moebooru/related_tags
|
||||
jQuery(document).ready ->
|
||||
Moebooru.relatedTags.initialize()
|
121
app/assets/javascripts/moebooru/related_tags.js.coffee
Normal file
121
app/assets/javascripts/moebooru/related_tags.js.coffee
Normal file
@ -0,0 +1,121 @@
|
||||
#= require moebooru
|
||||
jQuery(document).ready ($) ->
|
||||
window.Moebooru.relatedTags =
|
||||
recentTags: -> $.cookie("recent_tags").match(/\S+/g) || []
|
||||
myTags: -> $.cookie("my_tags").match(/\S+/g) || []
|
||||
artistSource: -> $("#post_source").val()
|
||||
source: -> $ "#post_tags"
|
||||
target: -> $ "#related"
|
||||
tagUrl: (tag) -> Moebooru.path "/post?tags=#{encodeURIComponent tag}"
|
||||
|
||||
getTags: ->
|
||||
source = @source()
|
||||
selectFrom = source[0].selectionStart
|
||||
selectTo = source[0].selectionEnd
|
||||
tags = source.val()
|
||||
|
||||
if tags.length != 0 && selectFrom != 0 && selectFrom != tags.length
|
||||
selectionStart = tags.slice(0, selectFrom).lastIndexOf " "
|
||||
selectionEnd = tags.indexOf " ", selectTo
|
||||
selectionStart = 0 if selectionStart == -1
|
||||
selectionEnd = undefined if selectionEnd == -1
|
||||
tags = tags.slice selectionStart, selectionEnd
|
||||
tags
|
||||
|
||||
refreshList: (extra) ->
|
||||
buf = @target().empty()
|
||||
if @myTags().length > 0
|
||||
buf.append @buildList("My Tags", @myTags())
|
||||
if @recentTags().length > 0
|
||||
buf.append @buildList("Recent Tags", @recentTags())
|
||||
|
||||
for title, tags of extra
|
||||
buf.append @buildList(title, tags) if tags.length > 0
|
||||
|
||||
@highlightList()
|
||||
|
||||
highlightList: ->
|
||||
highlightedTags = @source().val().match(/\S+/g) || []
|
||||
$(".tag-column").find("a").removeClass "highlighted"
|
||||
for tag in highlightedTags
|
||||
$(".tag-column").find("a[href='#{@tagUrl tag}']").addClass "highlighted"
|
||||
|
||||
buildList: (title, tags) ->
|
||||
buf = $("<div>").addClass "tag-column"
|
||||
buf.append $("<h6>").text(title.replace /_/g, " ")
|
||||
tagsList = $("<ul>")
|
||||
|
||||
for tag in tags.sort()
|
||||
tagName = tag.replace /_/g, " "
|
||||
tag = tag
|
||||
tagsList.append(
|
||||
$("<li>").append $("<a>").text(tagName).attr(href: @tagUrl(tag))
|
||||
)
|
||||
|
||||
buf.append tagsList
|
||||
|
||||
fetchStart: -> @target().html $("<em>").text("Fetching...")
|
||||
|
||||
fetchArtistSuccess: (data) ->
|
||||
console.log (artist.name for artist in data)
|
||||
@refreshList "Artist": (artist.name for artist in data)
|
||||
|
||||
fetchSuccess: (data) ->
|
||||
tagsCollection = {}
|
||||
for name, tags of data
|
||||
tagsCollection[name] = (tag[0] for tag in tags)
|
||||
@refreshList tagsCollection
|
||||
|
||||
toggleTag: (e) ->
|
||||
e.preventDefault()
|
||||
tagName = $(e.target).text().replace /\s/g, "_"
|
||||
currentTags = @source().val()
|
||||
jumpToEnd = @source()[0].selectionStart == currentTags.length
|
||||
|
||||
if $(e.target).hasClass "highlighted"
|
||||
newVal = currentTags.replace(tagName, "")
|
||||
else
|
||||
newVal = "#{currentTags} #{tagName}"
|
||||
|
||||
newVal = "#{newVal.replace(/^\s+|\s+$/g, "").replace(/\s\s+/g, " ")} "
|
||||
newVal = "" if newVal == " "
|
||||
|
||||
@source().val(newVal)
|
||||
@source()[0].selectionStart = newVal.length if jumpToEnd
|
||||
@highlightList()
|
||||
@source().focus()
|
||||
|
||||
run: (e) ->
|
||||
e.preventDefault()
|
||||
|
||||
tags = @getTags()
|
||||
type = $(e.target).data("type")
|
||||
|
||||
if type == "artist-url"
|
||||
source = @artistSource() || ""
|
||||
return unless source.length > 0 && source.match /^https?:\/\//
|
||||
@fetchStart()
|
||||
$.ajax
|
||||
url: Moebooru.path "/artist.json"
|
||||
data:
|
||||
url: source
|
||||
limit: 10
|
||||
success: $.proxy @fetchArtistSuccess, this
|
||||
else
|
||||
type = null if type == "all"
|
||||
return unless tags.length > 0
|
||||
@fetchStart()
|
||||
$.ajax
|
||||
url: Moebooru.path "/tag/related.json"
|
||||
data: { type: type, tags: tags }
|
||||
success: $.proxy @fetchSuccess, this
|
||||
|
||||
initialize: ->
|
||||
return unless @source().length && @target().length
|
||||
$("[data-toggle='related-tags']").click $.proxy(@run, this)
|
||||
@target().on "click", "a", $.proxy(@toggleTag, this)
|
||||
@source().on "input keyup", $.proxy(@highlightList, this)
|
||||
if @artistSource()
|
||||
$("[data-toggle='related-tags'][data-type='artist-url']").click()
|
||||
else
|
||||
@refreshList()
|
18
app/assets/stylesheets/related_tags.css.scss
Normal file
18
app/assets/stylesheets/related_tags.css.scss
Normal file
@ -0,0 +1,18 @@
|
||||
.tag-column {
|
||||
h6 {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
margin: 0;
|
||||
|
||||
a.highlighted {
|
||||
color: white;
|
||||
background: rgb(0, 111, 250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -123,7 +123,7 @@ class TagController < ApplicationController
|
||||
end
|
||||
|
||||
def related
|
||||
if params[:type]
|
||||
if params[:type].present?
|
||||
@tags = Tag.scan_tags(params[:tags])
|
||||
@tags = TagAlias.to_aliased(@tags)
|
||||
@tags = @tags.inject({}) do |all, x|
|
||||
|
@ -43,8 +43,6 @@
|
||||
<% content_for :post_cookie_javascripts do %>
|
||||
<script type="text/javascript">
|
||||
|
||||
RelatedTags.init(Cookie.get('my_tags'), '<%= params[:url] %>')
|
||||
|
||||
if (Cookie.get('resize_image') == '1') {
|
||||
Post.resize_image()
|
||||
}
|
||||
|
@ -62,12 +62,13 @@
|
||||
<td>
|
||||
<%= text_area "post", "tags", :readonly => !@post.can_be_seen_by?(@current_user), :size => "50x4", :value => @post.cached_tags, :tabindex => 10 %>
|
||||
<% if @post.can_be_seen_by?(@current_user) %>
|
||||
<%= link_to_function t('.related.tags'), "RelatedTags.find('post_tags')" %> |
|
||||
<%= link_to_function t('.related.artists'), "RelatedTags.find('post_tags', 'artist')" %> |
|
||||
<%= link_to_function t('.related.characters'), "RelatedTags.find('post_tags', 'char')" %> |
|
||||
<%= link_to_function t('.related.copyrights'), "RelatedTags.find('post_tags', 'copyright')" %>
|
||||
<%= link_to t(".related.tags"), "#", :data => { :toggle => "related-tags", :type => "all" } %> |
|
||||
<%= link_to t(".related.artists"), "#", :data => { :toggle => "related-tags", :type => "artist" } %> |
|
||||
<%= link_to t(".related.characters"), "#", :data => { :toggle => "related-tags", :type => "char" } %> |
|
||||
<%= link_to t(".related.copyrights"), "#", :data => { :toggle => "related-tags", :type => "copyright" } %> |
|
||||
<%= link_to t("post.upload.form.find_related.circles"), "#", :data => { :toggle => "related-tags", :type => "circle" } %>
|
||||
<% if CONFIG["enable_artists"] %>
|
||||
| <%= link_to_function(t('.find_artists'), "RelatedTags.find_artist($F('post_source'))") %>
|
||||
| <%= link_to t(".find_artists"), "#", :data => { :toggle => "related-tags", :type => "artist-url" } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
|
@ -79,9 +79,9 @@
|
||||
<% end %>
|
||||
</th>
|
||||
<td>
|
||||
<%= text_field "post", "source", :value => params["url"], :size => 50, :tabindex => 2 %>
|
||||
<%= text_field "post", "source", :value => (params["url"] || params["ref"]), :size => 50, :tabindex => 2 %>
|
||||
<% if CONFIG["enable_artists"] %>
|
||||
<%= link_to_function(t('.form.find_artist'), "RelatedTags.find_artist($F('post_source'))") %>
|
||||
<%= link_to t(".form.find_artist"), "#", :data => { :toggle => "related-tags", :type => "artist-url" } %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
@ -94,11 +94,11 @@
|
||||
</th>
|
||||
<td>
|
||||
<%= text_area "post", "tags", :value => params[:tags], :size => "60x2", :tabindex => 3 %>
|
||||
<%= link_to_function t('.form.find_related.tags'), "RelatedTags.find('post_tags')" %> |
|
||||
<%= link_to_function t('.form.find_related.artists'), "RelatedTags.find('post_tags', 'artist')" %> |
|
||||
<%= link_to_function t('.form.find_related.characters'), "RelatedTags.find('post_tags', 'char')" %> |
|
||||
<%= link_to_function t('.form.find_related.copyrights'), "RelatedTags.find('post_tags', 'copyright')" %> |
|
||||
<%= link_to_function t('.form.find_related.circles'), "RelatedTags.find('post_tags', 'circle')" %>
|
||||
<%= link_to t(".form.find_related.tags"), "#", :data => { :toggle => "related-tags", :type => "all" } %> |
|
||||
<%= link_to t(".form.find_related.artists"), "#", :data => { :toggle => "related-tags", :type => "artist" } %> |
|
||||
<%= link_to t(".form.find_related.characters"), "#", :data => { :toggle => "related-tags", :type => "char" } %> |
|
||||
<%= link_to t(".form.find_related.copyrights"), "#", :data => { :toggle => "related-tags", :type => "copyright" } %> |
|
||||
<%= link_to t(".form.find_related.circles"), "#", :data => { :toggle => "related-tags", :type => "circle" } %>
|
||||
</td>
|
||||
</tr>
|
||||
<% if CONFIG["enable_parent_posts"] %>
|
||||
@ -160,12 +160,6 @@
|
||||
}.bindAsEventListener());
|
||||
</script>
|
||||
|
||||
<% content_for :post_cookie_javascripts do %>
|
||||
<script type="text/javascript">
|
||||
RelatedTags.init(Cookie.unescape(Cookie.get('my_tags')), '<%= params[:ref] || params[:url] %>')
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
new TagCompletionBox($("post_tags"));
|
||||
if(TagCompletion)
|
||||
|
@ -1,161 +0,0 @@
|
||||
RelatedTags = {
|
||||
user_tags: [],
|
||||
recent_tags: [],
|
||||
recent_search: {},
|
||||
|
||||
init: function(user_tags, artist_url) {
|
||||
this.user_tags = (user_tags.match(/\S+/g) || []).sort()
|
||||
this.recent_tags = Cookie.get("recent_tags").match(/\S+/g)
|
||||
if (this.recent_tags) {
|
||||
this.recent_tags = this.recent_tags.sort().uniq(true)
|
||||
} else {
|
||||
this.recent_tags = []
|
||||
}
|
||||
|
||||
if ((artist_url != null) && (artist_url.match(/^http/))) {
|
||||
this.find_artist($F("post_source"))
|
||||
} else {
|
||||
this.build_all({})
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function(link, field) {
|
||||
var field = $(field)
|
||||
var tags = field.value.match(/\S+/g) || []
|
||||
var tag = (link.innerText || link.textContent).replace(/ /g, "_")
|
||||
|
||||
if (tags.include(tag)) {
|
||||
field.value = tags.without(tag).join(" ") + " "
|
||||
} else {
|
||||
field.value = tags.concat([tag]).join(" ") + " "
|
||||
}
|
||||
|
||||
this.build_all(this.recent_search)
|
||||
return false
|
||||
},
|
||||
|
||||
build_html: function(key, tags) {
|
||||
if (tags == null || tags.size() == 0) {
|
||||
return ""
|
||||
}
|
||||
|
||||
var html = ""
|
||||
var current = $F("post_tags").match(/\S+/g) || []
|
||||
|
||||
html += '<div class="tag-column">'
|
||||
html += '<h6><em>' + key.replace(/_/g, " ") + '</em></h6>'
|
||||
|
||||
for (var i=0; i<tags.size(); ++i) {
|
||||
var tag = tags[i]
|
||||
html += ('<a href="/post?tags=' + encodeURIComponent(tag) + '" onclick="RelatedTags.toggle(this, \'post_tags\'); return false"')
|
||||
|
||||
if (current.include(tag)) {
|
||||
html += ' style="background: rgb(0, 111, 250); color: white;"'
|
||||
}
|
||||
|
||||
html += '>' + tag.escapeHTML().replace(/_/g, " ") + '</a><br> '
|
||||
}
|
||||
html += '</div>'
|
||||
|
||||
return html
|
||||
},
|
||||
|
||||
build_all: function(tags) {
|
||||
this.recent_search = tags
|
||||
|
||||
var html = this.build_html("My Tags", this.user_tags) + this.build_html("Recent Tags", this.recent_tags)
|
||||
var keys = []
|
||||
|
||||
for (key in tags) {
|
||||
keys.push(key)
|
||||
}
|
||||
|
||||
keys.sort()
|
||||
|
||||
for (var i=0; i<keys.size(); ++i) {
|
||||
html += this.build_html(keys[i], tags[keys[i]])
|
||||
}
|
||||
|
||||
$("related").update(html)
|
||||
},
|
||||
|
||||
find: function(field, type) {
|
||||
$("related").update("<em>Fetching...</em>")
|
||||
var field = $(field)
|
||||
var tags = null
|
||||
// .textLength is empty in IE9.
|
||||
if (field.textLength == null) {
|
||||
field.textLength = jQuery(field).val().length;
|
||||
};
|
||||
|
||||
// Fetch all related tags if cursor position is either at the beginning or
|
||||
// the end of text area.
|
||||
if ((field.selectionStart == 0) || (field.selectionStart == field.textLength)) {
|
||||
tags = field.value
|
||||
} else {
|
||||
var a = field.selectionStart
|
||||
var b = field.selectionEnd
|
||||
|
||||
if(a != b) {
|
||||
while ((b > 0) && field.value[b] != " ") {
|
||||
b -= 1
|
||||
}
|
||||
}
|
||||
while ((a > 0) && field.value[a] != " ") {
|
||||
a -= 1
|
||||
}
|
||||
|
||||
if (field.value[a] == " ") {
|
||||
a += 1
|
||||
}
|
||||
|
||||
while ((b < field.textLength) && field.value[b] != " ") {
|
||||
b += 1
|
||||
}
|
||||
|
||||
tags = field.value.slice(a, b)
|
||||
}
|
||||
|
||||
var params = {"tags": tags}
|
||||
if (type) {
|
||||
params["type"] = type
|
||||
}
|
||||
|
||||
new Ajax.Request("/tag/related.json", {
|
||||
method: 'get',
|
||||
parameters: params,
|
||||
onComplete: function(resp) {
|
||||
var resp = resp.responseJSON
|
||||
var converted = this.convert_related_js_response(resp)
|
||||
this.build_all(converted)
|
||||
}.bind(this)
|
||||
})
|
||||
},
|
||||
|
||||
convert_related_js_response: function(resp) {
|
||||
var converted = {}
|
||||
|
||||
for (k in resp) {
|
||||
var tags = resp[k].map(function(x) {return x[0]}).sort()
|
||||
converted[k] = tags
|
||||
}
|
||||
|
||||
return converted
|
||||
},
|
||||
|
||||
find_artist: function(url) {
|
||||
if (url.match(/^http/)) {
|
||||
new Ajax.Request("/artist.json", {
|
||||
method: "get",
|
||||
parameters: {
|
||||
"url": url,
|
||||
"limit": "10"
|
||||
},
|
||||
onComplete: function(resp) {
|
||||
var resp = resp.responseJSON
|
||||
this.build_all({"Artist": resp.map(function(x) {return x.name})})
|
||||
}.bind(this)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user