mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Closes #1026,#983,#982,#978 PR #1026 contains the full history of the changes made herein. Due to the volume of commits with no meaningful comment, they have been squashed down to this one. Adding bidi Files Tuning code style Adding rest of bidi files and its dependencies Tuning code style editing numeric shaping value Tuning Code style adding bidi support Adding Bidi Support for the rest of files Adding Bidi support Editing Bidi menu adding mirroring enablement handeling code style Addinng Bidi Support Adding Bidi Support Adding locale settings to national calendar support Adding Numeric Shaping Support scss files after adding rtl direction part 1 adding rtl direction at scss files part2 adding right directionality at comman typeInput correcting some comments editing spaces applying code style editing code style editing code style editing code style editing code style adding right directionality adding right directionality adding style in case of right directionality adding style in case of right directionality adding style in case of right directionality create a global variable for ui direction to call it once need Update main.js Update typedInput.js Update 10-switch.html manage palette mirroring adding RTL directionality to Tabs and Manage palette Style Editing Adding mirroring to subflow workspace handle mirroring defects at manage palette Handle Mirroring defects at sidebar seperator Numeric Shaping Updates Editing code style Handling mirroring defects Handling mirroring defects Fixing mirroring defects editing code style fixing mirroring defects at deploy dialog editing code style Updating Bidi Support handling some reviewing comments handling chicks Update base-text-dir.js Update bidi-util.js Update bidi-util.js Handling reviewing comment Fixing Popover mirroring defect Handling namespace structure for bidi features reflecting new namespace structure for bidi features at editorfiles Handling comments that related to css moving bidi.js under js/bidi folder
1344 lines
51 KiB
JavaScript
1344 lines
51 KiB
JavaScript
/**
|
|
* Copyright 2016 IBM Corp.
|
|
*
|
|
* 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.
|
|
**/
|
|
|
|
RED.bidi.format = (function() {
|
|
|
|
var TextSegment = (function() {
|
|
var TextSegment = function (obj) {
|
|
this.content = "";
|
|
this.actual = "";
|
|
this.textDirection = "";
|
|
this.localGui = "";
|
|
this.isVisible = true;
|
|
this.isSeparator = false;
|
|
this.isParsed = false;
|
|
this.keep = false;
|
|
this.inBounds = false;
|
|
this.inPoints = false;
|
|
var prop = "";
|
|
for (prop in obj) {
|
|
if (obj.hasOwnProperty(prop)) {
|
|
this[prop] = obj[prop];
|
|
}
|
|
}
|
|
};
|
|
return TextSegment;
|
|
})();
|
|
|
|
var tools = (function() {
|
|
function initBounds(bounds) {
|
|
if (!bounds) {
|
|
return false;
|
|
}
|
|
if (typeof(bounds.start) === "undefined") {
|
|
bounds.start = "";
|
|
}
|
|
if (typeof(bounds.end) === "undefined") {
|
|
bounds.end = "";
|
|
}
|
|
if (typeof(bounds.startAfter) !== "undefined") {
|
|
bounds.start = bounds.startAfter;
|
|
bounds.after = true;
|
|
} else {
|
|
bounds.after = false;
|
|
}
|
|
if (typeof(bounds.endBefore) !== "undefined") {
|
|
bounds.end = bounds.endBefore;
|
|
bounds.before = true;
|
|
} else {
|
|
bounds.before = false;
|
|
}
|
|
var startPos = parseInt(bounds.startPos, 10);
|
|
if (!isNaN(startPos)) {
|
|
bounds.usePos = true;
|
|
} else {
|
|
bounds.usePos = false;
|
|
}
|
|
var bLength = parseInt(bounds.length, 10);
|
|
if (!isNaN(bLength)) {
|
|
bounds.useLength = true;
|
|
} else {
|
|
bounds.useLength = false;
|
|
}
|
|
bounds.loops = typeof(bounds.loops) !== "undefined" ? !!bounds.loops : true;
|
|
return true;
|
|
}
|
|
|
|
function getBounds(segment, src) {
|
|
var bounds = {};
|
|
for (var prop in src) {
|
|
if (src.hasOwnProperty(prop)) {
|
|
bounds[prop] = src[prop];
|
|
}
|
|
}
|
|
var content = segment.content;
|
|
var usePos = bounds.usePos && bounds.startPos < content.length;
|
|
if (usePos) {
|
|
bounds.start = "";
|
|
bounds.loops = false;
|
|
}
|
|
bounds.bStart = usePos ? bounds.startPos : bounds.start.length > 0 ? content.indexOf(bounds.start) : 0;
|
|
var useLength = bounds.useLength && bounds.length > 0 && bounds.bStart + bounds.length < content.length;
|
|
if (useLength) {
|
|
bounds.end = "";
|
|
}
|
|
bounds.bEnd = useLength ? bounds.bStart + bounds.length : bounds.end.length > 0 ?
|
|
content.indexOf(bounds.end, bounds.bStart + bounds.start.length) + 1 : content.length;
|
|
if (!bounds.after) {
|
|
bounds.start = "";
|
|
}
|
|
if (!bounds.before) {
|
|
bounds.end = "";
|
|
}
|
|
return bounds;
|
|
}
|
|
|
|
return {
|
|
handleSubcontents: function (segments, args, subs, origContent, locale) { // jshint unused: false
|
|
if (!subs.content || typeof(subs.content) !== "string" || subs.content.length === 0) {
|
|
return segments;
|
|
}
|
|
var sLoops = true;
|
|
if (typeof(subs.loops) !== "undefined") {
|
|
sLoops = !!subs.loops;
|
|
}
|
|
for (var j = 0; true; j++) {
|
|
if (j >= segments.length) {
|
|
break;
|
|
}
|
|
if (segments[j].isParsed || segments.keep || segments[j].isSeparator) {
|
|
continue;
|
|
}
|
|
var content = segments[j].content;
|
|
var start = content.indexOf(subs.content);
|
|
if (start < 0) {
|
|
continue;
|
|
}
|
|
var end;
|
|
var length = 0;
|
|
if (subs.continued) {
|
|
do {
|
|
length++;
|
|
end = content.indexOf(subs.content, start + length * subs.content.length);
|
|
} while (end === 0);
|
|
} else {
|
|
length = 1;
|
|
}
|
|
end = start + length * subs.content.length;
|
|
segments.splice(j, 1);
|
|
if (start > 0) {
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: content.substring(0, start),
|
|
localGui: args.dir,
|
|
keep: true
|
|
}));
|
|
j++;
|
|
}
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: content.substring(start, end),
|
|
textDirection: subs.subDir,
|
|
localGui: args.dir
|
|
}));
|
|
if (end < content.length) {
|
|
segments.splice(j + 1, 0, new TextSegment({
|
|
content: content.substring(end, content.length),
|
|
localGui: args.dir,
|
|
keep: true
|
|
}));
|
|
}
|
|
if (!sLoops) {
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
|
|
handleBounds: function (segments, args, aBounds, origContent, locale) {
|
|
for (var i = 0; i < aBounds.length; i++) {
|
|
if (!initBounds(aBounds[i])) {
|
|
continue;
|
|
}
|
|
for (var j = 0; true; j++) {
|
|
if (j >= segments.length) {
|
|
break;
|
|
}
|
|
if (segments[j].isParsed || segments[j].inBounds || segments.keep || segments[j].isSeparator) {
|
|
continue;
|
|
}
|
|
var bounds = getBounds(segments[j], aBounds[i]);
|
|
var start = bounds.bStart;
|
|
var end = bounds.bEnd;
|
|
if (start < 0 || end < 0) {
|
|
continue;
|
|
}
|
|
var content = segments[j].content;
|
|
|
|
segments.splice(j, 1);
|
|
if (start > 0) {
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: content.substring(0, start),
|
|
localGui: args.dir,
|
|
keep: true
|
|
}));
|
|
j++;
|
|
}
|
|
if (bounds.start) {
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: bounds.start,
|
|
localGui: args.dir,
|
|
isSeparator: true
|
|
}));
|
|
j++;
|
|
}
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: content.substring(start + bounds.start.length, end - bounds.end.length),
|
|
textDirection: bounds.subDir,
|
|
localGui: args.dir,
|
|
inBounds: true
|
|
}));
|
|
if (bounds.end) {
|
|
j++;
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: bounds.end,
|
|
localGui: args.dir,
|
|
isSeparator: true
|
|
}));
|
|
}
|
|
if (end + bounds.end.length < content.length) {
|
|
segments.splice(j + 1, 0, new TextSegment({
|
|
content: content.substring(end + bounds.end.length, content.length),
|
|
localGui: args.dir,
|
|
keep: true
|
|
}));
|
|
}
|
|
if (!bounds.loops) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < segments.length; i++) {
|
|
segments[i].inBounds = false;
|
|
}
|
|
return segments;
|
|
},
|
|
|
|
handleCases: function (segments, args, cases, origContent, locale) {
|
|
if (cases.length === 0) {
|
|
return segments;
|
|
}
|
|
var hArgs = {};
|
|
for (var prop in args) {
|
|
if (args.hasOwnProperty(prop)) {
|
|
hArgs[prop] = args[prop];
|
|
}
|
|
}
|
|
for (var i = 0; i < cases.length; i++) {
|
|
if (!cases[i].handler || typeof(cases[i].handler.handle) !== "function") {
|
|
cases[i].handler = args.commonHandler;
|
|
}
|
|
if (cases[i].args) {
|
|
hArgs.cases = cases[i].args.cases;
|
|
hArgs.points = cases[i].args.points;
|
|
hArgs.bounds = cases[i].args.bounds;
|
|
hArgs.subs = cases[i].args.subs;
|
|
} else {
|
|
hArgs.cases = [];
|
|
hArgs.points = [];
|
|
hArgs.bounds = [];
|
|
hArgs.subs = {};
|
|
}
|
|
cases[i].handler.handle(origContent, segments, hArgs, locale);
|
|
}
|
|
return segments;
|
|
},
|
|
|
|
handlePoints: function (segments, args, points, origContent, locale) { //jshint unused: false
|
|
for (var i = 0; i < points.length; i++) {
|
|
for (var j = 0; true; j++) {
|
|
if (j >= segments.length) {
|
|
break;
|
|
}
|
|
if (segments[j].isParsed || segments[j].keep || segments[j].isSeparator) {
|
|
continue;
|
|
}
|
|
var content = segments[j].content;
|
|
var pos = content.indexOf(points[i]);
|
|
if (pos >= 0) {
|
|
segments.splice(j, 1);
|
|
if (pos > 0) {
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: content.substring(0, pos),
|
|
textDirection: args.subDir,
|
|
localGui: args.dir,
|
|
inPoints: true
|
|
}));
|
|
j++;
|
|
}
|
|
segments.splice(j, 0, new TextSegment({
|
|
content: points[i],
|
|
localGui: args.dir,
|
|
isSeparator: true
|
|
}));
|
|
if (pos + points[i].length + 1 <= content.length) {
|
|
segments.splice(j + 1, 0, new TextSegment({
|
|
content: content.substring(pos + points[i].length),
|
|
textDirection: args.subDir,
|
|
localGui: args.dir,
|
|
inPoints: true
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < segments.length; i++) {
|
|
if (segments[i].keep) {
|
|
segments[i].keep = false;
|
|
} else if(segments[i].inPoints){
|
|
segments[i].isParsed = true;
|
|
segments[i].inPoints = false;
|
|
}
|
|
}
|
|
return segments;
|
|
}
|
|
};
|
|
})();
|
|
|
|
var common = (function() {
|
|
return {
|
|
handle: function (content, segments, args, locale) {
|
|
var cases = [];
|
|
if (Array.isArray(args.cases)) {
|
|
cases = args.cases;
|
|
}
|
|
var points = [];
|
|
if (typeof(args.points) !== "undefined") {
|
|
if (Array.isArray(args.points)) {
|
|
points = args.points;
|
|
} else if (typeof(args.points) === "string") {
|
|
points = args.points.split("");
|
|
}
|
|
}
|
|
var subs = {};
|
|
if (typeof(args.subs) === "object") {
|
|
subs = args.subs;
|
|
}
|
|
var aBounds = [];
|
|
if (Array.isArray(args.bounds)) {
|
|
aBounds = args.bounds;
|
|
}
|
|
|
|
tools.handleBounds(segments, args, aBounds, content, locale);
|
|
tools.handleSubcontents(segments, args, subs, content, locale);
|
|
tools.handleCases(segments, args, cases, content, locale);
|
|
tools.handlePoints(segments, args, points, content, locale);
|
|
return segments;
|
|
}
|
|
};
|
|
})();
|
|
|
|
var misc = (function() {
|
|
var isBidiLocale = function (locale) {
|
|
var lang = !locale ? "" : locale.split("-")[0];
|
|
if (!lang || lang.length < 2) {
|
|
return false;
|
|
}
|
|
return ["iw", "he", "ar", "fa", "ur"].some(function (bidiLang) {
|
|
return bidiLang === lang;
|
|
});
|
|
};
|
|
var LRE = "\u202A";
|
|
var RLE = "\u202B";
|
|
var PDF = "\u202C";
|
|
var LRM = "\u200E";
|
|
var RLM = "\u200F";
|
|
var LRO = "\u202D";
|
|
var RLO = "\u202E";
|
|
|
|
return {
|
|
LRE: LRE,
|
|
RLE: RLE,
|
|
PDF: PDF,
|
|
LRM: LRM,
|
|
RLM: RLM,
|
|
LRO: LRO,
|
|
RLO: RLO,
|
|
|
|
getLocaleDetails: function (locale) {
|
|
if (!locale) {
|
|
locale = typeof navigator === "undefined" ? "" :
|
|
(navigator.language ||
|
|
navigator.userLanguage ||
|
|
"");
|
|
}
|
|
locale = locale.toLowerCase();
|
|
if (isBidiLocale(locale)) {
|
|
var full = locale.split("-");
|
|
return {lang: full[0], country: full[1] ? full[1] : ""};
|
|
}
|
|
return {lang: "not-bidi"};
|
|
},
|
|
|
|
removeUcc: function (text) {
|
|
if (text) {
|
|
return text.replace(/[\u200E\u200F\u202A-\u202E]/g, "");
|
|
}
|
|
return text;
|
|
},
|
|
|
|
removeTags: function (text) {
|
|
if (text) {
|
|
return text.replace(/<[^<]*>/g, "");
|
|
}
|
|
return text;
|
|
},
|
|
|
|
getDirection: function (text, dir, guiDir, checkEnd) {
|
|
if (dir !== "auto" && (/^(rtl|ltr)$/i).test(dir)) {
|
|
return dir;
|
|
}
|
|
guiDir = (/^(rtl|ltr)$/i).test(guiDir) ? guiDir : "ltr";
|
|
var txt = !checkEnd ? text : text.split("").reverse().join("");
|
|
var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(txt);
|
|
return fdc ? (fdc[0] <= "z" ? "ltr" : "rtl") : guiDir;
|
|
},
|
|
|
|
hasArabicChar: function (text) {
|
|
var fdc = /[\u0600-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
|
|
return !!fdc;
|
|
},
|
|
|
|
showMarks: function (text, guiDir) {
|
|
var result = "";
|
|
for (var i = 0; i < text.length; i++) {
|
|
var c = "" + text.charAt(i);
|
|
switch (c) {
|
|
case LRM:
|
|
result += "<LRM>";
|
|
break;
|
|
case RLM:
|
|
result += "<RLM>";
|
|
break;
|
|
case LRE:
|
|
result += "<LRE>";
|
|
break;
|
|
case RLE:
|
|
result += "<RLE>";
|
|
break;
|
|
case LRO:
|
|
result += "<LRO>";
|
|
break;
|
|
case RLO:
|
|
result += "<RLO>";
|
|
break;
|
|
case PDF:
|
|
result += "<PDF>";
|
|
break;
|
|
default:
|
|
result += c;
|
|
}
|
|
}
|
|
var mark = typeof(guiDir) === "undefined" || !((/^(rtl|ltr)$/i).test(guiDir)) ? "" :
|
|
guiDir === "rtl" ? RLO : LRO;
|
|
return mark + result + (mark === "" ? "" : PDF);
|
|
},
|
|
|
|
hideMarks: function (text) {
|
|
var txt = text.replace(/<LRM>/g, this.LRM).replace(/<RLM>/g, this.RLM).replace(/<LRE>/g, this.LRE);
|
|
return txt.replace(/<RLE>/g, this.RLE).replace(/<LRO>/g, this.LRO).replace(/<RLO>/g, this.RLO).replace(/<PDF>/g, this.PDF);
|
|
},
|
|
|
|
showTags: function (text) {
|
|
return "<xmp>" + text + "</xmp>";
|
|
},
|
|
|
|
hideTags: function (text) {
|
|
return text.replace(/<xmp>/g,"").replace(/<\/xmp>/g,"");
|
|
}
|
|
};
|
|
})();
|
|
|
|
var stext = (function() {
|
|
var stt = {};
|
|
|
|
// args
|
|
// handler: main handler (default - dbidi/stt/handlers/common)
|
|
// guiDir: GUI direction (default - "ltr")
|
|
// dir: main stt direction (default - guiDir)
|
|
// subDir: direction of subsegments
|
|
// points: array of delimiters (default - [])
|
|
// bounds: array of definitions of bounds in which handler works
|
|
// subs: object defines special handling for some substring if found
|
|
// cases: array of additional modules with their args for handling special cases (default - [])
|
|
function parseAndDisplayStructure(content, fArgs, isHtml, locale) {
|
|
if (!content || !fArgs) {
|
|
return content;
|
|
}
|
|
return displayStructure(parseStructure(content, fArgs, locale), fArgs, isHtml);
|
|
}
|
|
|
|
function checkArguments(fArgs, fullCheck) {
|
|
var args = Array.isArray(fArgs)? fArgs[0] : fArgs;
|
|
if (!args.guiDir) {
|
|
args.guiDir = "ltr";
|
|
}
|
|
if (!args.dir) {
|
|
args.dir = args.guiDir;
|
|
}
|
|
if (!fullCheck) {
|
|
return args;
|
|
}
|
|
if (typeof(args.points) === "undefined") {
|
|
args.points = [];
|
|
}
|
|
if (!args.cases) {
|
|
args.cases = [];
|
|
}
|
|
if (!args.bounds) {
|
|
args.bounds = [];
|
|
}
|
|
args.commonHandler = common;
|
|
return args;
|
|
}
|
|
|
|
function parseStructure(content, fArgs, locale) {
|
|
if (!content || !fArgs) {
|
|
return new TextSegment({content: ""});
|
|
}
|
|
var args = checkArguments(fArgs, true);
|
|
var segments = [new TextSegment(
|
|
{
|
|
content: content,
|
|
actual: content,
|
|
localGui: args.dir
|
|
})];
|
|
var parse = common.handle;
|
|
if (args.handler && typeof(args.handler) === "function") {
|
|
parse = args.handler.handle;
|
|
}
|
|
parse(content, segments, args, locale);
|
|
return segments;
|
|
}
|
|
|
|
function displayStructure(segments, fArgs, isHtml) {
|
|
var args = checkArguments(fArgs, false);
|
|
if (isHtml) {
|
|
return getResultWithHtml(segments, args);
|
|
}
|
|
else {
|
|
return getResultWithUcc(segments, args);
|
|
}
|
|
}
|
|
|
|
function getResultWithUcc(segments, args, isHtml) {
|
|
var result = "";
|
|
var checkedDir = "";
|
|
var prevDir = "";
|
|
var stop = false;
|
|
for (var i = 0; i < segments.length; i++) {
|
|
if (segments[i].isVisible) {
|
|
var dir = segments[i].textDirection;
|
|
var lDir = segments[i].localGui;
|
|
if (lDir !== "" && prevDir === "") {
|
|
result += (lDir === "rtl" ? misc.RLE : misc.LRE);
|
|
}
|
|
else if(prevDir !== "" && (lDir === "" || lDir !== prevDir || stop)) {
|
|
result += misc.PDF + (i == segments.length - 1 && lDir !== ""? "" : args.dir === "rtl" ? misc.RLM : misc.LRM);
|
|
if (lDir !== "") {
|
|
result += (lDir === "rtl" ? misc.RLE : misc.LRE);
|
|
}
|
|
}
|
|
if (dir === "auto") {
|
|
dir = misc.getDirection(segments[i].content, dir, args.guiDir);
|
|
}
|
|
if ((/^(rtl|ltr)$/i).test(dir)) {
|
|
result += (dir === "rtl" ? misc.RLE : misc.LRE) + segments[i].content + misc.PDF;
|
|
checkedDir = dir;
|
|
}
|
|
else {
|
|
result += segments[i].content;
|
|
checkedDir = misc.getDirection(segments[i].content, dir, args.guiDir, true);
|
|
}
|
|
if (i < segments.length - 1) {
|
|
var locDir = lDir && segments[i+1].localGui? lDir : args.dir;
|
|
result += locDir === "rtl" ? misc.RLM : misc.LRM;
|
|
}
|
|
else if(prevDir !== "") {
|
|
result += misc.PDF;
|
|
}
|
|
prevDir = lDir;
|
|
stop = false;
|
|
}
|
|
else {
|
|
stop = true;
|
|
}
|
|
}
|
|
var sttDir = args.dir === "auto" ? misc.getDirection(segments[0].actual, args.dir, args.guiDir) : args.dir;
|
|
if (sttDir !== args.guiDir) {
|
|
result = (sttDir === "rtl" ? misc.RLE : misc.LRE) + result + misc.PDF;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function getResultWithHtml(segments, args, isHtml) {
|
|
var result = "";
|
|
var checkedDir = "";
|
|
var prevDir = "";
|
|
for (var i = 0; i < segments.length; i++) {
|
|
if (segments[i].isVisible) {
|
|
var dir = segments[i].textDirection;
|
|
var lDir = segments[i].localGui;
|
|
if (lDir !== "" && prevDir === "") {
|
|
result += "<bdi dir='" + (lDir === "rtl" ? "rtl" : "ltr") + "'>";
|
|
}
|
|
else if(prevDir !== "" && (lDir === "" || lDir !== prevDir || stop)) {
|
|
result += "</bdi>" + (i == segments.length - 1 && lDir !== ""? "" : "<span style='unicode-bidi: embed; direction: " + (args.dir === "rtl" ? "rtl" : "ltr") + ";'></span>");
|
|
if (lDir !== "") {
|
|
result += "<bdi dir='" + (lDir === "rtl" ? "rtl" : "ltr") + "'>";
|
|
}
|
|
}
|
|
|
|
if (dir === "auto") {
|
|
dir = misc.getDirection(segments[i].content, dir, args.guiDir);
|
|
}
|
|
if ((/^(rtl|ltr)$/i).test(dir)) {
|
|
//result += "<span style='unicode-bidi: embed; direction: " + (dir === "rtl" ? "rtl" : "ltr") + ";'>" + segments[i].content + "</span>";
|
|
result += "<bdi dir='" + (dir === "rtl" ? "rtl" : "ltr") + "'>" + segments[i].content + "</bdi>";
|
|
checkedDir = dir;
|
|
}
|
|
else {
|
|
result += segments[i].content;
|
|
checkedDir = misc.getDirection(segments[i].content, dir, args.guiDir, true);
|
|
}
|
|
if (i < segments.length - 1) {
|
|
var locDir = lDir && segments[i+1].localGui? lDir : args.dir;
|
|
result += "<span style='unicode-bidi: embed; direction: " + (locDir === "rtl" ? "rtl" : "ltr") + ";'></span>";
|
|
}
|
|
else if(prevDir !== "") {
|
|
result += "</bdi>";
|
|
}
|
|
prevDir = lDir;
|
|
stop = false;
|
|
}
|
|
else {
|
|
stop = true;
|
|
}
|
|
}
|
|
var sttDir = args.dir === "auto" ? misc.getDirection(segments[0].actual, args.dir, args.guiDir) : args.dir;
|
|
if (sttDir !== args.guiDir) {
|
|
result = "<bdi dir='" + (sttDir === "rtl" ? "rtl" : "ltr") + "'>" + result + "</bdi>";
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//TBD ?
|
|
function restore(text, isHtml) {
|
|
return text;
|
|
}
|
|
|
|
stt.parseAndDisplayStructure = parseAndDisplayStructure;
|
|
stt.parseStructure = parseStructure;
|
|
stt.displayStructure = displayStructure;
|
|
stt.restore = restore;
|
|
|
|
return stt;
|
|
})();
|
|
|
|
var breadcrumb = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: args.dir ? args.dir : isRtl ? "rtl" : "ltr",
|
|
subs: {
|
|
content: ">",
|
|
continued: true,
|
|
subDir: isRtl ? "rtl" : "ltr"
|
|
},
|
|
cases: [{
|
|
args: {
|
|
subs: {
|
|
content: "<",
|
|
continued: true,
|
|
subDir: isRtl ? "ltr" : "rtl"
|
|
}
|
|
}
|
|
}]
|
|
};
|
|
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var comma = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: ","
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var email = (function() {
|
|
function getDir(text, locale) {
|
|
if (misc.getLocaleDetails(locale).lang !== "ar") {
|
|
return "ltr";
|
|
}
|
|
var ind = text.indexOf("@");
|
|
if (ind > 0 && ind < text.length - 1) {
|
|
return misc.hasArabicChar(text.substring(ind + 1)) ? "rtl" : "ltr";
|
|
}
|
|
return "ltr";
|
|
}
|
|
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: getDir(text, locale),
|
|
points: "<>.:,;@",
|
|
cases: [{
|
|
handler: common,
|
|
args: {
|
|
bounds: [{
|
|
startAfter: "\"",
|
|
endBefore: "\""
|
|
},
|
|
{
|
|
startAfter: "(",
|
|
endBefore: ")"
|
|
}
|
|
],
|
|
points: ""
|
|
}
|
|
}]
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var filepath = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: "/\\:.&<>"
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var formula = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: " /%^&[]<>=!?~:.,|()+-*{}",
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
|
|
var sql = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: "\t!#%&()*+,-./:;<=>?|[]{}",
|
|
cases: [{
|
|
handler: common,
|
|
args: {
|
|
bounds: [{
|
|
startAfter: "/*",
|
|
endBefore: "*/"
|
|
},
|
|
{
|
|
startAfter: "--",
|
|
end: "\n"
|
|
},
|
|
{
|
|
startAfter: "--"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
handler: common,
|
|
args: {
|
|
subs: {
|
|
content: " ",
|
|
continued: true
|
|
}
|
|
}
|
|
},
|
|
{
|
|
handler: common,
|
|
args: {
|
|
bounds: [{
|
|
startAfter: "'",
|
|
endBefore: "'"
|
|
},
|
|
{
|
|
startAfter: "\"",
|
|
endBefore: "\""
|
|
}
|
|
]
|
|
}
|
|
}
|
|
]
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var underscore = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: "_"
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var url = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: ":?#/@.[]=&<>"
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var word = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: args.dir ? args.dir : isRtl ? "rtl" : "ltr",
|
|
points: " ,.!?;:",
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var xpath = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var fArgs =
|
|
{
|
|
guiDir: isRtl ? "rtl" : "ltr",
|
|
dir: "ltr",
|
|
points: " /[]<>=!:@.|()+-*",
|
|
cases: [{
|
|
handler: common,
|
|
args: {
|
|
bounds: [{
|
|
startAfter: "\"",
|
|
endBefore: "\""
|
|
},
|
|
{
|
|
startAfter: "'",
|
|
endBefore: "'"
|
|
}
|
|
],
|
|
points: ""
|
|
}
|
|
}
|
|
]
|
|
};
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, fArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var custom = (function() {
|
|
return {
|
|
format: function (text, args, isRtl, isHtml, locale, parseOnly) {
|
|
var hArgs = {};
|
|
var prop = "";
|
|
var sArgs = Array.isArray(args)? args[0] : args;
|
|
for (prop in sArgs) {
|
|
if (sArgs.hasOwnProperty(prop)) {
|
|
hArgs[prop] = sArgs[prop];
|
|
}
|
|
}
|
|
hArgs.guiDir = isRtl ? "rtl" : "ltr";
|
|
hArgs.dir = hArgs.dir ? hArgs.dir : hArgs.guiDir;
|
|
if (!parseOnly) {
|
|
return stext.parseAndDisplayStructure(text, hArgs, !!isHtml, locale);
|
|
}
|
|
else {
|
|
return stext.parseStructure(text, hArgs, !!isHtml, locale);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
|
|
var message = (function() {
|
|
var params = {msgLang: "en", msgDir: "", phLang: "", phDir: "", phPacking: ["{","}"], phStt: {type: "none", args: {}}, guiDir: ""};
|
|
var parametersChecked = false;
|
|
|
|
function getDirectionOfLanguage(lang) {
|
|
if (lang === "he" || lang === "iw" || lang === "ar") {
|
|
return "rtl";
|
|
}
|
|
return "ltr";
|
|
}
|
|
|
|
function checkParameters(obj) {
|
|
if (obj.msgDir.length === 0) {
|
|
obj.msgDir = getDirectionOfLanguage(obj.msgLang);
|
|
}
|
|
obj.msgDir = obj.msgDir !== "ltr" && obj.msgDir !== "rtl" && obj.msgDir != "auto"? "ltr" : obj.msgDir;
|
|
if (obj.guiDir.length === 0) {
|
|
obj.guiDir = obj.msgDir;
|
|
}
|
|
obj.guiDir = obj.guiDir !== "rtl"? "ltr" : "rtl";
|
|
if (obj.phDir.length === 0) {
|
|
obj.phDir = obj.phLang.length === 0? obj.msgDir : getDirectionOfLanguage(obj.phLang);
|
|
}
|
|
obj.phDir = obj.phDir !== "ltr" && obj.phDir !== "rtl" && obj.phDir != "auto"? "ltr" : obj.phDir;
|
|
if (typeof (obj.phPacking) === "string") {
|
|
obj.phPacking = obj.phPacking.split("");
|
|
}
|
|
if (obj.phPacking.length < 2) {
|
|
obj.phPacking = ["{","}"];
|
|
}
|
|
}
|
|
|
|
return {
|
|
setDefaults: function (args) {
|
|
for (var prop in args) {
|
|
if (params.hasOwnProperty(prop)) {
|
|
params[prop] = args[prop];
|
|
}
|
|
}
|
|
checkParameters(params);
|
|
parametersChecked = true;
|
|
},
|
|
|
|
format: function (text) {
|
|
if (!parametersChecked) {
|
|
checkParameters(params);
|
|
parametersChecked = true;
|
|
}
|
|
var isHtml = false;
|
|
var hasHtmlArg = false;
|
|
var spLength = params.phPacking[0].length;
|
|
var epLength = params.phPacking[1].length;
|
|
if (arguments.length > 0) {
|
|
var last = arguments[arguments.length-1];
|
|
if (typeof (last) === "boolean") {
|
|
isHtml = last;
|
|
hasHtmlArg = true;
|
|
}
|
|
}
|
|
//Message
|
|
var re = new RegExp(params.phPacking[0] + "\\d+" + params.phPacking[1]);
|
|
var m;
|
|
var tSegments = [];
|
|
var offset = 0;
|
|
var txt = text;
|
|
while ((m = re.exec(txt)) != null) {
|
|
var lastIndex = txt.indexOf(m[0]) + m[0].length;
|
|
if (lastIndex > m[0].length) {
|
|
tSegments.push({text: txt.substring(0, lastIndex - m[0].length), ph: false});
|
|
}
|
|
tSegments.push({text: m[0], ph: true});
|
|
offset += lastIndex;
|
|
txt = txt.substring(lastIndex, txt.length);
|
|
}
|
|
if (offset < text.length) {
|
|
tSegments.push({text: text.substring(offset, text.length), ph: false});
|
|
}
|
|
//Parameters
|
|
var tArgs = [];
|
|
for (var i = 1; i < arguments.length - (hasHtmlArg? 1 : 0); i++) {
|
|
var arg = arguments[i];
|
|
var checkArr = arg;
|
|
var inLoop = false;
|
|
var indArr = 0;
|
|
if (Array.isArray(checkArr)) {
|
|
arg = checkArr[0];
|
|
if (typeof(arg) === "undefined") {
|
|
continue;
|
|
}
|
|
inLoop = true;
|
|
}
|
|
do {
|
|
if (typeof (arg) === "string") {
|
|
tArgs.push({text: arg, dir: params.phDir, stt: params.stt});
|
|
}
|
|
else if(typeof (arg) === "boolean") {
|
|
isHtml = arg;
|
|
}
|
|
else if(typeof (arg) === "object") {
|
|
tArgs.push(arg);
|
|
if (!arg.hasOwnProperty("text")) {
|
|
tArgs[tArgs.length-1].text = "{???}";
|
|
}
|
|
if (!arg.hasOwnProperty("dir") || arg.dir.length === 0) {
|
|
tArgs[tArgs.length-1].dir = params.phDir;
|
|
}
|
|
if (!arg.hasOwnProperty("stt") || (typeof (arg.stt) === "string" && arg.stt.length === 0) ||
|
|
(typeof (arg.stt) === "object" && Object.keys(arg.stt).length === 0)) {
|
|
tArgs[tArgs.length-1].stt = params.phStt;
|
|
}
|
|
}
|
|
else {
|
|
tArgs.push({text: "" + arg, dir: params.phDir, stt: params.phStt});
|
|
}
|
|
if (inLoop) {
|
|
indArr++;
|
|
if (indArr == checkArr.length) {
|
|
inLoop = false;
|
|
}
|
|
else {
|
|
arg = checkArr[indArr];
|
|
}
|
|
}
|
|
} while(inLoop);
|
|
}
|
|
//Indexing
|
|
var segments = [];
|
|
for (i = 0; i < tSegments.length; i++) {
|
|
var t = tSegments[i];
|
|
if (!t.ph) {
|
|
segments.push(new TextSegment({content: t.text, textDirection: params.msgDir}));
|
|
}
|
|
else {
|
|
var ind = parseInt(t.text.substring(spLength, t.text.length - epLength));
|
|
if (isNaN(ind) || ind >= tArgs.length) {
|
|
segments.push(new TextSegment({content: t.text, textDirection: params.msgDir}));
|
|
continue;
|
|
}
|
|
var sttType = "none";
|
|
if (!tArgs[ind].stt) {
|
|
tArgs[ind].stt = params.phStt;
|
|
}
|
|
if (tArgs[ind].stt) {
|
|
if (typeof (tArgs[ind].stt) === "string") {
|
|
sttType = tArgs[ind].stt;
|
|
}
|
|
else if(tArgs[ind].stt.hasOwnProperty("type")) {
|
|
sttType = tArgs[ind].stt.type;
|
|
}
|
|
}
|
|
if (sttType.toLowerCase() !== "none") {
|
|
var sttSegs = getHandler(sttType).format(tArgs[ind].text, tArgs[ind].stt.args || {},
|
|
params.msgDir === "rtl", false, params.msgLang, true);
|
|
for (var j = 0; j < sttSegs.length; j++) {
|
|
segments.push(sttSegs[j]);
|
|
}
|
|
segments.push(new TextSegment({isVisible: false}));
|
|
}
|
|
else {
|
|
segments.push(new TextSegment({content: tArgs[ind].text, textDirection: (tArgs[ind].dir? tArgs[ind].dir : params.phDir)}));
|
|
}
|
|
}
|
|
}
|
|
var result = stext.displayStructure(segments, {guiDir: params.guiDir, dir: params.msgDir}, isHtml);
|
|
return result;
|
|
}
|
|
};
|
|
})();
|
|
|
|
var event = null;
|
|
|
|
function getHandler(type) {
|
|
switch (type) {
|
|
case "breadcrumb" :
|
|
return breadcrumb;
|
|
case "comma" :
|
|
return comma;
|
|
case "email" :
|
|
return email;
|
|
case "filepath" :
|
|
return filepath;
|
|
case "formula" :
|
|
return formula;
|
|
case "sql" :
|
|
return sql;
|
|
case "underscore" :
|
|
return underscore;
|
|
case "url" :
|
|
return url;
|
|
case "word" :
|
|
return word;
|
|
case "xpath" :
|
|
return xpath;
|
|
default:
|
|
return custom;
|
|
}
|
|
}
|
|
|
|
function isInputEventSupported(element) {
|
|
var agent = window.navigator.userAgent;
|
|
if (agent.indexOf("MSIE") >=0 || agent.indexOf("Trident") >=0 || agent.indexOf("Edge") >=0) {
|
|
return false;
|
|
}
|
|
var checked = document.createElement(element.tagName);
|
|
checked.contentEditable = true;
|
|
var isSupported = ("oninput" in checked);
|
|
if (!isSupported) {
|
|
checked.setAttribute('oninput', 'return;');
|
|
isSupported = typeof checked['oninput'] == 'function';
|
|
}
|
|
checked = null;
|
|
return isSupported;
|
|
}
|
|
|
|
function attachElement(element, type, args, isRtl, locale) {
|
|
//if (!element || element.nodeType != 1 || !element.isContentEditable)
|
|
if (!element || element.nodeType != 1) {
|
|
return false;
|
|
}
|
|
if (!event) {
|
|
event = document.createEvent('Event');
|
|
event.initEvent('TF', true, true);
|
|
}
|
|
element.setAttribute("data-tf-type", type);
|
|
var sArgs = args === "undefined"? "{}" : JSON.stringify(Array.isArray(args)? args[0] : args);
|
|
element.setAttribute("data-tf-args", sArgs);
|
|
var dir = "ltr";
|
|
if (isRtl === "undefined") {
|
|
if (element.dir) {
|
|
dir = element.dir;
|
|
}
|
|
else if(element.style && element.style.direction) {
|
|
dir = element.style.direction;
|
|
}
|
|
isRtl = dir.toLowerCase() === "rtl";
|
|
}
|
|
element.setAttribute("data-tf-dir", isRtl);
|
|
element.setAttribute("data-tf-locale", misc.getLocaleDetails(locale).lang);
|
|
if (isInputEventSupported(element)) {
|
|
var ehandler = element.oninput;
|
|
element.oninput = function(event) {
|
|
displayWithStructure(event.target);
|
|
};
|
|
}
|
|
else {
|
|
element.onkeyup = function(e) {
|
|
displayWithStructure(e.target);
|
|
element.dispatchEvent(event);
|
|
};
|
|
element.onmouseup = function(e) {
|
|
displayWithStructure(e.target);
|
|
element.dispatchEvent(event);
|
|
};
|
|
}
|
|
displayWithStructure(element);
|
|
|
|
return true;
|
|
}
|
|
|
|
function detachElement(element) {
|
|
if (!element || element.nodeType != 1) {
|
|
return;
|
|
}
|
|
element.removeAttribute("data-tf-type");
|
|
element.removeAttribute("data-tf-args");
|
|
element.removeAttribute("data-tf-dir");
|
|
element.removeAttribute("data-tf-locale");
|
|
element.innerHTML = element.textContent || "";
|
|
}
|
|
|
|
function displayWithStructure(element) {
|
|
var txt = element.textContent || "";
|
|
var selection = document.getSelection();
|
|
if (txt.length === 0 || !selection || selection.rangeCount <= 0) {
|
|
element.dispatchEvent(event);
|
|
return;
|
|
}
|
|
|
|
var range = selection.getRangeAt(0);
|
|
var tempRange = range.cloneRange(), startNode, startOffset;
|
|
startNode = range.startContainer;
|
|
startOffset = range.startOffset;
|
|
var textOffset = 0;
|
|
if (startNode.nodeType === 3) {
|
|
textOffset += startOffset;
|
|
}
|
|
tempRange.setStart(element,0);
|
|
tempRange.setEndBefore(startNode);
|
|
var div = document.createElement('div');
|
|
div.appendChild(tempRange.cloneContents());
|
|
textOffset += div.textContent.length;
|
|
|
|
element.innerHTML = getHandler(element.getAttribute("data-tf-type")).
|
|
format(txt, JSON.parse(element.getAttribute("data-tf-args")), (element.getAttribute("data-tf-dir") === "true"? true : false),
|
|
true, element.getAttribute("data-tf-locale"));
|
|
var parent = element;
|
|
var node = element;
|
|
var newOffset = 0;
|
|
var inEnd = false;
|
|
selection.removeAllRanges();
|
|
range.setStart(element,0);
|
|
range.setEnd(element,0);
|
|
while (node) {
|
|
if (node.nodeType === 3) {
|
|
if (newOffset + node.nodeValue.length >= textOffset) {
|
|
range.setStart(node, textOffset - newOffset);
|
|
break;
|
|
}
|
|
else {
|
|
newOffset += node.nodeValue.length;
|
|
node = node.nextSibling;
|
|
}
|
|
}
|
|
else if(node.hasChildNodes()) {
|
|
parent = node;
|
|
node = parent.firstChild;
|
|
continue;
|
|
}
|
|
else {
|
|
node = node.nextSibling;
|
|
}
|
|
while (!node) {
|
|
if (parent === element) {
|
|
inEnd = true;
|
|
break;
|
|
}
|
|
node = parent.nextSibling;
|
|
parent = parent.parentNode;
|
|
}
|
|
if (inEnd) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
selection.addRange(range);
|
|
element.dispatchEvent(event);
|
|
}
|
|
|
|
return {
|
|
/**
|
|
* Returns the string representation of a given structured text
|
|
* @param text - the structured text
|
|
* @param type - could be one of filepath, url, email
|
|
* @param args - pass additional arguments to the handler. generally null.
|
|
* @param isRtl - indicates if the GUI is mirrored
|
|
* @param locale - the browser locale
|
|
*/
|
|
getString: function (text, type, args, isRtl, locale) {
|
|
return getHandler(type).format(text, args, isRtl, false, locale);
|
|
},
|
|
|
|
/**
|
|
* Returns the HTML representation of a given structured text
|
|
* @param text - the structured text
|
|
* @param type - could be one of filepath, url, email
|
|
* @param args - pass additional arguments to the handler. generally null.
|
|
* @param isRtl - indicates if the GUI is mirrored
|
|
* @param locale - the browser locale
|
|
*/
|
|
getHtml: function (text, type, args, isRtl, locale) {
|
|
return getHandler(type).format(text, args, isRtl, true, locale);
|
|
},
|
|
/**
|
|
* Handle Structured text correct display for a given HTML element.
|
|
* @param element - the element : should be of type div contenteditable=true
|
|
* @param type - could be one of filepath, url, email
|
|
* @param args - pass additional arguments to the handler. generally null.
|
|
* @param isRtl - indicates if the GUI is mirrored
|
|
* @param locale - the browser locale
|
|
*/
|
|
attach: function (element, type, args, isRtl, locale) {
|
|
return attachElement(element, type, args, isRtl, locale);
|
|
}
|
|
};
|
|
})();
|