Browse Source

Merge pull request #174 from digital-dreamer/improved-unicode-conversion

Improved unicode conversion
master
miguelfreitas 10 years ago
parent
commit
a96bcbdbf9
  1. 4
      css/style.css
  2. 301
      js/interface_common.js
  3. 18
      theme_calm/css/style.css

4
css/style.css

@ -631,6 +631,10 @@ textarea.splited-post {
display: inline-block; display: inline-block;
margin-top: 4px; margin-top: 4px;
} }
.undo-unicode
{
font-family: sans-serif, Symbola;
}
.post-area-new.open > .post-area-extras .post-area-new.open > .post-area-extras
{ {
height: 35px; height: 35px;

301
js/interface_common.js

@ -697,7 +697,7 @@ function replyTextKeypress(e) {
* n: index of char to be stored and appended to result * n: index of char to be stored and appended to result
*/ */
var unicodeConversionList = { var unicodeConversionList = {
"ponctuations": [ "punctuation": [
{ {
"k": /\.\.\./, "k": /\.\.\./,
"u": "\u2026", "u": "\u2026",
@ -953,202 +953,161 @@ var unicodeConversionList = {
] ]
}; };
/* // Marks ranges in a message where unicode replacements will be ignored (inside URLs).
* a stack for undo... function getRangesForUnicodeConversion(msg)
* element for the unicodeConversionStack {
* { if(!msg) return;
k: original string that's replaced
u: unicode var tempMsg = msg;
p: position in string var results = [];
l: length of k var regexHttpStart = /http[s]?:\/\//;
m: new string length after convertion var regexHttpEnd = /[ \n\t]/;
* } var start=0, end, position, rep = true;
*/
var unicodeConversionStack = []; position = tempMsg.search(regexHttpStart);
//we want to handle new typed text after the last conversion.
var lastConvertedIndex = -1; while(position!=-1)
{
function convert2Unicodes(s, ta) { end = start + position;
if(end > start)
var tmp = s; {
results.push({start: start, end: end, replace: rep});
//check if there is a deletion...
//NOTE: BUGGY... can't handle everytime...
if (unicodeConversionStack.length>0 && s.length < unicodeConversionStack[0].m){
//check if a replaced unicode was deleted...
for (var i=unicodeConversionStack.length-1; i>=0; i--){
//get position and check the positions are same...
var ni = s.indexOf(unicodeConversionStack[i].u);
if (ni > -1 && s[ni] !== unicodeConversionStack[i].p){
var op = -1;
for (var j=i-1; j>=0; j--){
if (unicodeConversionStack[j].u === unicodeConversionStack[i].u){
if (unicodeConversionStack[j].p === ni){
op = -1;
break;
}
op = unicodeConversionStack[j].p;
}
}
if (op === -1) {
//remove deleted unicode...
unicodeConversionStack.splice(i, 1);
} else {
//update the position of the unicode!
unicodeConversionStack[i].p = ni;
}
}
} }
unicodeConversionStack[0].m = s.length; rep = !rep;
start = end;
tempMsg = tempMsg.substring(position, tempMsg.length);
if(rep == true)
position = tempMsg.search(regexHttpStart);
else
position = tempMsg.search(regexHttpEnd);
} }
end = msg.length;
if(end > start)
results.push({start: start, end: end, replace: rep});
return results;
}
if (s.length < lastConvertedIndex) function getUnicodeReplacement(msg, list, ranges, ta)
lastConvertedIndex = s.length; {
if(!msg || !list || !ranges) return;
if ($.Options.getUnicodeConversionOpt() === "enable" || $.Options.getConvertPunctuationsOpt()){ if(ranges.length===0) return "";
var position, substrings = [];
for (var j=0; j<ranges.length; j++)
{
substrings[j] = msg.substring(ranges[j].start, ranges[j].end);
if(ranges[j].replace==true)
{
for (var i=0; i<list.length; i++)
{
position = substrings[j].search(list[i].k);
if(position!=-1 && ta.data("disabledUnicodeRules").indexOf(list[i].u)==-1)
{
var oldSubstring = substrings[j];
substrings[j] = substrings[j].replace(list[i].k, list[i].u);
var len = oldSubstring.length - substrings[j].length + list[i].u.length;
ta.data("unicodeConversionStack").unshift({
"k": oldSubstring.substr(position, len),
"u": list[i].u,
"p": ranges[j].start + position
});
}
}
}
}
var returnString = substrings[0];
for (var j=1; j<ranges.length; j++)
{
returnString += substrings[j];
}
return returnString;
}
var list = unicodeConversionList.ponctuations; function convert2Unicodes(s, ta)
for (var i=0; i<list.length; i++){ {
var kl = list[i].k.exec(tmp); if(!ta.data("unicodeConversionStack")) // A stack of undo steps
if (kl && kl.length > 0 && kl.index >= lastConvertedIndex) { ta.data("unicodeConversionStack", []);
var nc = ""; if(!ta.data("disabledUnicodeRules")) // A list of conversion rules that are temporarily disabled
if (list[i].n > -1){ ta.data("disabledUnicodeRules", []);
//if it's necessary, get any next char to prevent from any data loss var ranges = getRangesForUnicodeConversion(s);
nc = tmp[kl.index + list[i].n]; var list;
} if ($.Options.getUnicodeConversionOpt() === "enable" || $.Options.getConvertPunctuationsOpt())
tmp = tmp.replace(list[i].k, list[i].u + nc); {
var len = s.length - tmp.length + list[i].u.length; list = unicodeConversionList.punctuation;
unicodeConversionStack.unshift({ s = getUnicodeReplacement(s, list, ranges, ta);
"k": s.substr(kl.index, len),
"u": list[i].u,
"p": kl.index,
"l": len,
"m": tmp.length
});
s = tmp;
lastConvertedIndex = tmp.length;
}
}
} }
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertEmotionsOpt())
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertEmotionsOpt()){ {
list = unicodeConversionList.emotions;
var list = unicodeConversionList.emotions; s = getUnicodeReplacement(s, list, ranges, ta);
for (var i=0; i<list.length; i++){
var kl = list[i].k.exec(tmp);
if (kl && kl.length > 0 && kl.index >= lastConvertedIndex) {
var nc = "";
if (list[i].n > -1){
//if it's necessary, get any next char to prevent from any data loss
nc = tmp[kl.index + list[i].n];
}
tmp = tmp.replace(list[i].k, list[i].u + nc);
var len = s.length - tmp.length + list[i].u.length;
unicodeConversionStack.unshift({
"k": s.substr(kl.index, len),
"u": list[i].u,
"p": kl.index,
"l": len,
"m": tmp.length
});
s = tmp;
lastConvertedIndex = tmp.length;
}
}
} }
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertSignsOpt())
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertSignsOpt()){ {
list = unicodeConversionList.signs;
var list = unicodeConversionList.signs; s = getUnicodeReplacement(s, list, ranges, ta);
for (var i=0; i<list.length; i++){
var kl = list[i].k.exec(tmp);
if (kl && kl.length > 0 && kl.index >= lastConvertedIndex) {
var nc = "";
if (list[i].n > -1){
//if it's necessary, get any next char to prevent from any data loss
nc = tmp[kl.index + list[i].n];
}
tmp = tmp.replace(list[i].k, list[i].u + nc);
var len = s.length - tmp.length + list[i].u.length;
unicodeConversionStack.unshift({
"k": s.substr(kl.index, len),
"u": list[i].u,
"p": kl.index,
"l": len,
"m": tmp.length
});
s = tmp;
lastConvertedIndex = tmp.length;
}
}
} }
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertFractionsOpt())
if ($.Options.getUnicodeConversionOpt() === "enable"|| $.Options.getConvertFractionsOpt()){ {
list = unicodeConversionList.fractions;
var list = unicodeConversionList.fractions; s = getUnicodeReplacement(s, list, ranges, ta);
for (var i=0; i<list.length; i++){
var kl = list[i].k.exec(tmp);
if (kl && kl.length > 0 && kl.index >= lastConvertedIndex) {
var nc = "";
if (list[i].n > -1){
//if it's necessary, get any next char to prevent from any data loss
nc = tmp[kl.index + list[i].n];
}
tmp = tmp.replace(list[i].k, list[i].u + nc);
var len = s.length - tmp.length + list[i].u.length;
unicodeConversionStack.unshift({
"k": s.substr(kl.index, len),
"u": list[i].u,
"p": kl.index,
"l": len,
"m": tmp.length
});
s = tmp;
lastConvertedIndex = tmp.length;
}
}
} }
if (unicodeConversionStack.length > 0){ if (ta.data("unicodeConversionStack").length > 0)
{
var ub = ta.closest(".post-area-new").find(".undo-unicode"); var ub = ta.closest(".post-area-new").find(".undo-unicode");
ub.text("undo: " + unicodeConversionStack[0].u); ub.text("undo: " + ta.data("unicodeConversionStack")[0].u);
$.MAL.enableButton(ub); $.MAL.enableButton(ub);
} else { }
else
{
$.MAL.disableButton(ta.closest(".post-area-new").find(".undo-unicode")); $.MAL.disableButton(ta.closest(".post-area-new").find(".undo-unicode"));
} }
return tmp; return s;
} }
//BUGGY... if user deletes something in the middle, stack could be deformed...
function undoLastUnicode(e) { function undoLastUnicode(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
if (unicodeConversionStack.length === 0) var $ta = $(this).closest(".post-area-new").find("textarea");
if ($ta.data("unicodeConversionStack").length === 0)
return; return;
var uc = unicodeConversionStack.shift(); var uc = $ta.data("unicodeConversionStack").shift();
$ta = $(this).closest(".post-area-new").find("textarea");
var pt = $ta.val(); var pt = $ta.val();
if (pt.substr(uc.p, uc.u.length) === uc.u) // If the text was shifted, and character is no longer at the saved position, this function
$ta.val(pt.substr(0,uc.p) + uc.k + pt.substr(uc.p + uc.u.length)); // searches for it to the right. If it is not there, it searches in the oposite direction.
else { // if it's not there either, it means it was deleted, so it is skipped.
//if it can't be found at its index, last unicode will be removed var substrLeft = pt.substring(0, uc.p);
var i = pt.lastIndexOf(uc.u); var substrRight = pt.substring(uc.p, pt.length);
if (i>-1) { if(substrRight.search(uc.u)!=-1)
$ta.val(pt.substr(0,i) + uc.k + pt.substr(i + uc.u.length)); {
} substrRight = substrRight.replace(uc.u, uc.k);
$ta.val(substrLeft + substrRight);
$ta.data("disabledUnicodeRules").push(uc.u);
}
else if(substrLeft.search(uc.u)!=-1)
{
var closestToTheLeft = substrLeft.lastIndexOf(uc.u);
var substrCenter = substrLeft.substring(closestToTheLeft, substrLeft.length).replace(uc.u, uc.k);
substrLeft = substrLeft.substring(0, closestToTheLeft);
$ta.val(substrLeft + substrCenter + substrRight);
$ta.data("disabledUnicodeRules").push(uc.u);
} }
if (unicodeConversionStack.length > 0) if ($ta.data("unicodeConversionStack").length > 0)
$(this).text("undo: " + unicodeConversionStack[0].u); $(this).text("undo: " + $ta.data("unicodeConversionStack")[0].u);
else else
{
$(this).text("undo");
$.MAL.disableButton($(this)); $.MAL.disableButton($(this));
}
lastConvertedIndex = $ta.val().length;
} }
var postSubmit = function(e, oldLastPostId) var postSubmit = function(e, oldLastPostId)
@ -1227,6 +1186,8 @@ var postSubmit = function(e, oldLastPostId)
$('.post-area-new').removeClass('open').find('textarea').blur(); $('.post-area-new').removeClass('open').find('textarea').blur();
}; };
setTimeout('requestTimelineUpdate("latest",postsPerRefresh,followingUsers,promotedPostsOnly)', 1000); setTimeout('requestTimelineUpdate("latest",postsPerRefresh,followingUsers,promotedPostsOnly)', 1000);
$replyText.data("unicodeConversionStack", []);
$replyText.data("disabledUnicodeRules", []);
} }

18
theme_calm/css/style.css

@ -759,7 +759,23 @@ textarea.splited-post {
transition: all 200ms; transition: all 200ms;
} }
.post-submit:hover, .dm-submit:hover { .undo-unicode {
display: inline-block;
height: 34px;
padding: 0 10px 0 10px;
color: #f1f1f1;
font: 17px/34px "Open Sans Condensed", Symbola;
border-radius: 2px;
opacity: 1;
-webkit-transition: all 200ms;
-moz-transition: all 200ms;
-ms-transition: all 200ms;
-o-transition: all 200ms;
transition: all 200ms;
}
.post-submit:hover, .dm-submit:hover, .undo-unicode:hover {
color: #fff; color: #fff;
opacity: .9; opacity: .9;

Loading…
Cancel
Save