From 98e2821b38a775737e42a2479a6bc65107210859 Mon Sep 17 00:00:00 2001 From: Elliot Kroo Date: Thu, 11 Mar 2010 15:21:30 -0800 Subject: reorganizing the first level of folders (trunk/branch folders are not the git way :) --- infrastructure/ace/www/linestylefilter.js | 247 ++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 infrastructure/ace/www/linestylefilter.js (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js new file mode 100644 index 0000000..0ac578b --- /dev/null +++ b/infrastructure/ace/www/linestylefilter.js @@ -0,0 +1,247 @@ +// THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.linestylefilter +// %APPJET%: import("etherpad.collab.ace.easysync2.Changeset"); + +/** + * Copyright 2009 Google Inc. + * + * 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. + */ + +// requires: easysync2.Changeset + +var linestylefilter = {}; + +linestylefilter.ATTRIB_CLASSES = { + 'bold':'tag:b', + 'italic':'tag:i', + 'underline':'tag:u', + 'strikethrough':'tag:s' +}; + +linestylefilter.getAuthorClassName = function(author) { + return "author-"+author.replace(/[^a-y0-9]/g, function(c) { + if (c == ".") return "-"; + return 'z'+c.charCodeAt(0)+'z'; + }); +}; + +// lineLength is without newline; aline includes newline, +// but may be falsy if lineLength == 0 +linestylefilter.getLineStyleFilter = function(lineLength, aline, + textAndClassFunc, apool) { + + if (lineLength == 0) return textAndClassFunc; + + var nextAfterAuthorColors = textAndClassFunc; + + var authorColorFunc = (function() { + var lineEnd = lineLength; + var curIndex = 0; + var extraClasses; + var leftInAuthor; + + function attribsToClasses(attribs) { + var classes = ''; + Changeset.eachAttribNumber(attribs, function(n) { + var key = apool.getAttribKey(n); + if (key) { + var value = apool.getAttribValue(n); + if (value) { + if (key == 'author') { + classes += ' '+linestylefilter.getAuthorClassName(value); + } + else if (key == 'list') { + classes += ' list:'+value; + } + else if (linestylefilter.ATTRIB_CLASSES[key]) { + classes += ' '+linestylefilter.ATTRIB_CLASSES[key]; + } + } + } + }); + return classes.substring(1); + } + + var attributionIter = Changeset.opIterator(aline); + var nextOp, nextOpClasses; + function goNextOp() { + nextOp = attributionIter.next(); + nextOpClasses = (nextOp.opcode && attribsToClasses(nextOp.attribs)); + } + goNextOp(); + function nextClasses() { + if (curIndex < lineEnd) { + extraClasses = nextOpClasses; + leftInAuthor = nextOp.chars; + goNextOp(); + while (nextOp.opcode && nextOpClasses == extraClasses) { + leftInAuthor += nextOp.chars; + goNextOp(); + } + } + } + nextClasses(); + + return function(txt, cls) { + while (txt.length > 0) { + if (leftInAuthor <= 0) { + // prevent infinite loop if something funny's going on + return nextAfterAuthorColors(txt, cls); + } + var spanSize = txt.length; + if (spanSize > leftInAuthor) { + spanSize = leftInAuthor; + } + var curTxt = txt.substring(0, spanSize); + txt = txt.substring(spanSize); + nextAfterAuthorColors(curTxt, (cls&&cls+" ")+extraClasses); + curIndex += spanSize; + leftInAuthor -= spanSize; + if (leftInAuthor == 0) { + nextClasses(); + } + } + }; + })(); + return authorColorFunc; +}; + +linestylefilter.getAtSignSplitterFilter = function(lineText, + textAndClassFunc) { + var at = /@/g; + at.lastIndex = 0; + var splitPoints = null; + var execResult; + while ((execResult = at.exec(lineText))) { + if (! splitPoints) { + splitPoints = []; + } + splitPoints.push(execResult.index); + } + + if (! splitPoints) return textAndClassFunc; + + return linestylefilter.textAndClassFuncSplitter(textAndClassFunc, + splitPoints); +}; + +linestylefilter.REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/; +linestylefilter.REGEX_URLCHAR = new RegExp('('+/[-:@a-zA-Z0-9_.,~%+\/\\?=&#;()$]/.source+'|'+linestylefilter.REGEX_WORDCHAR.source+')'); +linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt):\/\/|mailto:)/.source+linestylefilter.REGEX_URLCHAR.source+'*(?![:.,;])'+linestylefilter.REGEX_URLCHAR.source, 'g'); + +linestylefilter.getURLFilter = function(lineText, textAndClassFunc) { + linestylefilter.REGEX_URL.lastIndex = 0; + var urls = null; + var splitPoints = null; + var execResult; + while ((execResult = linestylefilter.REGEX_URL.exec(lineText))) { + if (! urls) { + urls = []; + splitPoints = []; + } + var startIndex = execResult.index; + var url = execResult[0]; + urls.push([startIndex, url]); + splitPoints.push(startIndex, startIndex + url.length); + } + + if (! urls) return textAndClassFunc; + + function urlForIndex(idx) { + for(var k=0; k= u[0] && idx < u[0]+u[1].length) { + return u[1]; + } + } + return false; + } + + var handleUrlsAfterSplit = (function() { + var curIndex = 0; + return function(txt, cls) { + var txtlen = txt.length; + var newCls = cls; + var url = urlForIndex(curIndex); + if (url) { + newCls += " url:"+url; + } + textAndClassFunc(txt, newCls); + curIndex += txtlen; + }; + })(); + + return linestylefilter.textAndClassFuncSplitter(handleUrlsAfterSplit, + splitPoints); +}; + +linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { + var nextPointIndex = 0; + var idx = 0; + + // don't split at 0 + while (splitPointsOpt && + nextPointIndex < splitPointsOpt.length && + splitPointsOpt[nextPointIndex] == 0) { + nextPointIndex++; + } + + function spanHandler(txt, cls) { + if ((! splitPointsOpt) || nextPointIndex >= splitPointsOpt.length) { + func(txt, cls); + idx += txt.length; + } + else { + var splitPoints = splitPointsOpt; + var pointLocInSpan = splitPoints[nextPointIndex] - idx; + var txtlen = txt.length; + if (pointLocInSpan >= txtlen) { + func(txt, cls); + idx += txt.length; + if (pointLocInSpan == txtlen) { + nextPointIndex++; + } + } + else { + if (pointLocInSpan > 0) { + func(txt.substring(0, pointLocInSpan), cls); + idx += pointLocInSpan; + } + nextPointIndex++; + // recurse + spanHandler(txt.substring(pointLocInSpan), cls); + } + } + } + return spanHandler; +}; + +// domLineObj is like that returned by domline.createDomLine +linestylefilter.populateDomLine = function(textLine, aline, apool, + domLineObj) { + // remove final newline from text if any + var text = textLine; + if (text.slice(-1) == '\n') { + text = text.substring(0, text.length-1); + } + + function textAndClassFunc(tokenText, tokenClass) { + domLineObj.appendSpan(tokenText, tokenClass); + } + + var func = textAndClassFunc; + func = linestylefilter.getURLFilter(text, func); + func = linestylefilter.getLineStyleFilter(text.length, aline, + func, apool); + func(text, ''); +}; -- cgit v1.2.3 From b897b18b9cb727f277a41ba12349548fe854d724 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Thu, 25 Mar 2010 17:53:24 +0100 Subject: Added support for plugins in the ACE linefilter --- infrastructure/ace/www/linestylefilter.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index 0ac578b..c493911 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -1,5 +1,6 @@ // THIS FILE IS ALSO AN APPJET MODULE: etherpad.collab.ace.linestylefilter // %APPJET%: import("etherpad.collab.ace.easysync2.Changeset"); +// %APPJET%: import("etherpad.admin.plugins"); /** * Copyright 2009 Google Inc. @@ -18,6 +19,10 @@ */ // requires: easysync2.Changeset +// requires: top +// requires: plugins +// requires: plugins +// requires: undefined var linestylefilter = {}; @@ -226,6 +231,27 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { return spanHandler; }; +linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { + var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); + + /* Handle both client and server side situation */ + + var pluginModule = (top == undefined) ? plugins : top.plugins; + + var hookFilters = pluginModule.callHook("aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); + for (var i = 0; i < hookFilters.length; i++) + func = hookFilters[i](lineText, func); + + if (browser !== undefined && browser.msie) { + // IE7+ will take an e-mail address like and linkify it to foo@bar.com. + // We then normalize it back to text with no angle brackets. It's weird. So always + // break spans at an "at" sign. + func = linestylefilter.getAtSignSplitterFilter( + lineText, func); + } + return func; +}; + // domLineObj is like that returned by domline.createDomLine linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj) { @@ -239,8 +265,7 @@ linestylefilter.populateDomLine = function(textLine, aline, apool, domLineObj.appendSpan(tokenText, tokenClass); } - var func = textAndClassFunc; - func = linestylefilter.getURLFilter(text, func); + var func = linestylefilter.getFilterStack(text, textAndClassFunc); func = linestylefilter.getLineStyleFilter(text.length, aline, func, apool); func(text, ''); -- cgit v1.2.3 From f7dd3aa34cad8a59ad00172339c565731ad80fbb Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Thu, 25 Mar 2010 18:21:35 +0100 Subject: Generalized linestylefilter.getURLFilter to a linestylefilter.getRegexpFilter --- infrastructure/ace/www/linestylefilter.js | 89 ++++++++++++++++--------------- 1 file changed, 47 insertions(+), 42 deletions(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index c493911..71bc30d 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -140,56 +140,61 @@ linestylefilter.getAtSignSplitterFilter = function(lineText, splitPoints); }; -linestylefilter.REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/; -linestylefilter.REGEX_URLCHAR = new RegExp('('+/[-:@a-zA-Z0-9_.,~%+\/\\?=&#;()$]/.source+'|'+linestylefilter.REGEX_WORDCHAR.source+')'); -linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt):\/\/|mailto:)/.source+linestylefilter.REGEX_URLCHAR.source+'*(?![:.,;])'+linestylefilter.REGEX_URLCHAR.source, 'g'); - -linestylefilter.getURLFilter = function(lineText, textAndClassFunc) { - linestylefilter.REGEX_URL.lastIndex = 0; - var urls = null; - var splitPoints = null; - var execResult; - while ((execResult = linestylefilter.REGEX_URL.exec(lineText))) { - if (! urls) { - urls = []; - splitPoints = []; +linestylefilter.getRegexpFilter = function (regExp, tag) { + return function (lineText, textAndClassFunc) { + regExp.lastIndex = 0; + var regExpMatchs = null; + var splitPoints = null; + var execResult; + while ((execResult = regExp.exec(lineText))) { + if (! regExpMatchs) { + regExpMatchs = []; + splitPoints = []; + } + var startIndex = execResult.index; + var regExpMatch = execResult[0]; + regExpMatchs.push([startIndex, regExpMatch]); + splitPoints.push(startIndex, startIndex + regExpMatch.length); } - var startIndex = execResult.index; - var url = execResult[0]; - urls.push([startIndex, url]); - splitPoints.push(startIndex, startIndex + url.length); - } - if (! urls) return textAndClassFunc; + if (! regExpMatchs) return textAndClassFunc; - function urlForIndex(idx) { - for(var k=0; k= u[0] && idx < u[0]+u[1].length) { - return u[1]; + function regExpMatchForIndex(idx) { + for(var k=0; k= u[0] && idx < u[0]+u[1].length) { + return u[1]; + } } + return false; } - return false; - } - var handleUrlsAfterSplit = (function() { - var curIndex = 0; - return function(txt, cls) { - var txtlen = txt.length; - var newCls = cls; - var url = urlForIndex(curIndex); - if (url) { - newCls += " url:"+url; - } - textAndClassFunc(txt, newCls); - curIndex += txtlen; - }; - })(); - - return linestylefilter.textAndClassFuncSplitter(handleUrlsAfterSplit, - splitPoints); + var handleRegExpMatchsAfterSplit = (function() { + var curIndex = 0; + return function(txt, cls) { + var txtlen = txt.length; + var newCls = cls; + var regExpMatch = regExpMatchForIndex(curIndex); + if (regExpMatch) { + newCls += " "+tag+":"+regExpMatch; + } + textAndClassFunc(txt, newCls); + curIndex += txtlen; + }; + })(); + + return linestylefilter.textAndClassFuncSplitter(handleRegExpMatchsAfterSplit, + splitPoints); + }; }; + +linestylefilter.REGEX_WORDCHAR = /[\u0030-\u0039\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u1FFF\u3040-\u9FFF\uF900-\uFDFF\uFE70-\uFEFE\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFDC]/; +linestylefilter.REGEX_URLCHAR = new RegExp('('+/[-:@a-zA-Z0-9_.,~%+\/\\?=&#;()$]/.source+'|'+linestylefilter.REGEX_WORDCHAR.source+')'); +linestylefilter.REGEX_URL = new RegExp(/(?:(?:https?|s?ftp|ftps|file|smb|afp|nfs|(x-)?man|gopher|txmt):\/\/|mailto:)/.source+linestylefilter.REGEX_URLCHAR.source+'*(?![:.,;])'+linestylefilter.REGEX_URLCHAR.source, 'g'); +linestylefilter.getURLFilter = linestylefilter.getRegexpFilter( + linestylefilter.REGEX_URL, 'url'); + linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { var nextPointIndex = 0; var idx = 0; -- cgit v1.2.3 From 20014050bf91266757b2c1ba82ab333638fe570d Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Thu, 25 Mar 2010 19:14:53 +0100 Subject: Added aceCreateDomline hook plus some code cleanup in the ace --- infrastructure/ace/www/linestylefilter.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index 71bc30d..d69376a 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -21,7 +21,6 @@ // requires: easysync2.Changeset // requires: top // requires: plugins -// requires: plugins // requires: undefined var linestylefilter = {}; @@ -239,13 +238,11 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); - /* Handle both client and server side situation */ - - var pluginModule = (top == undefined) ? plugins : top.plugins; - - var hookFilters = pluginModule.callHook("aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); - for (var i = 0; i < hookFilters.length; i++) - func = hookFilters[i](lineText, func); + var hookFilters = ((top == undefined) ? plugins : top.plugins).callHook( + "aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); + hookFilters.map(function (hookFilter) { + func = hookFilter(lineText, func); + }); if (browser !== undefined && browser.msie) { // IE7+ will take an e-mail address like and linkify it to foo@bar.com. -- cgit v1.2.3 From 0b3182ce6e606d7f87cfd25fb58602980b41bc97 Mon Sep 17 00:00:00 2001 From: Egil Moeller Date: Sat, 27 Mar 2010 16:44:50 +0100 Subject: Bugfix for the ace callHook support --- infrastructure/ace/www/linestylefilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index d69376a..c163120 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -238,7 +238,7 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); - var hookFilters = ((top == undefined) ? plugins : top.plugins).callHook( + var hookFilters = (function () { try { return top.plugins; } catch (e) { return plugins; }; })().callHook( "aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); hookFilters.map(function (hookFilter) { func = hookFilter(lineText, func); -- cgit v1.2.3 From e794aa43d7977aa58a7ef8704ac212008e0280e9 Mon Sep 17 00:00:00 2001 From: "Simon B @piratpartiet" Date: Wed, 21 Apr 2010 10:55:30 +0200 Subject: Fix IFRAME bug. Closes #70 --- infrastructure/ace/www/linestylefilter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index c163120..341345e 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -238,7 +238,7 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); - var hookFilters = (function () { try { return top.plugins; } catch (e) { return plugins; }; })().callHook( + var hookFilters = parent.parent.plugins.callHook( "aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); hookFilters.map(function (hookFilter) { func = hookFilter(lineText, func); -- cgit v1.2.3 From c318ce528125da08ec3d4b4714d35e1b59de73eb Mon Sep 17 00:00:00 2001 From: "Simon B @piratpartiet" Date: Thu, 22 Apr 2010 00:16:22 +0200 Subject: Bugfix regession from IFRAME+IE bugs. Closes GH-70 --- infrastructure/ace/www/linestylefilter.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'infrastructure/ace/www/linestylefilter.js') diff --git a/infrastructure/ace/www/linestylefilter.js b/infrastructure/ace/www/linestylefilter.js index 341345e..196cb63 100644 --- a/infrastructure/ace/www/linestylefilter.js +++ b/infrastructure/ace/www/linestylefilter.js @@ -238,7 +238,14 @@ linestylefilter.textAndClassFuncSplitter = function(func, splitPointsOpt) { linestylefilter.getFilterStack = function(lineText, textAndClassFunc, browser) { var func = linestylefilter.getURLFilter(lineText, textAndClassFunc); - var hookFilters = parent.parent.plugins.callHook( + var plugins_; + if (typeof(plugins)!='undefined') { + plugins_ = plugins; + } else { + plugins_ = parent.parent.plugins; + } + + var hookFilters = plugins_.callHook( "aceGetFilterStack", {linestylefilter:linestylefilter, browser:browser}); hookFilters.map(function (hookFilter) { func = hookFilter(lineText, func); -- cgit v1.2.3