Added emojis. The emoji picker is coming soon, as is the font file. More emojis coming soon ^_^
Added the ability to ban and unban users. Improved the installation instructions. Changed the collation of the tables from utf8_general_ci to utf8mb4_general_ci. Changed the group ID order. Custom pages are now templates rather than little snippets being inserted into a template. Changed the collation of the driver to utf8mb4_general_ci. Added a default_group config setting. Ban flag is overwritten for admins and super mods.
This commit is contained in:
parent
6a320edbb4
commit
12abd657e1
|
@ -24,14 +24,17 @@ Instructions on how to do so on Linux: https://downloads.mariadb.org/mariadb/rep
|
|||
|
||||
**Run the following commands:**
|
||||
|
||||
go get github.com/go-sql-driver/mysql
|
||||
go install github.com/go-sql-driver/mysql
|
||||
|
||||
go get golang.org/x/crypto/bcrypt
|
||||
go install golang.org/x/crypto/bcrypt
|
||||
|
||||
Tweak the config.go file and put your database details in there. Import data.sql into the same database. Comment out the first line (put /* and */ around it), if you've already made a database, and don't want the script to generate it for you.
|
||||
|
||||
Set the password column of your user account in the database to what you want your password to be. The system will encrypt your password when you login for the first time.
|
||||
|
||||
Add -u after go get to update those libraries, if you've already got them installed.
|
||||
|
||||
# Run the program
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ var max_request_size = 5 * megabyte
|
|||
|
||||
// Misc
|
||||
var default_route = route_topics
|
||||
var default_group = 3
|
||||
var staff_css = " background-color: #ffeaff;"
|
||||
var uncategorised_forum_visible = true
|
||||
var siteurl = "localhost:8080"
|
||||
var noavatar = "https://api.adorable.io/avatars/285/{id}@" + siteurl + ".png"
|
||||
var items_per_page = 50
|
17
data.sql
17
data.sql
|
@ -13,7 +13,7 @@ CREATE TABLE `users`(
|
|||
`email` varchar(200) DEFAULT '' not null,
|
||||
`avatar` varchar(20) DEFAULT '' not null,
|
||||
primary key(`uid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `users_groups`(
|
||||
`gid` int not null AUTO_INCREMENT,
|
||||
|
@ -24,7 +24,7 @@ CREATE TABLE `users_groups`(
|
|||
`is_banned` tinyint DEFAULT 0 not null,
|
||||
`tag` varchar(50) DEFAULT '' not null,
|
||||
primary key(`gid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `forums`(
|
||||
`fid` int not null AUTO_INCREMENT,
|
||||
|
@ -36,7 +36,7 @@ CREATE TABLE `forums`(
|
|||
`lastReplyerID` int DEFAULT 0 not null,
|
||||
`lastTopicTime` datetime not null,
|
||||
primary key(`fid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `topics`(
|
||||
`tid` int not null AUTO_INCREMENT,
|
||||
|
@ -50,7 +50,7 @@ CREATE TABLE `topics`(
|
|||
`sticky` tinyint DEFAULT 0 not null,
|
||||
`parentID` int DEFAULT 1 not null,
|
||||
primary key(`tid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `replies`(
|
||||
`rid` int not null AUTO_INCREMENT,
|
||||
|
@ -62,7 +62,7 @@ CREATE TABLE `replies`(
|
|||
`lastEdit` int not null,
|
||||
`lastEditBy` int not null,
|
||||
primary key(`rid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
CREATE TABLE `users_replies`(
|
||||
`rid` int not null AUTO_INCREMENT,
|
||||
|
@ -74,7 +74,7 @@ CREATE TABLE `users_replies`(
|
|||
`lastEdit` int not null,
|
||||
`lastEditBy` int not null,
|
||||
primary key(`rid`)
|
||||
);
|
||||
) CHARSET=utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
/*CREATE TABLE `replies_reports` (
|
||||
`rid` int not null AUTO_INCREMENT,
|
||||
|
@ -86,9 +86,12 @@ CREATE TABLE `users_replies`(
|
|||
|
||||
INSERT INTO users(`name`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`)
|
||||
VALUES ('Admin',1,1,NOW(),NOW());
|
||||
|
||||
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{}',1,1,"Admin");
|
||||
INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{}');
|
||||
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{}',1,"Mod");
|
||||
INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{}');
|
||||
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{}',1);
|
||||
|
||||
INSERT INTO forums(`name`,`lastTopicTime`) VALUES ('General',NOW());
|
||||
INSERT INTO topics(`title`,`content`,`createdAt`,`lastReplyAt`,`createdBy`,`parentID`)
|
||||
VALUES ('Test Topic','A topic automatically generated by the software.',NOW(),NOW(),1,1);
|
||||
|
|
BIN
grosolo.exe
BIN
grosolo.exe
Binary file not shown.
BIN
grosolo.exe~
BIN
grosolo.exe~
Binary file not shown.
54
main.go
54
main.go
|
@ -6,7 +6,10 @@ import (
|
|||
_ "github.com/go-sql-driver/mysql"
|
||||
"log"
|
||||
"mime"
|
||||
"strings"
|
||||
"strconv"
|
||||
"path/filepath"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"html/template"
|
||||
)
|
||||
|
@ -40,6 +43,7 @@ var set_avatar_stmt *sql.Stmt
|
|||
var set_username_stmt *sql.Stmt
|
||||
var register_stmt *sql.Stmt
|
||||
var username_exists_stmt *sql.Stmt
|
||||
var change_group_stmt *sql.Stmt
|
||||
var create_profile_reply_stmt *sql.Stmt
|
||||
var edit_profile_reply_stmt *sql.Stmt
|
||||
var delete_profile_reply_stmt *sql.Stmt
|
||||
|
@ -48,8 +52,8 @@ var create_forum_stmt *sql.Stmt
|
|||
var delete_forum_stmt *sql.Stmt
|
||||
var update_forum_stmt *sql.Stmt
|
||||
|
||||
var custom_pages map[string]string = make(map[string]string)
|
||||
var templates = template.Must(template.ParseGlob("templates/*"))
|
||||
var custom_pages = template.Must(template.ParseGlob("pages/*"))
|
||||
var no_css_tmpl = template.CSS("")
|
||||
var staff_css_tmpl = template.CSS(staff_css)
|
||||
var groups map[int]Group = make(map[int]Group)
|
||||
|
@ -60,7 +64,7 @@ func init_database(err error) {
|
|||
if(dbpassword != ""){
|
||||
dbpassword = ":" + dbpassword
|
||||
}
|
||||
db, err = sql.Open("mysql",dbuser + dbpassword + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname)
|
||||
db, err = sql.Open("mysql",dbuser + dbpassword + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?collation=utf8mb4_general_ci")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -177,7 +181,7 @@ func init_database(err error) {
|
|||
// create_account_stmt, err = db.Prepare("INSERT INTO
|
||||
|
||||
log.Print("Preparing register statement.")
|
||||
register_stmt, err = db.Prepare("INSERT INTO users(`name`,`password`,`salt`,`group`,`is_super_admin`,`session`) VALUES(?,?,?,2,0,?)")
|
||||
register_stmt, err = db.Prepare("INSERT INTO users(`name`,`password`,`salt`,`group`,`is_super_admin`,`session`) VALUES(?,?,?," + strconv.Itoa(default_group) + ",0,?)")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -188,6 +192,12 @@ func init_database(err error) {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing change_group statement.")
|
||||
change_group_stmt, err = db.Prepare("UPDATE `users` SET `group` = ? WHERE `uid` = ?")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Preparing create_profile_reply statement.")
|
||||
create_profile_reply_stmt, err = db.Prepare("INSERT INTO users_replies(uid,content,parsed_content,createdAt,createdBy) VALUES(?,?,?,NOW(),?)")
|
||||
if err != nil {
|
||||
|
@ -285,30 +295,30 @@ func main(){
|
|||
var err error
|
||||
init_database(err);
|
||||
|
||||
log.Print("Loading the custom pages.")
|
||||
err = filepath.Walk("pages/", add_custom_page)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Loading the static files.")
|
||||
files, err := ioutil.ReadDir("./public")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
err = filepath.Walk("./public", func(path string, f os.FileInfo, err error) error {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
return nil
|
||||
}
|
||||
data, err := ioutil.ReadFile("./public/" + f.Name())
|
||||
|
||||
path = strings.Replace(path,"\\","/",-1)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path = strings.TrimPrefix(path,"public/")
|
||||
log.Print("Added the '" + path + "' static file.")
|
||||
static_files["/static/" + path] = SFile{data,0,int64(len(data)),mime.TypeByExtension(filepath.Ext("/public/" + path)),f,f.ModTime().UTC().Format(http.TimeFormat)}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Print("Added the '" + f.Name() + "' static file.")
|
||||
static_files["/static/" + f.Name()] = SFile{data,0,int64(len(data)),mime.TypeByExtension(filepath.Ext(f.Name())),f,f.ModTime().UTC().Format(http.TimeFormat)}
|
||||
}
|
||||
//parse_map["grinning"] = []byte("😀")
|
||||
//parse_map["grin"] = []byte("😁")
|
||||
//parse_map["joy"] = []byte("😂")
|
||||
|
||||
// In a directory to stop it clashing with the other paths
|
||||
http.HandleFunc("/static/", route_static)
|
||||
|
@ -359,7 +369,9 @@ func main(){
|
|||
http.HandleFunc("/profile/reply/edit/submit/", route_profile_reply_edit_submit)
|
||||
http.HandleFunc("/profile/reply/delete/submit/", route_profile_reply_delete_submit)
|
||||
//http.HandleFunc("/user/:id/edit/", route_logout)
|
||||
//http.HandleFunc("/user/:id/ban/", route_logout)
|
||||
http.HandleFunc("/users/ban/", route_ban)
|
||||
http.HandleFunc("/users/ban/submit/", route_ban_submit)
|
||||
http.HandleFunc("/users/unban/", route_unban)
|
||||
|
||||
// Admin
|
||||
http.HandleFunc("/panel/forums/", route_panel_forums)
|
||||
|
|
127
mod_routes.go
127
mod_routes.go
|
@ -47,7 +47,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
topic_content := html.EscapeString(r.PostFormValue("topic_content"))
|
||||
_, err = edit_topic_stmt.Exec(topic_name, topic_content, parse_message(topic_content), is_closed, tid)
|
||||
_, err = edit_topic_stmt.Exec(topic_name, preparse_message(topic_content), parse_message(html.EscapeString(preparse_message(topic_content))), is_closed, tid)
|
||||
if err != nil {
|
||||
InternalErrorJSQ(err,w,r,user,is_js)
|
||||
return
|
||||
|
@ -160,7 +160,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
content := html.EscapeString(r.PostFormValue("edit_item"))
|
||||
content := html.EscapeString(preparse_message(r.PostFormValue("edit_item")))
|
||||
_, err = edit_reply_stmt.Exec(content, parse_message(content), rid)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -262,7 +262,7 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
content := html.EscapeString(r.PostFormValue("edit_item"))
|
||||
content := html.EscapeString(preparse_message(r.PostFormValue("edit_item")))
|
||||
_, err = edit_profile_reply_stmt.Exec(content, parse_message(content), rid)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
|
@ -324,6 +324,127 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func route_ban(w http.ResponseWriter, r *http.Request) {
|
||||
user := SessionCheck(w,r)
|
||||
if !user.Is_Mod && !user.Is_Admin {
|
||||
NoPermissions(w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
var uname string
|
||||
err = db.QueryRow("SELECT name from users where uid = ?", uid).Scan(&uname)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The user you're trying to ban no longer exists.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
confirm_msg := "Are you sure you want to ban '" + uname + "'?"
|
||||
yousure := AreYouSure{"/users/ban/submit/" + strconv.Itoa(uid),confirm_msg}
|
||||
|
||||
pi := Page{"Ban User","ban-user",user,tList,yousure}
|
||||
templates.ExecuteTemplate(w,"areyousure.html", pi)
|
||||
}
|
||||
|
||||
func route_ban_submit(w http.ResponseWriter, r *http.Request) {
|
||||
user := SessionCheck(w,r)
|
||||
if !user.Is_Mod && !user.Is_Admin {
|
||||
NoPermissions(w,r,user)
|
||||
return
|
||||
}
|
||||
if r.FormValue("session") != user.Session {
|
||||
SecurityError(w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/ban/submit/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
var group int
|
||||
var is_super_admin bool
|
||||
err = db.QueryRow("SELECT `group`, `is_super_admin` from `users` where `uid` = ?", uid).Scan(&group, &is_super_admin)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The user you're trying to ban no longer exists.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if is_super_admin || groups[group].Is_Admin || groups[group].Is_Mod {
|
||||
LocalError("You may not ban another staff member.",w,r,user)
|
||||
return
|
||||
}
|
||||
if uid == user.ID {
|
||||
LocalError("You may not ban yourself.",w,r,user)
|
||||
return
|
||||
}
|
||||
if uid == -2 {
|
||||
LocalError("You may not ban me. Fine, I will offer up some guidance unto thee. Come to my lair, young one. /arcane-tower/",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if groups[group].Is_Banned {
|
||||
LocalError("The user you're trying to unban is already banned.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = change_group_stmt.Exec(4, uid)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func route_unban(w http.ResponseWriter, r *http.Request) {
|
||||
user := SessionCheck(w,r)
|
||||
if !user.Is_Mod && !user.Is_Admin {
|
||||
NoPermissions(w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
uid, err := strconv.Atoi(r.URL.Path[len("/users/unban/"):])
|
||||
if err != nil {
|
||||
LocalError("The provided User ID is not a valid number.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
var uname string
|
||||
var group int
|
||||
err = db.QueryRow("SELECT `name`, `group` from users where `uid` = ?", uid).Scan(&uname, &group)
|
||||
if err == sql.ErrNoRows {
|
||||
LocalError("The user you're trying to unban no longer exists.",w,r,user)
|
||||
return
|
||||
} else if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
if !groups[group].Is_Banned {
|
||||
LocalError("The user you're trying to unban isn't banned.",w,r,user)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = change_group_stmt.Exec(default_group, uid)
|
||||
if err != nil {
|
||||
InternalError(err,w,r,user)
|
||||
return
|
||||
}
|
||||
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func route_panel_forums(w http.ResponseWriter, r *http.Request){
|
||||
user := SessionCheck(w,r)
|
||||
if !user.Is_Admin {
|
||||
|
|
71
pages.go
71
pages.go
|
@ -1,9 +1,6 @@
|
|||
package main
|
||||
import "strings"
|
||||
import "os"
|
||||
import "log"
|
||||
import "io/ioutil"
|
||||
import "path/filepath"
|
||||
//import "regexp"
|
||||
|
||||
type Page struct
|
||||
{
|
||||
|
@ -27,31 +24,55 @@ type AreYouSure struct
|
|||
Message string
|
||||
}
|
||||
|
||||
func add_custom_page(path string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
func shortcode_to_unicode(msg string) string {
|
||||
//re := regexp.MustCompile(":(.):")
|
||||
msg = strings.Replace(msg,":grinning:","😀",-1)
|
||||
msg = strings.Replace(msg,":grin:","😁",-1)
|
||||
msg = strings.Replace(msg,":joy:","😂",-1)
|
||||
msg = strings.Replace(msg,":rofl:","🤣",-1)
|
||||
msg = strings.Replace(msg,":smiley:","😃",-1)
|
||||
msg = strings.Replace(msg,":smile:","😄",-1)
|
||||
msg = strings.Replace(msg,":sweat_smile:","😅",-1)
|
||||
msg = strings.Replace(msg,":laughing:","😆",-1)
|
||||
msg = strings.Replace(msg,":satisfied:","😆",-1)
|
||||
msg = strings.Replace(msg,":wink:","😉",-1)
|
||||
msg = strings.Replace(msg,":blush:","😊",-1)
|
||||
msg = strings.Replace(msg,":yum:","😋",-1)
|
||||
msg = strings.Replace(msg,":sunglasses:","😎",-1)
|
||||
msg = strings.Replace(msg,":heart_eyes:","😍",-1)
|
||||
msg = strings.Replace(msg,":kissing_heart:","😘",-1)
|
||||
msg = strings.Replace(msg,":kissing:","😗",-1)
|
||||
msg = strings.Replace(msg,":kissing_smiling_eyes:","😙",-1)
|
||||
msg = strings.Replace(msg,":kissing_closed_eyes:","😚",-1)
|
||||
msg = strings.Replace(msg,":relaxed:","☺️",-1)
|
||||
msg = strings.Replace(msg,":slight_smile:","🙂",-1)
|
||||
msg = strings.Replace(msg,":hugging:","🤗",-1)
|
||||
msg = strings.Replace(msg,":thinking:","🤔",-1)
|
||||
msg = strings.Replace(msg,":neutral_face:","😐",-1)
|
||||
msg = strings.Replace(msg,":expressionless:","😑",-1)
|
||||
msg = strings.Replace(msg,":no_mouth:","😶",-1)
|
||||
msg = strings.Replace(msg,":rolling_eyes:","🙄",-1)
|
||||
msg = strings.Replace(msg,":smirk:","😏",-1)
|
||||
msg = strings.Replace(msg,":persevere:","😣",-1)
|
||||
msg = strings.Replace(msg,":disappointed_relieved:","😥",-1)
|
||||
msg = strings.Replace(msg,":open_mouth:","😮",-1)
|
||||
msg = strings.Replace(msg,":zipper_mouth:","🤐",-1)
|
||||
msg = strings.Replace(msg,":hushed:","😯",-1)
|
||||
msg = strings.Replace(msg,":sleepy:","😪",-1)
|
||||
msg = strings.Replace(msg,":tired_face:","😫",-1)
|
||||
msg = strings.Replace(msg,":sleeping:","😴",-1)
|
||||
msg = strings.Replace(msg,":relieved:","😌",-1)
|
||||
msg = strings.Replace(msg,":nerd:","🤓",-1)
|
||||
return strings.Replace(msg,":stuck_out_tongue:","😛",-1)
|
||||
}
|
||||
|
||||
// Is this a directory..?
|
||||
fileInfo, err := os.Stat(path)
|
||||
is_dir := fileInfo.IsDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if is_dir {
|
||||
return err
|
||||
}
|
||||
|
||||
custom_page, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Print("Loaded the '" + path + "' page.")
|
||||
name := strings.TrimSuffix(path, filepath.Ext(path))
|
||||
custom_pages[name] = string(custom_page)
|
||||
return nil
|
||||
func preparse_message(msg string) string {
|
||||
return shortcode_to_unicode(msg)
|
||||
}
|
||||
|
||||
func parse_message(msg string) string {
|
||||
msg = strings.Replace(msg,":)","😀",-1)
|
||||
msg = strings.Replace(msg,":D","😃",-1)
|
||||
//msg = shortcode_to_unicode(msg)
|
||||
return strings.Replace(msg,"\n","<br>",-1)
|
||||
}
|
|
@ -1 +1,6 @@
|
|||
<div class="rowitem">Testing</div>
|
||||
{{template "header.html" . }}
|
||||
<div class="rowblock">
|
||||
<div class="rowitem">{{.Title}}</div>
|
||||
</div>
|
||||
<div class="rowblock">Testing</div>
|
||||
{{template "footer.html" . }}
|
|
@ -0,0 +1,14 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2011-2012 by linyows <linyows@gmail.com>
|
||||
|
||||
Permission is hereby granted, freef charge, to any personbtaining a copyf this software and associated documentation files (the 'Software'),
|
||||
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copiesf the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copiesr substantial portionsf the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,99 @@
|
|||
*NOTICE* This extends the [original plugin](https://github.com/diy/jquery-emojiarea) by groups. (See screenshot at dropdown menu)
|
||||
|
||||
#### About this extension
|
||||
This was originally created for my project *The Msngr*, which should have become an open-source end-to-end encrypted messanger. I am always happy about an attribution to me and my website, e.g. [\<a href="https://pius-ladenburger.de">Pius Ladenburger\</a>](https://pius-ladenburger.de).
|
||||
|
||||
I hope this helps you and makes your day easier.
|
||||
|
||||
#.emojiarea()
|
||||
|
||||
A small **6kb** [jQuery](http://jquery.com/) plugin for turning regular textareas into ones that support emojis, WYSIWYG style! Set up a list of available emojis, call `$('textarea').emojiarea()` and you're done (basically). There's a plain-text fallback, so if the browser doesn't support [contentEditable](http://caniuse.com/#search=contenteditable), it will degrade gracefully—the user will still be able to use the dropdown menu of emojis.
|
||||
|
||||
![Screenshot](http://i.imgur.com/C4Z8F.gif)
|
||||
|
||||
```html
|
||||
<textarea>Hello :smile:</textarea>
|
||||
<script type="text/javascript">$('textarea').emojiarea();</script>
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Dropdown Menu
|
||||
|
||||
![Dropdown Screenshot](http://i.imgur.com/EuTTpHk.png)
|
||||
|
||||
By default, the plugin will insert a link after the editor that toggles the emoji selector when clicked.
|
||||
|
||||
```html
|
||||
<a href="javascript:void(0)" class="emoji-button">Emojis</a>
|
||||
```
|
||||
|
||||
If you wish change this behavior and have the button placed before the editor, or change the label of the link, use:
|
||||
|
||||
```javascript
|
||||
$('textarea').emojiarea({
|
||||
buttonLabel: 'Add Emoji',
|
||||
buttonPosition: 'before'
|
||||
});
|
||||
```
|
||||
|
||||
Alternatively, if you wish to use your own button:
|
||||
|
||||
```javascript
|
||||
$('textarea').emojiarea({button: '#your-button'});
|
||||
```
|
||||
|
||||
For customizing the visual appearance, see the [CSS / Skinning](#css--skinning) section.
|
||||
|
||||
### Available Emojis
|
||||
|
||||
```javascript
|
||||
$.emojiarea.path = '/path/to/folder/with/icons';
|
||||
$.emojiarea.icons = {
|
||||
':smile:' : 'smile.png',
|
||||
':angry:' : 'angry.png',
|
||||
':flushed:' : 'flushed.png',
|
||||
':neckbeard:' : 'neckbeard.png',
|
||||
':laughing:' : 'laughing.png'
|
||||
};
|
||||
```
|
||||
|
||||
### Defaults
|
||||
|
||||
If you wish to set the defaults for `$().emojiarea()`, extend `$.emojiarea.defaults` like so:
|
||||
|
||||
```javascript
|
||||
$.extend($.emojiarea.defaults, {
|
||||
buttonPosition: 'before'
|
||||
});
|
||||
```
|
||||
|
||||
For a basic set of emojis, see "packs/basic".
|
||||
|
||||
## CSS / Skinning
|
||||
|
||||
See [jquery.emojiarea.css](https://github.com/diy/jquery-emojiarea/blob/master/jquery.emojiarea.css) for the few fundamental CSS styles needed for this to work.
|
||||
|
||||
Basically, you'll want to adjust the following styles:
|
||||
|
||||
```css
|
||||
.emoji-wysiwyg-editor /* the editor box itself */
|
||||
.emoji-menu > div /* the dropdown menu with options */
|
||||
.emoji-wysiwyg-editor img /* the emoji images in the editor */
|
||||
```
|
||||
|
||||
## Footnotes
|
||||
|
||||
* Huge props to [Tim Down](http://stackoverflow.com/users/96100/tim-down) for the many insightful answers on Stack Overflow having to deal with cross-browser selection handling.
|
||||
* If you have a really rad set of emojis and would like to share, please fork this, add them to "packs/", and submit a pull request!
|
||||
* For a giant list of emojis (used by Github, Basecamp, et al), see ["Emoji cheat sheet"](http://www.emoji-cheat-sheet.com/).
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2012 DIY Co and 2015 Pius Ladenburger
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
I am always happy about an attribution to me and my website, e.g. [\<a href="https://pius-ladenburger.de">Pius Ladenburger\</a>](https://pius-ladenburger.de)
|
|
@ -0,0 +1,862 @@
|
|||
$.emojiarea.path = '/static/smilies/emojiarea';
|
||||
$.emojiarea.icons = [{"name" : "<i class='icon-smile'></i>", "icons" : {':bowtie:' : 'bowtie.png',
|
||||
':smile:' : 'smile.png',
|
||||
':laughing:' : 'laughing.png',
|
||||
':blush:' : 'blush.png',
|
||||
':smiley:' : 'smiley.png',
|
||||
':relaxed:' : 'relaxed.png',
|
||||
':smirk:' : 'smirk.png',
|
||||
':heart_eyes:' : 'heart_eyes.png',
|
||||
':kissing_heart:' : 'kissing_heart.png',
|
||||
':kissing_closed_eyes:' : 'kissing_closed_eyes.png',
|
||||
':flushed:' : 'flushed.png',
|
||||
':relieved:' : 'relieved.png',
|
||||
':satisfied:' : 'satisfied.png',
|
||||
':grin:' : 'grin.png',
|
||||
':wink:' : 'wink.png',
|
||||
':stuck_out_tongue_winking_eye:' : 'stuck_out_tongue_winking_eye.png',
|
||||
':stuck_out_tongue_closed_eyes:' : 'stuck_out_tongue_closed_eyes.png',
|
||||
':grinning:' : 'grinning.png',
|
||||
':kissing:' : 'kissing.png',
|
||||
':kissing_smiling_eyes:' : 'kissing_smiling_eyes.png',
|
||||
':stuck_out_tongue:' : 'stuck_out_tongue.png',
|
||||
':sleeping:' : 'sleeping.png',
|
||||
':worried:' : 'worried.png',
|
||||
':frowning:' : 'frowning.png',
|
||||
':anguished:' : 'anguished.png',
|
||||
':open_mouth:' : 'open_mouth.png',
|
||||
':grimacing:' : 'grimacing.png',
|
||||
':confused:' : 'confused.png',
|
||||
':hushed:' : 'hushed.png',
|
||||
':expressionless:' : 'expressionless.png',
|
||||
':unamused:' : 'unamused.png',
|
||||
':sweat_smile:' : 'sweat_smile.png',
|
||||
':sweat:' : 'sweat.png',
|
||||
':weary:' : 'weary.png',
|
||||
':pensive:' : 'pensive.png',
|
||||
':disappointed:' : 'disappointed.png',
|
||||
':confounded:' : 'confounded.png',
|
||||
':fearful:' : 'fearful.png',
|
||||
':cold_sweat:' : 'cold_sweat.png',
|
||||
':persevere:' : 'persevere.png',
|
||||
':joy:' : 'joy.png',
|
||||
':astonished:' : 'astonished.png',
|
||||
':scream:' : 'scream.png',
|
||||
':neckbeard:' : 'neckbeard.png',
|
||||
':tired_face:' : 'tired_face.png',
|
||||
':angry:' : 'angry.png',
|
||||
':rage:' : 'rage.png',
|
||||
':triumph:' : 'triumph.png',
|
||||
':sleepy:' : 'sleepy.png',
|
||||
':yum:' : 'yum.png',
|
||||
':mask:' : 'mask.png',
|
||||
':sunglasses:' : 'sunglasses.png',
|
||||
':dizzy_face:' : 'dizzy_face.png',
|
||||
':imp:' : 'imp.png',
|
||||
':smiling_imp:' : 'smiling_imp.png',
|
||||
':neutral_face:' : 'neutral_face.png',
|
||||
':no_mouth:' : 'no_mouth.png',
|
||||
':innocent:' : 'innocent.png',
|
||||
':alien:' : 'alien.png',
|
||||
':yellow_heart:' : 'yellow_heart.png',
|
||||
':blue_heart:' : 'blue_heart.png',
|
||||
':purple_heart:' : 'purple_heart.png',
|
||||
':heart:' : 'heart.png',
|
||||
':green_heart:' : 'green_heart.png',
|
||||
':broken_heart:' : 'broken_heart.png',
|
||||
':heartbeat:' : 'heartbeat.png',
|
||||
':heartpulse:' : 'heartpulse.png',
|
||||
':two_hearts:' : 'two_hearts.png',
|
||||
':revolving_hearts:' : 'revolving_hearts.png',
|
||||
':cupid:' : 'cupid.png',
|
||||
':sparkling_heart:' : 'sparkling_heart.png',
|
||||
':sparkles:' : 'sparkles.png',
|
||||
':star:' : 'star.png',
|
||||
':star2:' : 'star2.png',
|
||||
':dizzy:' : 'dizzy.png',
|
||||
':boom:' : 'boom.png',
|
||||
':collision:' : 'collision.png',
|
||||
':anger:' : 'anger.png',
|
||||
':exclamation:' : 'exclamation.png',
|
||||
':question:' : 'question.png',
|
||||
':grey_exclamation:' : 'grey_exclamation.png',
|
||||
':grey_question:' : 'grey_question.png',
|
||||
':zzz:' : 'zzz.png',
|
||||
':dash:' : 'dash.png',
|
||||
':sweat_drops:' : 'sweat_drops.png',
|
||||
':notes:' : 'notes.png',
|
||||
':musical_note:' : 'musical_note.png',
|
||||
':fire:' : 'fire.png',
|
||||
':hankey:' : 'hankey.png',
|
||||
':poop:' : 'poop.png',
|
||||
':shit:' : 'shit.png',
|
||||
':+1:' : '+1.png',
|
||||
':thumbsup:' : 'thumbsup.png',
|
||||
':-1:' : '-1.png',
|
||||
':thumbsdown:' : 'thumbsdown.png',
|
||||
':ok_hand:' : 'ok_hand.png',
|
||||
':punch:' : 'punch.png',
|
||||
':facepunch:' : 'facepunch.png',
|
||||
':fist:' : 'fist.png',
|
||||
':v:' : 'v.png',
|
||||
':wave:' : 'wave.png',
|
||||
':hand:' : 'hand.png',
|
||||
':raised_hand:' : 'raised_hand.png',
|
||||
':open_hands:' : 'open_hands.png',
|
||||
':point_up:' : 'point_up.png',
|
||||
':point_down:' : 'point_down.png',
|
||||
':point_left:' : 'point_left.png',
|
||||
':point_right:' : 'point_right.png',
|
||||
':raised_hands:' : 'raised_hands.png',
|
||||
':pray:' : 'pray.png',
|
||||
':point_up_2:' : 'point_up_2.png',
|
||||
':clap:' : 'clap.png',
|
||||
':muscle:' : 'muscle.png',
|
||||
':metal:' : 'metal.png',
|
||||
':walking:' : 'walking.png',
|
||||
':runner:' : 'runner.png',
|
||||
':running:' : 'running.png',
|
||||
':couple:' : 'couple.png',
|
||||
':family:' : 'family.png',
|
||||
':two_men_holding_hands:' : 'two_men_holding_hands.png',
|
||||
':two_women_holding_hands:' : 'two_women_holding_hands.png',
|
||||
':ok_woman:' : 'ok_woman.png',
|
||||
':no_good:' : 'no_good.png',
|
||||
':information_desk_person:' : 'information_desk_person.png',
|
||||
':bride_with_veil:' : 'bride_with_veil.png',
|
||||
':person_with_pouting_face:' : 'person_with_pouting_face.png',
|
||||
':person_frowning:' : 'person_frowning.png',
|
||||
':bow:' : 'bow.png',
|
||||
':couplekiss:' : 'couplekiss.png',
|
||||
':couple_with_heart:' : 'couple_with_heart.png',
|
||||
':massage:' : 'massage.png',
|
||||
':haircut:' : 'haircut.png',
|
||||
':nail_care:' : 'nail_care.png',
|
||||
':boy:' : 'boy.png',
|
||||
':girl:' : 'girl.png',
|
||||
':woman:' : 'woman.png',
|
||||
':man:' : 'man.png',
|
||||
':baby:' : 'baby.png',
|
||||
':older_woman:' : 'older_woman.png',
|
||||
':older_man:' : 'older_man.png',
|
||||
':person_with_blond_hair:' : 'person_with_blond_hair.png',
|
||||
':man_with_gua_pi_mao:' : 'man_with_gua_pi_mao.png',
|
||||
':man_with_turban:' : 'man_with_turban.png',
|
||||
':construction_worker:' : 'construction_worker.png',
|
||||
':cop:' : 'cop.png',
|
||||
':angel:' : 'angel.png',
|
||||
':princess:' : 'princess.png',
|
||||
':smiley_cat:' : 'smiley_cat.png',
|
||||
':smile_cat:' : 'smile_cat.png',
|
||||
':heart_eyes_cat:' : 'heart_eyes_cat.png',
|
||||
':kissing_cat:' : 'kissing_cat.png',
|
||||
':smirk_cat:' : 'smirk_cat.png',
|
||||
':scream_cat:' : 'scream_cat.png',
|
||||
':crying_cat_face:' : 'crying_cat_face.png',
|
||||
':joy_cat:' : 'joy_cat.png',
|
||||
':pouting_cat:' : 'pouting_cat.png',
|
||||
':japanese_ogre:' : 'japanese_ogre.png',
|
||||
':japanese_goblin:' : 'japanese_goblin.png',
|
||||
':see_no_evil:' : 'see_no_evil.png',
|
||||
':hear_no_evil:' : 'hear_no_evil.png',
|
||||
':speak_no_evil:' : 'speak_no_evil.png',
|
||||
':guardsman:' : 'guardsman.png',
|
||||
':skull:' : 'skull.png',
|
||||
':feet:' : 'feet.png',
|
||||
':lips:' : 'lips.png',
|
||||
':kiss:' : 'kiss.png',
|
||||
':droplet:' : 'droplet.png',
|
||||
':ear:' : 'ear.png',
|
||||
':eyes:' : 'eyes.png',
|
||||
':nose:' : 'nose.png',
|
||||
':tongue:' : 'tongue.png',
|
||||
':love_letter:' : 'love_letter.png',
|
||||
':bust_in_silhouette:' : 'bust_in_silhouette.png',
|
||||
':busts_in_silhouette:' : 'busts_in_silhouette.png',
|
||||
':speech_balloon:' : 'speech_balloon.png',
|
||||
':thought_balloon:' : 'thought_balloon.png',
|
||||
':feelsgood:' : 'feelsgood.png',
|
||||
':finnadie:' : 'finnadie.png',
|
||||
':goberserk:' : 'goberserk.png',
|
||||
':godmode:' : 'godmode.png',
|
||||
':hurtrealbad:' : 'hurtrealbad.png',
|
||||
':rage1:' : 'rage1.png',
|
||||
':rage2:' : 'rage2.png',
|
||||
':rage3:' : 'rage3.png',
|
||||
':rage4:' : 'rage4.png',
|
||||
':suspect:' : 'suspect.png',
|
||||
':trollface:' : 'trollface.png'}},
|
||||
{'name': '<i class="icon-tree"></i>', 'icons' : {':sunny:' : 'sunny.png',
|
||||
':umbrella:' : 'umbrella.png',
|
||||
':cloud:' : 'cloud.png',
|
||||
':snowflake:' : 'snowflake.png',
|
||||
':snowman:' : 'snowman.png',
|
||||
':zap:' : 'zap.png',
|
||||
':cyclone:' : 'cyclone.png',
|
||||
':foggy:' : 'foggy.png',
|
||||
':ocean:' : 'ocean.png',
|
||||
':cat:' : 'cat.png',
|
||||
':dog:' : 'dog.png',
|
||||
':mouse:' : 'mouse.png',
|
||||
':hamster:' : 'hamster.png',
|
||||
':rabbit:' : 'rabbit.png',
|
||||
':wolf:' : 'wolf.png',
|
||||
':frog:' : 'frog.png',
|
||||
':tiger:' : 'tiger.png',
|
||||
':koala:' : 'koala.png',
|
||||
':bear:' : 'bear.png',
|
||||
':pig:' : 'pig.png',
|
||||
':pig_nose:' : 'pig_nose.png',
|
||||
':cow:' : 'cow.png',
|
||||
':boar:' : 'boar.png',
|
||||
':monkey_face:' : 'monkey_face.png',
|
||||
':monkey:' : 'monkey.png',
|
||||
':horse:' : 'horse.png',
|
||||
':racehorse:' : 'racehorse.png',
|
||||
':camel:' : 'camel.png',
|
||||
':sheep:' : 'sheep.png',
|
||||
':elephant:' : 'elephant.png',
|
||||
':panda_face:' : 'panda_face.png',
|
||||
':snake:' : 'snake.png',
|
||||
':bird:' : 'bird.png',
|
||||
':baby_chick:' : 'baby_chick.png',
|
||||
':hatched_chick:' : 'hatched_chick.png',
|
||||
':hatching_chick:' : 'hatching_chick.png',
|
||||
':chicken:' : 'chicken.png',
|
||||
':penguin:' : 'penguin.png',
|
||||
':turtle:' : 'turtle.png',
|
||||
':bug:' : 'bug.png',
|
||||
':honeybee:' : 'honeybee.png',
|
||||
':ant:' : 'ant.png',
|
||||
':beetle:' : 'beetle.png',
|
||||
':snail:' : 'snail.png',
|
||||
':octopus:' : 'octopus.png',
|
||||
':tropical_fish:' : 'tropical_fish.png',
|
||||
':fish:' : 'fish.png',
|
||||
':whale:' : 'whale.png',
|
||||
':whale2:' : 'whale2.png',
|
||||
':dolphin:' : 'dolphin.png',
|
||||
':cow2:' : 'cow2.png',
|
||||
':ram:' : 'ram.png',
|
||||
':rat:' : 'rat.png',
|
||||
':water_buffalo:' : 'water_buffalo.png',
|
||||
':tiger2:' : 'tiger2.png',
|
||||
':rabbit2:' : 'rabbit2.png',
|
||||
':dragon:' : 'dragon.png',
|
||||
':goat:' : 'goat.png',
|
||||
':rooster:' : 'rooster.png',
|
||||
':dog2:' : 'dog2.png',
|
||||
':pig2:' : 'pig2.png',
|
||||
':mouse2:' : 'mouse2.png',
|
||||
':ox:' : 'ox.png',
|
||||
':dragon_face:' : 'dragon_face.png',
|
||||
':blowfish:' : 'blowfish.png',
|
||||
':crocodile:' : 'crocodile.png',
|
||||
':dromedary_camel:' : 'dromedary_camel.png',
|
||||
':leopard:' : 'leopard.png',
|
||||
':cat2:' : 'cat2.png',
|
||||
':poodle:' : 'poodle.png',
|
||||
':paw_prints:' : 'paw_prints.png',
|
||||
':bouquet:' : 'bouquet.png',
|
||||
':cherry_blossom:' : 'cherry_blossom.png',
|
||||
':tulip:' : 'tulip.png',
|
||||
':four_leaf_clover:' : 'four_leaf_clover.png',
|
||||
':rose:' : 'rose.png',
|
||||
':sunflower:' : 'sunflower.png',
|
||||
':hibiscus:' : 'hibiscus.png',
|
||||
':maple_leaf:' : 'maple_leaf.png',
|
||||
':leaves:' : 'leaves.png',
|
||||
':fallen_leaf:' : 'fallen_leaf.png',
|
||||
':herb:' : 'herb.png',
|
||||
':mushroom:' : 'mushroom.png',
|
||||
':cactus:' : 'cactus.png',
|
||||
':palm_tree:' : 'palm_tree.png',
|
||||
':evergreen_tree:' : 'evergreen_tree.png',
|
||||
':deciduous_tree:' : 'deciduous_tree.png',
|
||||
':chestnut:' : 'chestnut.png',
|
||||
':seedling:' : 'seedling.png',
|
||||
':blossom:' : 'blossom.png',
|
||||
':ear_of_rice:' : 'ear_of_rice.png',
|
||||
':shell:' : 'shell.png',
|
||||
':globe_with_meridians:' : 'globe_with_meridians.png',
|
||||
':sun_with_face:' : 'sun_with_face.png',
|
||||
':full_moon_with_face:' : 'full_moon_with_face.png',
|
||||
':new_moon_with_face:' : 'new_moon_with_face.png',
|
||||
':new_moon:' : 'new_moon.png',
|
||||
':waxing_crescent_moon:' : 'waxing_crescent_moon.png',
|
||||
':first_quarter_moon:' : 'first_quarter_moon.png',
|
||||
':waxing_gibbous_moon:' : 'waxing_gibbous_moon.png',
|
||||
':full_moon:' : 'full_moon.png',
|
||||
':waning_gibbous_moon:' : 'waning_gibbous_moon.png',
|
||||
':last_quarter_moon:' : 'last_quarter_moon.png',
|
||||
':waning_crescent_moon:' : 'waning_crescent_moon.png',
|
||||
':last_quarter_moon_with_face:' : 'last_quarter_moon_with_face.png',
|
||||
':first_quarter_moon_with_face:' : 'first_quarter_moon_with_face.png',
|
||||
':moon:' : 'moon.png',
|
||||
':earth_africa:' : 'earth_africa.png',
|
||||
':earth_americas:' : 'earth_americas.png',
|
||||
':earth_asia:' : 'earth_asia.png',
|
||||
':volcano:' : 'volcano.png',
|
||||
':milky_way:' : 'milky_way.png',
|
||||
':partly_sunny:' : 'partly_sunny.png',
|
||||
':octocat:' : 'octocat.png'}},
|
||||
{'name': '<i class="icon-bell-alt"></i>', 'icons' : {':squirrel:' : 'squirrel.png',
|
||||
':bamboo:' : 'bamboo.png',
|
||||
':gift_heart:' : 'gift_heart.png',
|
||||
':dolls:' : 'dolls.png',
|
||||
':school_satchel:' : 'school_satchel.png',
|
||||
':mortar_board:' : 'mortar_board.png',
|
||||
':flags:' : 'flags.png',
|
||||
':fireworks:' : 'fireworks.png',
|
||||
':sparkler:' : 'sparkler.png',
|
||||
':wind_chime:' : 'wind_chime.png',
|
||||
':rice_scene:' : 'rice_scene.png',
|
||||
':jack_o_lantern:' : 'jack_o_lantern.png',
|
||||
':ghost:' : 'ghost.png',
|
||||
':santa:' : 'santa.png',
|
||||
':christmas_tree:' : 'christmas_tree.png',
|
||||
':gift:' : 'gift.png',
|
||||
':bell:' : 'bell.png',
|
||||
':no_bell:' : 'no_bell.png',
|
||||
':tanabata_tree:' : 'tanabata_tree.png',
|
||||
':tada:' : 'tada.png',
|
||||
':confetti_ball:' : 'confetti_ball.png',
|
||||
':balloon:' : 'balloon.png',
|
||||
':crystal_ball:' : 'crystal_ball.png',
|
||||
':cd:' : 'cd.png',
|
||||
':dvd:' : 'dvd.png',
|
||||
':floppy_disk:' : 'floppy_disk.png',
|
||||
':camera:' : 'camera.png',
|
||||
':video_camera:' : 'video_camera.png',
|
||||
':movie_camera:' : 'movie_camera.png',
|
||||
':computer:' : 'computer.png',
|
||||
':tv:' : 'tv.png',
|
||||
':iphone:' : 'iphone.png',
|
||||
':phone:' : 'phone.png',
|
||||
':telephone:' : 'telephone.png',
|
||||
':telephone_receiver:' : 'telephone_receiver.png',
|
||||
':pager:' : 'pager.png',
|
||||
':fax:' : 'fax.png',
|
||||
':minidisc:' : 'minidisc.png',
|
||||
':vhs:' : 'vhs.png',
|
||||
':sound:' : 'sound.png',
|
||||
':speaker:' : 'speaker.png',
|
||||
':mute:' : 'mute.png',
|
||||
':loudspeaker:' : 'loudspeaker.png',
|
||||
':mega:' : 'mega.png',
|
||||
':hourglass:' : 'hourglass.png',
|
||||
':hourglass_flowing_sand:' : 'hourglass_flowing_sand.png',
|
||||
':alarm_clock:' : 'alarm_clock.png',
|
||||
':watch:' : 'watch.png',
|
||||
':radio:' : 'radio.png',
|
||||
':satellite:' : 'satellite.png',
|
||||
':loop:' : 'loop.png',
|
||||
':mag:' : 'mag.png',
|
||||
':mag_right:' : 'mag_right.png',
|
||||
':unlock:' : 'unlock.png',
|
||||
':lock:' : 'lock.png',
|
||||
':lock_with_ink_pen:' : 'lock_with_ink_pen.png',
|
||||
':closed_lock_with_key:' : 'closed_lock_with_key.png',
|
||||
':key:' : 'key.png',
|
||||
':bulb:' : 'bulb.png',
|
||||
':flashlight:' : 'flashlight.png',
|
||||
':high_brightness:' : 'high_brightness.png',
|
||||
':low_brightness:' : 'low_brightness.png',
|
||||
':electric_plug:' : 'electric_plug.png',
|
||||
':battery:' : 'battery.png',
|
||||
':calling:' : 'calling.png',
|
||||
':email:' : 'email.png',
|
||||
':mailbox:' : 'mailbox.png',
|
||||
':postbox:' : 'postbox.png',
|
||||
':bath:' : 'bath.png',
|
||||
':bathtub:' : 'bathtub.png',
|
||||
':shower:' : 'shower.png',
|
||||
':toilet:' : 'toilet.png',
|
||||
':wrench:' : 'wrench.png',
|
||||
':nut_and_bolt:' : 'nut_and_bolt.png',
|
||||
':hammer:' : 'hammer.png',
|
||||
':seat:' : 'seat.png',
|
||||
':moneybag:' : 'moneybag.png',
|
||||
':yen:' : 'yen.png',
|
||||
':dollar:' : 'dollar.png',
|
||||
':pound:' : 'pound.png',
|
||||
':euro:' : 'euro.png',
|
||||
':credit_card:' : 'credit_card.png',
|
||||
':money_with_wings:' : 'money_with_wings.png',
|
||||
':e-mail:' : 'e-mail.png',
|
||||
':inbox_tray:' : 'inbox_tray.png',
|
||||
':outbox_tray:' : 'outbox_tray.png',
|
||||
':envelope:' : 'envelope.png',
|
||||
':incoming_envelope:' : 'incoming_envelope.png',
|
||||
':postal_horn:' : 'postal_horn.png',
|
||||
':mailbox_closed:' : 'mailbox_closed.png',
|
||||
':mailbox_with_mail:' : 'mailbox_with_mail.png',
|
||||
':mailbox_with_no_mail:' : 'mailbox_with_no_mail.png',
|
||||
':door:' : 'door.png',
|
||||
':smoking:' : 'smoking.png',
|
||||
':bomb:' : 'bomb.png',
|
||||
':gun:' : 'gun.png',
|
||||
':hocho:' : 'hocho.png',
|
||||
':pill:' : 'pill.png',
|
||||
':syringe:' : 'syringe.png',
|
||||
':page_facing_up:' : 'page_facing_up.png',
|
||||
':page_with_curl:' : 'page_with_curl.png',
|
||||
':bookmark_tabs:' : 'bookmark_tabs.png',
|
||||
':bar_chart:' : 'bar_chart.png',
|
||||
':chart_with_upwards_trend:' : 'chart_with_upwards_trend.png',
|
||||
':chart_with_downwards_trend:' : 'chart_with_downwards_trend.png',
|
||||
':scroll:' : 'scroll.png',
|
||||
':clipboard:' : 'clipboard.png',
|
||||
':calendar:' : 'calendar.png',
|
||||
':date:' : 'date.png',
|
||||
':card_index:' : 'card_index.png',
|
||||
':file_folder:' : 'file_folder.png',
|
||||
':open_file_folder:' : 'open_file_folder.png',
|
||||
':scissors:' : 'scissors.png',
|
||||
':pushpin:' : 'pushpin.png',
|
||||
':paperclip:' : 'paperclip.png',
|
||||
':black_nib:' : 'black_nib.png',
|
||||
':pencil2:' : 'pencil2.png',
|
||||
':straight_ruler:' : 'straight_ruler.png',
|
||||
':triangular_ruler:' : 'triangular_ruler.png',
|
||||
':closed_book:' : 'closed_book.png',
|
||||
':green_book:' : 'green_book.png',
|
||||
':blue_book:' : 'blue_book.png',
|
||||
':orange_book:' : 'orange_book.png',
|
||||
':notebook:' : 'notebook.png',
|
||||
':notebook_with_decorative_cover:' : 'notebook_with_decorative_cover.png',
|
||||
':ledger:' : 'ledger.png',
|
||||
':books:' : 'books.png',
|
||||
':bookmark:' : 'bookmark.png',
|
||||
':name_badge:' : 'name_badge.png',
|
||||
':microscope:' : 'microscope.png',
|
||||
':telescope:' : 'telescope.png',
|
||||
':newspaper:' : 'newspaper.png',
|
||||
':football:' : 'football.png',
|
||||
':basketball:' : 'basketball.png',
|
||||
':soccer:' : 'soccer.png',
|
||||
':baseball:' : 'baseball.png',
|
||||
':tennis:' : 'tennis.png',
|
||||
':8ball:' : '8ball.png',
|
||||
':rugby_football:' : 'rugby_football.png',
|
||||
':bowling:' : 'bowling.png',
|
||||
':golf:' : 'golf.png',
|
||||
':mountain_bicyclist:' : 'mountain_bicyclist.png',
|
||||
':bicyclist:' : 'bicyclist.png',
|
||||
':horse_racing:' : 'horse_racing.png',
|
||||
':snowboarder:' : 'snowboarder.png',
|
||||
':swimmer:' : 'swimmer.png',
|
||||
':surfer:' : 'surfer.png',
|
||||
':ski:' : 'ski.png',
|
||||
':spades:' : 'spades.png',
|
||||
':hearts:' : 'hearts.png',
|
||||
':clubs:' : 'clubs.png',
|
||||
':diamonds:' : 'diamonds.png',
|
||||
':gem:' : 'gem.png',
|
||||
':ring:' : 'ring.png',
|
||||
':trophy:' : 'trophy.png',
|
||||
':musical_score:' : 'musical_score.png',
|
||||
':musical_keyboard:' : 'musical_keyboard.png',
|
||||
':violin:' : 'violin.png',
|
||||
':space_invader:' : 'space_invader.png',
|
||||
':video_game:' : 'video_game.png',
|
||||
':black_joker:' : 'black_joker.png',
|
||||
':flower_playing_cards:' : 'flower_playing_cards.png',
|
||||
':game_die:' : 'game_die.png',
|
||||
':dart:' : 'dart.png',
|
||||
':mahjong:' : 'mahjong.png',
|
||||
':clapper:' : 'clapper.png',
|
||||
':memo:' : 'memo.png',
|
||||
':pencil:' : 'pencil.png',
|
||||
':book:' : 'book.png',
|
||||
':art:' : 'art.png',
|
||||
':microphone:' : 'microphone.png',
|
||||
':headphones:' : 'headphones.png',
|
||||
':trumpet:' : 'trumpet.png',
|
||||
':saxophone:' : 'saxophone.png',
|
||||
':guitar:' : 'guitar.png',
|
||||
':shoe:' : 'shoe.png',
|
||||
':sandal:' : 'sandal.png',
|
||||
':high_heel:' : 'high_heel.png',
|
||||
':lipstick:' : 'lipstick.png',
|
||||
':boot:' : 'boot.png',
|
||||
':shirt:' : 'shirt.png',
|
||||
':tshirt:' : 'tshirt.png',
|
||||
':necktie:' : 'necktie.png',
|
||||
':womans_clothes:' : 'womans_clothes.png',
|
||||
':dress:' : 'dress.png',
|
||||
':running_shirt_with_sash:' : 'running_shirt_with_sash.png',
|
||||
':jeans:' : 'jeans.png',
|
||||
':kimono:' : 'kimono.png',
|
||||
':bikini:' : 'bikini.png',
|
||||
':ribbon:' : 'ribbon.png',
|
||||
':tophat:' : 'tophat.png',
|
||||
':crown:' : 'crown.png',
|
||||
':womans_hat:' : 'womans_hat.png',
|
||||
':mans_shoe:' : 'mans_shoe.png',
|
||||
':closed_umbrella:' : 'closed_umbrella.png',
|
||||
':briefcase:' : 'briefcase.png',
|
||||
':handbag:' : 'handbag.png',
|
||||
':pouch:' : 'pouch.png',
|
||||
':purse:' : 'purse.png',
|
||||
':eyeglasses:' : 'eyeglasses.png',
|
||||
':fishing_pole_and_fish:' : 'fishing_pole_and_fish.png',
|
||||
':coffee:' : 'coffee.png',
|
||||
':tea:' : 'tea.png',
|
||||
':sake:' : 'sake.png',
|
||||
':baby_bottle:' : 'baby_bottle.png',
|
||||
':beer:' : 'beer.png',
|
||||
':beers:' : 'beers.png',
|
||||
':cocktail:' : 'cocktail.png',
|
||||
':tropical_drink:' : 'tropical_drink.png',
|
||||
':wine_glass:' : 'wine_glass.png',
|
||||
':fork_and_knife:' : 'fork_and_knife.png',
|
||||
':pizza:' : 'pizza.png',
|
||||
':hamburger:' : 'hamburger.png',
|
||||
':fries:' : 'fries.png',
|
||||
':poultry_leg:' : 'poultry_leg.png',
|
||||
':meat_on_bone:' : 'meat_on_bone.png',
|
||||
':spaghetti:' : 'spaghetti.png',
|
||||
':curry:' : 'curry.png',
|
||||
':fried_shrimp:' : 'fried_shrimp.png',
|
||||
':bento:' : 'bento.png',
|
||||
':sushi:' : 'sushi.png',
|
||||
':fish_cake:' : 'fish_cake.png',
|
||||
':rice_ball:' : 'rice_ball.png',
|
||||
':rice_cracker:' : 'rice_cracker.png',
|
||||
':rice:' : 'rice.png',
|
||||
':ramen:' : 'ramen.png',
|
||||
':stew:' : 'stew.png',
|
||||
':oden:' : 'oden.png',
|
||||
':dango:' : 'dango.png',
|
||||
':egg:' : 'egg.png',
|
||||
':bread:' : 'bread.png',
|
||||
':doughnut:' : 'doughnut.png',
|
||||
':custard:' : 'custard.png',
|
||||
':icecream:' : 'icecream.png',
|
||||
':ice_cream:' : 'ice_cream.png',
|
||||
':shaved_ice:' : 'shaved_ice.png',
|
||||
':birthday:' : 'birthday.png',
|
||||
':cake:' : 'cake.png',
|
||||
':cookie:' : 'cookie.png',
|
||||
':chocolate_bar:' : 'chocolate_bar.png',
|
||||
':candy:' : 'candy.png',
|
||||
':lollipop:' : 'lollipop.png',
|
||||
':honey_pot:' : 'honey_pot.png',
|
||||
':apple:' : 'apple.png',
|
||||
':green_apple:' : 'green_apple.png',
|
||||
':tangerine:' : 'tangerine.png',
|
||||
':lemon:' : 'lemon.png',
|
||||
':cherries:' : 'cherries.png',
|
||||
':grapes:' : 'grapes.png',
|
||||
':watermelon:' : 'watermelon.png',
|
||||
':strawberry:' : 'strawberry.png',
|
||||
':peach:' : 'peach.png',
|
||||
':melon:' : 'melon.png',
|
||||
':banana:' : 'banana.png',
|
||||
':pear:' : 'pear.png',
|
||||
':pineapple:' : 'pineapple.png',
|
||||
':sweet_potato:' : 'sweet_potato.png',
|
||||
':eggplant:' : 'eggplant.png',
|
||||
':tomato:' : 'tomato.png'}},
|
||||
{'name': '<i class="icon-location"></i>', 'icons' : {':corn:' : 'corn.png',
|
||||
':house:' : 'house.png',
|
||||
':house_with_garden:' : 'house_with_garden.png',
|
||||
':school:' : 'school.png',
|
||||
':office:' : 'office.png',
|
||||
':post_office:' : 'post_office.png',
|
||||
':hospital:' : 'hospital.png',
|
||||
':bank:' : 'bank.png',
|
||||
':convenience_store:' : 'convenience_store.png',
|
||||
':love_hotel:' : 'love_hotel.png',
|
||||
':hotel:' : 'hotel.png',
|
||||
':wedding:' : 'wedding.png',
|
||||
':church:' : 'church.png',
|
||||
':department_store:' : 'department_store.png',
|
||||
':european_post_office:' : 'european_post_office.png',
|
||||
':city_sunrise:' : 'city_sunrise.png',
|
||||
':city_sunset:' : 'city_sunset.png',
|
||||
':japanese_castle:' : 'japanese_castle.png',
|
||||
':european_castle:' : 'european_castle.png',
|
||||
':tent:' : 'tent.png',
|
||||
':factory:' : 'factory.png',
|
||||
':tokyo_tower:' : 'tokyo_tower.png',
|
||||
':japan:' : 'japan.png',
|
||||
':mount_fuji:' : 'mount_fuji.png',
|
||||
':sunrise_over_mountains:' : 'sunrise_over_mountains.png',
|
||||
':sunrise:' : 'sunrise.png',
|
||||
':stars:' : 'stars.png',
|
||||
':statue_of_liberty:' : 'statue_of_liberty.png',
|
||||
':bridge_at_night:' : 'bridge_at_night.png',
|
||||
':carousel_horse:' : 'carousel_horse.png',
|
||||
':rainbow:' : 'rainbow.png',
|
||||
':ferris_wheel:' : 'ferris_wheel.png',
|
||||
':fountain:' : 'fountain.png',
|
||||
':roller_coaster:' : 'roller_coaster.png',
|
||||
':ship:' : 'ship.png',
|
||||
':speedboat:' : 'speedboat.png',
|
||||
':boat:' : 'boat.png',
|
||||
':sailboat:' : 'sailboat.png',
|
||||
':rowboat:' : 'rowboat.png',
|
||||
':anchor:' : 'anchor.png',
|
||||
':rocket:' : 'rocket.png',
|
||||
':airplane:' : 'airplane.png',
|
||||
':helicopter:' : 'helicopter.png',
|
||||
':steam_locomotive:' : 'steam_locomotive.png',
|
||||
':tram:' : 'tram.png',
|
||||
':mountain_railway:' : 'mountain_railway.png',
|
||||
':bike:' : 'bike.png',
|
||||
':aerial_tramway:' : 'aerial_tramway.png',
|
||||
':suspension_railway:' : 'suspension_railway.png',
|
||||
':mountain_cableway:' : 'mountain_cableway.png',
|
||||
':tractor:' : 'tractor.png',
|
||||
':blue_car:' : 'blue_car.png',
|
||||
':oncoming_automobile:' : 'oncoming_automobile.png',
|
||||
':car:' : 'car.png',
|
||||
':red_car:' : 'red_car.png',
|
||||
':taxi:' : 'taxi.png',
|
||||
':oncoming_taxi:' : 'oncoming_taxi.png',
|
||||
':articulated_lorry:' : 'articulated_lorry.png',
|
||||
':bus:' : 'bus.png',
|
||||
':oncoming_bus:' : 'oncoming_bus.png',
|
||||
':rotating_light:' : 'rotating_light.png',
|
||||
':police_car:' : 'police_car.png',
|
||||
':oncoming_police_car:' : 'oncoming_police_car.png',
|
||||
':fire_engine:' : 'fire_engine.png',
|
||||
':ambulance:' : 'ambulance.png',
|
||||
':minibus:' : 'minibus.png',
|
||||
':truck:' : 'truck.png',
|
||||
':train:' : 'train.png',
|
||||
':station:' : 'station.png',
|
||||
':train2:' : 'train2.png',
|
||||
':bullettrain_front:' : 'bullettrain_front.png',
|
||||
':bullettrain_side:' : 'bullettrain_side.png',
|
||||
':light_rail:' : 'light_rail.png',
|
||||
':monorail:' : 'monorail.png',
|
||||
':railway_car:' : 'railway_car.png',
|
||||
':trolleybus:' : 'trolleybus.png',
|
||||
':ticket:' : 'ticket.png',
|
||||
':fuelpump:' : 'fuelpump.png',
|
||||
':vertical_traffic_light:' : 'vertical_traffic_light.png',
|
||||
':traffic_light:' : 'traffic_light.png',
|
||||
':warning:' : 'warning.png',
|
||||
':construction:' : 'construction.png',
|
||||
':beginner:' : 'beginner.png',
|
||||
':atm:' : 'atm.png',
|
||||
':slot_machine:' : 'slot_machine.png',
|
||||
':busstop:' : 'busstop.png',
|
||||
':barber:' : 'barber.png',
|
||||
':hotsprings:' : 'hotsprings.png',
|
||||
':checkered_flag:' : 'checkered_flag.png',
|
||||
':crossed_flags:' : 'crossed_flags.png',
|
||||
':izakaya_lantern:' : 'izakaya_lantern.png',
|
||||
':moyai:' : 'moyai.png',
|
||||
':circus_tent:' : 'circus_tent.png',
|
||||
':performing_arts:' : 'performing_arts.png',
|
||||
':round_pushpin:' : 'round_pushpin.png',
|
||||
':triangular_flag_on_post:' : 'triangular_flag_on_post.png',
|
||||
':jp:' : 'jp.png',
|
||||
':kr:' : 'kr.png',
|
||||
':cn:' : 'cn.png',
|
||||
':us:' : 'us.png',
|
||||
':fr:' : 'fr.png',
|
||||
':es:' : 'es.png',
|
||||
':it:' : 'it.png',
|
||||
':ru:' : 'ru.png',
|
||||
':gb:' : 'gb.png',
|
||||
':uk:' : 'uk.png',
|
||||
':de:' : 'de.png'}},
|
||||
{'name': '<i class="icon-dollar"></i>', 'icons' : {':one:' : 'one.png',
|
||||
':two:' : 'two.png',
|
||||
':three:' : 'three.png',
|
||||
':four:' : 'four.png',
|
||||
':five:' : 'five.png',
|
||||
':six:' : 'six.png',
|
||||
':seven:' : 'seven.png',
|
||||
':eight:' : 'eight.png',
|
||||
':nine:' : 'nine.png',
|
||||
':keycap_ten:' : 'keycap_ten.png',
|
||||
':1234:' : '1234.png',
|
||||
':zero:' : 'zero.png',
|
||||
':hash:' : 'hash.png',
|
||||
':symbols:' : 'symbols.png',
|
||||
':arrow_backward:' : 'arrow_backward.png',
|
||||
':arrow_down:' : 'arrow_down.png',
|
||||
':arrow_forward:' : 'arrow_forward.png',
|
||||
':arrow_left:' : 'arrow_left.png',
|
||||
':capital_abcd:' : 'capital_abcd.png',
|
||||
':abcd:' : 'abcd.png',
|
||||
':abc:' : 'abc.png',
|
||||
':arrow_lower_left:' : 'arrow_lower_left.png',
|
||||
':arrow_lower_right:' : 'arrow_lower_right.png',
|
||||
':arrow_right:' : 'arrow_right.png',
|
||||
':arrow_up:' : 'arrow_up.png',
|
||||
':arrow_upper_left:' : 'arrow_upper_left.png',
|
||||
':arrow_upper_right:' : 'arrow_upper_right.png',
|
||||
':arrow_double_down:' : 'arrow_double_down.png',
|
||||
':arrow_double_up:' : 'arrow_double_up.png',
|
||||
':arrow_down_small:' : 'arrow_down_small.png',
|
||||
':arrow_heading_down:' : 'arrow_heading_down.png',
|
||||
':arrow_heading_up:' : 'arrow_heading_up.png',
|
||||
':leftwards_arrow_with_hook:' : 'leftwards_arrow_with_hook.png',
|
||||
':arrow_right_hook:' : 'arrow_right_hook.png',
|
||||
':left_right_arrow:' : 'left_right_arrow.png',
|
||||
':arrow_up_down:' : 'arrow_up_down.png',
|
||||
':arrow_up_small:' : 'arrow_up_small.png',
|
||||
':arrows_clockwise:' : 'arrows_clockwise.png',
|
||||
':arrows_counterclockwise:' : 'arrows_counterclockwise.png',
|
||||
':rewind:' : 'rewind.png',
|
||||
':fast_forward:' : 'fast_forward.png',
|
||||
':information_source:' : 'information_source.png',
|
||||
':ok:' : 'ok.png',
|
||||
':twisted_rightwards_arrows:' : 'twisted_rightwards_arrows.png',
|
||||
':repeat:' : 'repeat.png',
|
||||
':repeat_one:' : 'repeat_one.png',
|
||||
':new:' : 'new.png',
|
||||
':top:' : 'top.png',
|
||||
':up:' : 'up.png',
|
||||
':cool:' : 'cool.png',
|
||||
':free:' : 'free.png',
|
||||
':ng:' : 'ng.png',
|
||||
':cinema:' : 'cinema.png',
|
||||
':koko:' : 'koko.png',
|
||||
':signal_strength:' : 'signal_strength.png',
|
||||
':u5272:' : 'u5272.png',
|
||||
':u5408:' : 'u5408.png',
|
||||
':u55b6:' : 'u55b6.png',
|
||||
':u6307:' : 'u6307.png',
|
||||
':u6708:' : 'u6708.png',
|
||||
':u6709:' : 'u6709.png',
|
||||
':u6e80:' : 'u6e80.png',
|
||||
':u7121:' : 'u7121.png',
|
||||
':u7533:' : 'u7533.png',
|
||||
':u7a7a:' : 'u7a7a.png',
|
||||
':u7981:' : 'u7981.png',
|
||||
':sa:' : 'sa.png',
|
||||
':restroom:' : 'restroom.png',
|
||||
':mens:' : 'mens.png',
|
||||
':womens:' : 'womens.png',
|
||||
':baby_symbol:' : 'baby_symbol.png',
|
||||
':no_smoking:' : 'no_smoking.png',
|
||||
':parking:' : 'parking.png',
|
||||
':wheelchair:' : 'wheelchair.png',
|
||||
':metro:' : 'metro.png',
|
||||
':baggage_claim:' : 'baggage_claim.png',
|
||||
':accept:' : 'accept.png',
|
||||
':wc:' : 'wc.png',
|
||||
':potable_water:' : 'potable_water.png',
|
||||
':put_litter_in_its_place:' : 'put_litter_in_its_place.png',
|
||||
':secret:' : 'secret.png',
|
||||
':congratulations:' : 'congratulations.png',
|
||||
':m:' : 'm.png',
|
||||
':passport_control:' : 'passport_control.png',
|
||||
':left_luggage:' : 'left_luggage.png',
|
||||
':customs:' : 'customs.png',
|
||||
':ideograph_advantage:' : 'ideograph_advantage.png',
|
||||
':cl:' : 'cl.png',
|
||||
':sos:' : 'sos.png',
|
||||
':id:' : 'id.png',
|
||||
':no_entry_sign:' : 'no_entry_sign.png',
|
||||
':underage:' : 'underage.png',
|
||||
':no_mobile_phones:' : 'no_mobile_phones.png',
|
||||
':do_not_litter:' : 'do_not_litter.png',
|
||||
':non-potable_water:' : 'non-potable_water.png',
|
||||
':no_bicycles:' : 'no_bicycles.png',
|
||||
':no_pedestrians:' : 'no_pedestrians.png',
|
||||
':children_crossing:' : 'children_crossing.png',
|
||||
':no_entry:' : 'no_entry.png',
|
||||
':eight_spoked_asterisk:' : 'eight_spoked_asterisk.png',
|
||||
':eight_pointed_black_star:' : 'eight_pointed_black_star.png',
|
||||
':heart_decoration:' : 'heart_decoration.png',
|
||||
':vs:' : 'vs.png',
|
||||
':vibration_mode:' : 'vibration_mode.png',
|
||||
':mobile_phone_off:' : 'mobile_phone_off.png',
|
||||
':chart:' : 'chart.png',
|
||||
':currency_exchange:' : 'currency_exchange.png',
|
||||
':aries:' : 'aries.png',
|
||||
':taurus:' : 'taurus.png',
|
||||
':gemini:' : 'gemini.png',
|
||||
':cancer:' : 'cancer.png',
|
||||
':leo:' : 'leo.png',
|
||||
':virgo:' : 'virgo.png',
|
||||
':libra:' : 'libra.png',
|
||||
':scorpius:' : 'scorpius.png',
|
||||
':sagittarius:' : 'sagittarius.png',
|
||||
':capricorn:' : 'capricorn.png',
|
||||
':aquarius:' : 'aquarius.png',
|
||||
':pisces:' : 'pisces.png',
|
||||
':ophiuchus:' : 'ophiuchus.png',
|
||||
':six_pointed_star:' : 'six_pointed_star.png',
|
||||
':negative_squared_cross_mark:' : 'negative_squared_cross_mark.png',
|
||||
':a:' : 'a.png',
|
||||
':b:' : 'b.png',
|
||||
':ab:' : 'ab.png',
|
||||
':o2:' : 'o2.png',
|
||||
':diamond_shape_with_a_dot_inside:' : 'diamond_shape_with_a_dot_inside.png',
|
||||
':recycle:' : 'recycle.png',
|
||||
':end:' : 'end.png',
|
||||
':on:' : 'on.png',
|
||||
':soon:' : 'soon.png',
|
||||
':clock1:' : 'clock1.png',
|
||||
':clock130:' : 'clock130.png',
|
||||
':clock10:' : 'clock10.png',
|
||||
':clock1030:' : 'clock1030.png',
|
||||
':clock11:' : 'clock11.png',
|
||||
':clock1130:' : 'clock1130.png',
|
||||
':clock12:' : 'clock12.png',
|
||||
':clock1230:' : 'clock1230.png',
|
||||
':clock2:' : 'clock2.png',
|
||||
':clock230:' : 'clock230.png',
|
||||
':clock3:' : 'clock3.png',
|
||||
':clock330:' : 'clock330.png',
|
||||
':clock4:' : 'clock4.png',
|
||||
':clock430:' : 'clock430.png',
|
||||
':clock5:' : 'clock5.png',
|
||||
':clock530:' : 'clock530.png',
|
||||
':clock6:' : 'clock6.png',
|
||||
':clock630:' : 'clock630.png',
|
||||
':clock7:' : 'clock7.png',
|
||||
':clock730:' : 'clock730.png',
|
||||
':clock8:' : 'clock8.png',
|
||||
':clock830:' : 'clock830.png',
|
||||
':clock9:' : 'clock9.png',
|
||||
':clock930:' : 'clock930.png',
|
||||
':heavy_dollar_sign:' : 'heavy_dollar_sign.png',
|
||||
':copyright:' : 'copyright.png',
|
||||
':registered:' : 'registered.png',
|
||||
':tm:' : 'tm.png',
|
||||
':x:' : 'x.png',
|
||||
':heavy_exclamation_mark:' : 'heavy_exclamation_mark.png',
|
||||
':bangbang:' : 'bangbang.png',
|
||||
':interrobang:' : 'interrobang.png',
|
||||
':o:' : 'o.png',
|
||||
':heavy_multiplication_x:' : 'heavy_multiplication_x.png',
|
||||
':heavy_plus_sign:' : 'heavy_plus_sign.png',
|
||||
':heavy_minus_sign:' : 'heavy_minus_sign.png',
|
||||
':heavy_division_sign:' : 'heavy_division_sign.png',
|
||||
':white_flower:' : 'white_flower.png',
|
||||
':100:' : '100.png',
|
||||
':heavy_check_mark:' : 'heavy_check_mark.png',
|
||||
':ballot_box_with_check:' : 'ballot_box_with_check.png',
|
||||
':radio_button:' : 'radio_button.png',
|
||||
':link:' : 'link.png',
|
||||
':curly_loop:' : 'curly_loop.png',
|
||||
':wavy_dash:' : 'wavy_dash.png',
|
||||
':part_alternation_mark:' : 'part_alternation_mark.png',
|
||||
':trident:' : 'trident.png',
|
||||
':black_square:' : 'black_square.png',
|
||||
':white_check_mark:' : 'white_check_mark.png',
|
||||
':black_square_button:' : 'black_square_button.png',
|
||||
':white_square_button:' : 'white_square_button.png',
|
||||
':black_circle:' : 'black_circle.png',
|
||||
':white_circle:' : 'white_circle.png',
|
||||
':red_circle:' : 'red_circle.png',
|
||||
':large_blue_circle:' : 'large_blue_circle.png',
|
||||
':large_blue_diamond:' : 'large_blue_diamond.png',
|
||||
':large_orange_diamond:' : 'large_orange_diamond.png',
|
||||
':small_blue_diamond:' : 'small_blue_diamond.png',
|
||||
':small_orange_diamond:' : 'small_orange_diamond.png',
|
||||
':small_red_triangle:' : 'small_red_triangle.png',
|
||||
':small_red_triangle_down:' : 'small_red_triangle_down.png',
|
||||
':shipit:' : 'shipit.png',
|
||||
}}, ];
|
|
@ -0,0 +1,97 @@
|
|||
.emoji-wysiwyg-editor {
|
||||
border: 1px solid #d0d0d0;
|
||||
overflow: auto;
|
||||
outline: none;
|
||||
}
|
||||
.emoji-wysiwyg-editor img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: middle;
|
||||
margin: -3px 0 0 0;
|
||||
}
|
||||
.emoji-menu {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
width: 180px;
|
||||
margin-left: -100px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.emoji-menu > div {
|
||||
max-height: 200px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
width: 200px;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow: auto;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
|
||||
-moz-box-shadow: 0 1px 5px rgba(0,0,0,0.3);
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.3);
|
||||
padding-top: 40px;
|
||||
}
|
||||
.emoji-menu img {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
vertical-align: middle;
|
||||
border: 0 none;
|
||||
}
|
||||
.emoji-menu a {
|
||||
margin: -1px 0 0 -1px;
|
||||
border: 1px solid #f2f2f2;
|
||||
padding: 5px;
|
||||
display: block;
|
||||
float: left;
|
||||
}
|
||||
.emoji-menu a:hover {
|
||||
background-color: #fffae7;
|
||||
}
|
||||
.emoji-menu:after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
clear: left;
|
||||
}
|
||||
.emoji-menu a .label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.emoji-menu div {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.emoji-menu .group-selector {
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
height: 40px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: rgb(255,255,255);
|
||||
background-color: rgba(255,255,255, .9);
|
||||
}
|
||||
.emoji-menu .group-selector li {
|
||||
height: 15px;
|
||||
width: 17px;
|
||||
padding: 5px;
|
||||
}
|
||||
.emoji-menu .group-selector a:last-child li {
|
||||
width: 15px;
|
||||
}
|
||||
.emoji-menu .group-selector a {
|
||||
color: #EB7878;
|
||||
text-decoration: none;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
.emoji-menu .group-selector a:hover, .emoji-menu .group-selector a.active {
|
||||
color:#000000;
|
||||
}
|
|
@ -0,0 +1,485 @@
|
|||
/**
|
||||
* emojiarea - A rich textarea control that supports emojis, WYSIWYG-style.
|
||||
* Copyright (c) 2012 DIY Co
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under
|
||||
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
||||
* ANY KIND, either express or implied. See the License for the specific language
|
||||
* governing permissions and limitations under the License.
|
||||
*
|
||||
* @author Brian Reavis <brian@diy.org>
|
||||
*/
|
||||
|
||||
(function($, window, document) {
|
||||
|
||||
var ELEMENT_NODE = 1;
|
||||
var TEXT_NODE = 3;
|
||||
var TAGS_BLOCK = ['p', 'div', 'pre', 'form'];
|
||||
var KEY_ESC = 27;
|
||||
var KEY_TAB = 9;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
$.emojiarea = {
|
||||
path: '',
|
||||
icons: {},
|
||||
defaults: {
|
||||
button: null,
|
||||
buttonLabel: 'Emojis',
|
||||
buttonPosition: 'after'
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.emojiarea = function(options) {
|
||||
options = $.extend({}, $.emojiarea.defaults, options);
|
||||
return this.each(function() {
|
||||
var $textarea = $(this);
|
||||
if ('contentEditable' in document.body && options.wysiwyg !== false) {
|
||||
new EmojiArea_WYSIWYG($textarea, options);
|
||||
} else {
|
||||
new EmojiArea_Plain($textarea, options);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
var util = {};
|
||||
|
||||
util.restoreSelection = (function() {
|
||||
if (window.getSelection) {
|
||||
return function(savedSelection) {
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
for (var i = 0, len = savedSelection.length; i < len; ++i) {
|
||||
sel.addRange(savedSelection[i]);
|
||||
}
|
||||
};
|
||||
} else if (document.selection && document.selection.createRange) {
|
||||
return function(savedSelection) {
|
||||
if (savedSelection) {
|
||||
savedSelection.select();
|
||||
}
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
util.saveSelection = (function() {
|
||||
if (window.getSelection) {
|
||||
return function() {
|
||||
var sel = window.getSelection(), ranges = [];
|
||||
if (sel.rangeCount) {
|
||||
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
|
||||
ranges.push(sel.getRangeAt(i));
|
||||
}
|
||||
}
|
||||
return ranges;
|
||||
};
|
||||
} else if (document.selection && document.selection.createRange) {
|
||||
return function() {
|
||||
var sel = document.selection;
|
||||
return (sel.type.toLowerCase() !== 'none') ? sel.createRange() : null;
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
util.replaceSelection = (function() {
|
||||
if (window.getSelection) {
|
||||
return function(content) {
|
||||
var range, sel = window.getSelection();
|
||||
var node = typeof content === 'string' ? document.createTextNode(content) : content;
|
||||
if (sel.getRangeAt && sel.rangeCount) {
|
||||
range = sel.getRangeAt(0);
|
||||
range.deleteContents();
|
||||
range.insertNode(document.createTextNode(' '));
|
||||
range.insertNode(node);
|
||||
range.setStart(node, 0);
|
||||
|
||||
window.setTimeout(function() {
|
||||
range = document.createRange();
|
||||
range.setStartAfter(node);
|
||||
range.collapse(true);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
} else if (document.selection && document.selection.createRange) {
|
||||
return function(content) {
|
||||
var range = document.selection.createRange();
|
||||
if (typeof content === 'string') {
|
||||
range.text = content;
|
||||
} else {
|
||||
range.pasteHTML(content.outerHTML);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
util.insertAtCursor = function(text, el) {
|
||||
text = ' ' + text;
|
||||
var val = el.value, endIndex, startIndex, range;
|
||||
if (typeof el.selectionStart != 'undefined' && typeof el.selectionEnd != 'undefined') {
|
||||
startIndex = el.selectionStart;
|
||||
endIndex = el.selectionEnd;
|
||||
el.value = val.substring(0, startIndex) + text + val.substring(el.selectionEnd);
|
||||
el.selectionStart = el.selectionEnd = startIndex + text.length;
|
||||
} else if (typeof document.selection != 'undefined' && typeof document.selection.createRange != 'undefined') {
|
||||
el.focus();
|
||||
range = document.selection.createRange();
|
||||
range.text = text;
|
||||
range.select();
|
||||
}
|
||||
};
|
||||
|
||||
util.extend = function(a, b) {
|
||||
if (typeof a === 'undefined' || !a) { a = {}; }
|
||||
if (typeof b === 'object') {
|
||||
for (var key in b) {
|
||||
if (b.hasOwnProperty(key)) {
|
||||
a[key] = b[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return a;
|
||||
};
|
||||
|
||||
util.escapeRegex = function(str) {
|
||||
return (str + '').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
|
||||
};
|
||||
|
||||
util.htmlEntities = function(str) {
|
||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
var EmojiArea = function() {};
|
||||
|
||||
EmojiArea.prototype.setup = function() {
|
||||
var self = this;
|
||||
|
||||
this.$editor.on('focus', function() { self.hasFocus = true; });
|
||||
this.$editor.on('blur', function() { self.hasFocus = false; });
|
||||
|
||||
this.setupButton();
|
||||
};
|
||||
|
||||
EmojiArea.prototype.setupButton = function() {
|
||||
var self = this;
|
||||
var $button;
|
||||
|
||||
if (this.options.button) {
|
||||
$button = $(this.options.button);
|
||||
} else if (this.options.button !== false) {
|
||||
$button = $('<a href="javascript:void(0)">');
|
||||
$button.html(this.options.buttonLabel);
|
||||
$button.addClass('emoji-button');
|
||||
$button.attr({title: this.options.buttonLabel});
|
||||
this.$editor[this.options.buttonPosition]($button);
|
||||
} else {
|
||||
$button = $('');
|
||||
}
|
||||
|
||||
$button.on('click', function(e) {
|
||||
EmojiMenu.show(self);
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
this.$button = $button;
|
||||
};
|
||||
|
||||
EmojiArea.createIcon = function(group, emoji) {
|
||||
var filename = $.emojiarea.icons[group]['icons'][emoji];
|
||||
var path = $.emojiarea.path || '';
|
||||
if (path.length && path.charAt(path.length - 1) !== '/') {
|
||||
path += '/';
|
||||
}
|
||||
return '<img src="' + path + filename + '" alt="' + util.htmlEntities(emoji) + '">';
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Editor (plain-text)
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} $textarea
|
||||
* @param {object} options
|
||||
*/
|
||||
|
||||
var EmojiArea_Plain = function($textarea, options) {
|
||||
this.options = options;
|
||||
this.$textarea = $textarea;
|
||||
this.$editor = $textarea;
|
||||
this.setup();
|
||||
};
|
||||
|
||||
EmojiArea_Plain.prototype.insert = function(group, emoji) {
|
||||
if (!$.emojiarea.icons[group]['icons'].hasOwnProperty(emoji)) return;
|
||||
util.insertAtCursor(emoji, this.$textarea[0]);
|
||||
this.$textarea.trigger('change');
|
||||
};
|
||||
|
||||
EmojiArea_Plain.prototype.val = function() {
|
||||
return this.$textarea.val();
|
||||
};
|
||||
|
||||
util.extend(EmojiArea_Plain.prototype, EmojiArea.prototype);
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Editor (rich)
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} $textarea
|
||||
* @param {object} options
|
||||
*/
|
||||
|
||||
var EmojiArea_WYSIWYG = function($textarea, options) {
|
||||
var self = this;
|
||||
|
||||
this.options = options;
|
||||
this.$textarea = $textarea;
|
||||
this.$editor = $('<div>').addClass('emoji-wysiwyg-editor');
|
||||
this.$editor.text($textarea.val());
|
||||
this.$editor.attr({contenteditable: 'true'});
|
||||
this.$editor.on('blur keyup paste', function() { return self.onChange.apply(self, arguments); });
|
||||
this.$editor.on('mousedown focus', function() { document.execCommand('enableObjectResizing', false, false); });
|
||||
this.$editor.on('blur', function() { document.execCommand('enableObjectResizing', true, true); });
|
||||
|
||||
var html = this.$editor.text();
|
||||
var emojis = $.emojiarea.icons;
|
||||
for (var group in emojis) {
|
||||
for (var key in emojis[group]['icons']) {
|
||||
if (emojis[group]['icons'].hasOwnProperty(key)) {
|
||||
html = html.replace(new RegExp(util.escapeRegex(key), 'g'), EmojiArea.createIcon(group, key));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$editor.html(html);
|
||||
|
||||
$textarea.hide().after(this.$editor);
|
||||
|
||||
this.setup();
|
||||
|
||||
this.$button.on('mousedown', function() {
|
||||
if (self.hasFocus) {
|
||||
self.selection = util.saveSelection();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
EmojiArea_WYSIWYG.prototype.onChange = function() {
|
||||
this.$textarea.val(this.val()).trigger('change');
|
||||
};
|
||||
|
||||
EmojiArea_WYSIWYG.prototype.insert = function(group, emoji) {
|
||||
var content;
|
||||
var $img = $(EmojiArea.createIcon(group, emoji));
|
||||
if ($img[0].attachEvent) {
|
||||
$img[0].attachEvent('onresizestart', function(e) { e.returnValue = false; }, false);
|
||||
}
|
||||
|
||||
this.$editor.trigger('focus');
|
||||
if (this.selection) {
|
||||
util.restoreSelection(this.selection);
|
||||
}
|
||||
try { util.replaceSelection($img[0]); } catch (e) {}
|
||||
this.onChange();
|
||||
};
|
||||
|
||||
EmojiArea_WYSIWYG.prototype.val = function() {
|
||||
var lines = [];
|
||||
var line = [];
|
||||
|
||||
var flush = function() {
|
||||
lines.push(line.join(''));
|
||||
line = [];
|
||||
};
|
||||
|
||||
var sanitizeNode = function(node) {
|
||||
if (node.nodeType === TEXT_NODE) {
|
||||
line.push(node.nodeValue);
|
||||
} else if (node.nodeType === ELEMENT_NODE) {
|
||||
var tagName = node.tagName.toLowerCase();
|
||||
var isBlock = TAGS_BLOCK.indexOf(tagName) !== -1;
|
||||
|
||||
if (isBlock && line.length) flush();
|
||||
|
||||
if (tagName === 'img') {
|
||||
var alt = node.getAttribute('alt') || '';
|
||||
if (alt) line.push(alt);
|
||||
return;
|
||||
} else if (tagName === 'br') {
|
||||
flush();
|
||||
}
|
||||
|
||||
var children = node.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
sanitizeNode(children[i]);
|
||||
}
|
||||
|
||||
if (isBlock && line.length) flush();
|
||||
}
|
||||
};
|
||||
|
||||
var children = this.$editor[0].childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
sanitizeNode(children[i]);
|
||||
}
|
||||
|
||||
if (line.length) flush();
|
||||
|
||||
return lines.join('\n');
|
||||
};
|
||||
|
||||
util.extend(EmojiArea_WYSIWYG.prototype, EmojiArea.prototype);
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
/**
|
||||
* Emoji Dropdown Menu
|
||||
*
|
||||
* @constructor
|
||||
* @param {object} emojiarea
|
||||
*/
|
||||
var EmojiMenu = function() {
|
||||
var self = this;
|
||||
var $body = $(document.body);
|
||||
var $window = $(window);
|
||||
|
||||
this.visible = false;
|
||||
this.emojiarea = null;
|
||||
this.$menu = $('<div>');
|
||||
this.$menu.addClass('emoji-menu');
|
||||
this.$menu.hide();
|
||||
this.$items = $('<div>').appendTo(this.$menu);
|
||||
|
||||
$body.append(this.$menu);
|
||||
|
||||
$body.on('keydown', function(e) {
|
||||
if (e.keyCode === KEY_ESC || e.keyCode === KEY_TAB) {
|
||||
self.hide();
|
||||
}
|
||||
});
|
||||
|
||||
$body.on('mouseup', function() {
|
||||
self.hide();
|
||||
});
|
||||
|
||||
$window.on('resize', function() {
|
||||
if (self.visible) self.reposition();
|
||||
});
|
||||
|
||||
this.$menu.on('mouseup', 'a', function(e) {
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
|
||||
this.$menu.on('click', 'a', function(e) {
|
||||
var emoji = $('.label', $(this)).text();
|
||||
var group = $('.label', $(this)).parent().parent().attr('group');
|
||||
if(group && emoji !== ''){
|
||||
window.setTimeout(function() {
|
||||
self.onItemSelected.apply(self, [group, emoji]);
|
||||
}, 0);
|
||||
e.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
this.load();
|
||||
};
|
||||
|
||||
EmojiMenu.prototype.onItemSelected = function(group, emoji) {
|
||||
this.emojiarea.insert(group, emoji);
|
||||
this.hide();
|
||||
};
|
||||
|
||||
EmojiMenu.prototype.load = function() {
|
||||
var html = [];
|
||||
var groups = [];
|
||||
var options = $.emojiarea.icons;
|
||||
var path = $.emojiarea.path;
|
||||
if (path.length && path.charAt(path.length - 1) !== '/') {
|
||||
path += '/';
|
||||
}
|
||||
groups.push('<ul class="group-selector">');
|
||||
for (var group in options) {
|
||||
groups.push('<a href="#group_' + group + '" class="tab_switch"><li>' + options[group]['name'] + '</li></a>');
|
||||
html.push('<div class="select_group" group="' + group + '" id="group_' + group + '">');
|
||||
for (var key in options[group]['icons']) {
|
||||
if (options[group]['icons'].hasOwnProperty(key)) {
|
||||
var filename = options[key];
|
||||
html.push('<a href="javascript:void(0)" title="' + util.htmlEntities(key) + '">' + EmojiArea.createIcon(group, key) + '<span class="label">' + util.htmlEntities(key) + '</span></a>');
|
||||
}
|
||||
}
|
||||
html.push('</div>');
|
||||
}
|
||||
groups.push('</ul>');
|
||||
this.$items.html(html.join(''));
|
||||
this.$menu.prepend(groups.join(''));
|
||||
this.$menu.find('.tab_switch').each(function(i) {
|
||||
if (i != 0) {
|
||||
var select = $(this).attr('href');
|
||||
$(select).hide();
|
||||
} else {
|
||||
$(this).addClass('active');
|
||||
}
|
||||
$(this).click(function() {
|
||||
$(this).addClass('active');
|
||||
$(this).siblings().removeClass('active');
|
||||
$('.select_group').hide();
|
||||
var select = $(this).attr('href');
|
||||
$(select).show();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
EmojiMenu.prototype.reposition = function() {
|
||||
var $button = this.emojiarea.$button;
|
||||
var offset = $button.offset();
|
||||
offset.top += $button.outerHeight();
|
||||
offset.left += Math.round($button.outerWidth() / 2);
|
||||
|
||||
this.$menu.css({
|
||||
top: offset.top,
|
||||
left: offset.left
|
||||
});
|
||||
};
|
||||
|
||||
EmojiMenu.prototype.hide = function(callback) {
|
||||
if (this.emojiarea) {
|
||||
this.emojiarea.menu = null;
|
||||
this.emojiarea.$button.removeClass('on');
|
||||
this.emojiarea = null;
|
||||
}
|
||||
this.visible = false;
|
||||
this.$menu.hide();
|
||||
};
|
||||
|
||||
EmojiMenu.prototype.show = function(emojiarea) {
|
||||
if (this.emojiarea && this.emojiarea === emojiarea) return;
|
||||
this.emojiarea = emojiarea;
|
||||
this.emojiarea.menu = this;
|
||||
|
||||
this.reposition();
|
||||
this.$menu.show();
|
||||
this.visible = true;
|
||||
};
|
||||
|
||||
EmojiMenu.show = (function() {
|
||||
var menu = null;
|
||||
return function(emojiarea) {
|
||||
menu = menu || new EmojiMenu();
|
||||
menu.show(emojiarea);
|
||||
};
|
||||
})();
|
||||
|
||||
})(jQuery, window, document);
|
File diff suppressed because one or more lines are too long
|
@ -9,6 +9,25 @@ body
|
|||
font-family: arial;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'EmojiFont';
|
||||
src: url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff2') format('woff2'),
|
||||
url('https://github.com/Ranks/emojione/raw/master/assets/fonts/emojione-svg.woff') format('woff'), local("arial");
|
||||
}
|
||||
|
||||
@supports (-ms-ime-align:auto) {
|
||||
.user_content
|
||||
{
|
||||
font-family: EmojiFont, arial;
|
||||
}
|
||||
}
|
||||
@-moz-document url-prefix() {
|
||||
.user_content
|
||||
{
|
||||
font-family: EmojiFont, arial;
|
||||
}
|
||||
}
|
||||
|
||||
ul
|
||||
{
|
||||
border: 1px solid #ccc;
|
||||
|
|
20
routes.go
20
routes.go
|
@ -54,11 +54,9 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){
|
|||
user := SessionCheck(w,r)
|
||||
name := r.URL.Path[len("/pages/"):]
|
||||
|
||||
val, ok := custom_pages[name];
|
||||
if ok {
|
||||
pi := Page{"Page","page",user,tList,val}
|
||||
templates.ExecuteTemplate(w,"custom_page.html", pi)
|
||||
} else {
|
||||
pi := Page{"Page","page",user,tList,0}
|
||||
err := custom_pages.ExecuteTemplate(w,name, pi)
|
||||
if err != nil {
|
||||
NotFound(w,r,user)
|
||||
}
|
||||
}
|
||||
|
@ -407,6 +405,10 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
|||
puser.Is_Admin = puser.Is_Super_Admin || groups[puser.Group].Is_Admin
|
||||
puser.Is_Super_Mod = puser.Is_Admin || groups[puser.Group].Is_Mod
|
||||
puser.Is_Mod = puser.Is_Super_Mod
|
||||
puser.Is_Banned = groups[puser.Group].Is_Banned
|
||||
if puser.Is_Banned && puser.Is_Super_Mod {
|
||||
puser.Is_Banned = false
|
||||
}
|
||||
}
|
||||
|
||||
if puser.Avatar != "" {
|
||||
|
@ -500,7 +502,7 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
|
|||
success := 1
|
||||
topic_name := html.EscapeString(r.PostFormValue("topic-name"))
|
||||
|
||||
res, err := create_topic_stmt.Exec(topic_name,html.EscapeString(r.PostFormValue("topic-content")),parse_message(html.EscapeString(r.PostFormValue("topic-content"))),user.ID)
|
||||
res, err := create_topic_stmt.Exec(topic_name,html.EscapeString(preparse_message(r.PostFormValue("topic-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("topic-content")))),user.ID)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
|
@ -566,7 +568,9 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
_, err = create_reply_stmt.Exec(tid,html.EscapeString(r.PostFormValue("reply-content")),parse_message(html.EscapeString(r.PostFormValue("reply-content"))),user.ID)
|
||||
content := preparse_message(html.EscapeString(r.PostFormValue("reply-content")))
|
||||
log.Print(content)
|
||||
_, err = create_reply_stmt.Exec(tid,content,parse_message(content),user.ID)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
|
@ -636,7 +640,7 @@ func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
_, err = create_profile_reply_stmt.Exec(uid,html.EscapeString(r.PostFormValue("reply-content")),parse_message(html.EscapeString(r.PostFormValue("reply-content"))),user.ID)
|
||||
_, err = create_profile_reply_stmt.Exec(uid,html.EscapeString(preparse_message(r.PostFormValue("reply-content"))),parse_message(html.EscapeString(preparse_message(r.PostFormValue("reply-content")))),user.ID)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
success = 0
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
<div class="rowitem">{{.Something.Name}}</div>
|
||||
<div class="rowitem passive">
|
||||
<a class="username">Add Friend</a>
|
||||
{{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}<a class="username">Ban</a>{{end}}
|
||||
{{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}
|
||||
{{if .Something.Is_Banned }}<a href="/users/unban/{{.Something.ID}}" class="username">Unban</a>{{else}}<a href="/users/ban/{{.Something.ID}}" class="username">Ban</a>{{end}}
|
||||
{{end}}
|
||||
<a class="username">Report</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,7 +16,7 @@
|
|||
<div class="colblock_right" style="overflow: hidden;">
|
||||
{{range $index, $element := .ItemList}}
|
||||
<div class="rowitem passive deletable_block editable_parent" style="{{ if $element.Avatar }}background-image: url({{$element.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le $element.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{$element.Css}}{{end}}">
|
||||
<span class="editable_block">{{$element.ContentHtml}}</span>
|
||||
<span class="editable_block user_content">{{$element.ContentHtml}}</span>
|
||||
<br /><br />
|
||||
<a href="/user/{{$element.CreatedBy}}" class="username">{{$element.CreatedByName}}</a>
|
||||
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{$element.ID}}"><button class="username edit_item">Edit</button></a>
|
||||
|
@ -31,7 +33,7 @@
|
|||
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</div></div>
|
||||
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</div>
|
||||
<div class="rowblock">
|
||||
<div class="rowitem passive editable_parent" style="border-bottom: none;{{ if .Something.Avatar }}background-image: url({{ .Something.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Something.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Something.Css}}{{end}}">
|
||||
<span class="hide_on_edit topic_content">{{.Something.Content}}</span>
|
||||
<span class="hide_on_edit topic_content user_content">{{.Something.Content}}</span>
|
||||
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Something.Content}}</textarea>
|
||||
<br /><br />
|
||||
<a href="/user/{{.Something.CreatedBy}}" class="username">{{.Something.CreatedByName}}</a>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<div class="rowblock" style="overflow: hidden;">
|
||||
{{range $index, $element := .ItemList}}
|
||||
<div class="rowitem passive deletable_block editable_parent" style="{{ if $element.Avatar }}background-image: url({{$element.Avatar}}), url(/static/white-dot.jpg);background-position: 0px {{if le $element.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{$element.Css}}{{end}}">
|
||||
<span class="editable_block">{{$element.ContentHtml}}</span>
|
||||
<span class="editable_block user_content">{{$element.ContentHtml}}</span>
|
||||
<br /><br />
|
||||
<a href="/user/{{$element.CreatedBy}}" class="username">{{$element.CreatedByName}}</a>
|
||||
{{if $.CurrentUser.Is_Mod}}<a href="/reply/edit/submit/{{$element.ID}}"><button class="username edit_item">Edit</button></a>
|
||||
|
@ -49,7 +49,7 @@
|
|||
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
|
||||
</div>
|
||||
<div class="formrow">
|
||||
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</div></div>
|
||||
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
5
user.go
5
user.go
|
@ -71,10 +71,15 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (User) {
|
|||
log.Print(err)
|
||||
return user
|
||||
}
|
||||
|
||||
user.Is_Admin = user.Is_Super_Admin || groups[user.Group].Is_Admin
|
||||
user.Is_Super_Mod = groups[user.Group].Is_Mod || user.Is_Admin
|
||||
user.Is_Mod = user.Is_Super_Mod
|
||||
user.Is_Banned = groups[user.Group].Is_Banned
|
||||
if user.Is_Banned && user.Is_Super_Mod {
|
||||
user.Is_Banned = false
|
||||
}
|
||||
|
||||
if user.Avatar != "" {
|
||||
if user.Avatar[0] == '.' {
|
||||
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar
|
||||
|
|
Loading…
Reference in New Issue