Return-Path: X-Original-To: apmail-corinthia-commits-archive@minotaur.apache.org Delivered-To: apmail-corinthia-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3113C17D1F for ; Sun, 16 Aug 2015 10:58:16 +0000 (UTC) Received: (qmail 95937 invoked by uid 500); 16 Aug 2015 10:58:16 -0000 Delivered-To: apmail-corinthia-commits-archive@corinthia.apache.org Received: (qmail 95918 invoked by uid 500); 16 Aug 2015 10:58:16 -0000 Mailing-List: contact commits-help@corinthia.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@corinthia.incubator.apache.org Delivered-To: mailing list commits@corinthia.incubator.apache.org Received: (qmail 95899 invoked by uid 99); 16 Aug 2015 10:58:16 -0000 Received: from Unknown (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 16 Aug 2015 10:58:16 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 7728CDE324 for ; Sun, 16 Aug 2015 10:58:15 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.105 X-Spam-Level: * X-Spam-Status: No, score=1.105 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-0.697, URIBL_BLOCKED=0.001, WEIRD_QUOTING=0.001] autolearn=disabled Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id TVV2zLB_Oz2F for ; Sun, 16 Aug 2015 10:58:00 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with SMTP id 46B4842C06 for ; Sun, 16 Aug 2015 10:57:38 +0000 (UTC) Received: (qmail 94138 invoked by uid 99); 16 Aug 2015 10:57:38 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 16 Aug 2015 10:57:38 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id EA538E03D2; Sun, 16 Aug 2015 10:57:37 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jani@apache.org To: commits@corinthia.incubator.apache.org Date: Sun, 16 Aug 2015 10:58:25 -0000 Message-Id: <8465a8c0145e49a08ac8e26dc6a3915f@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [50/51] [partial] incubator-corinthia git commit: Added editorFramework in experiments. http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/26f461e7/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index d1f43c2..4e6af40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,8 +81,5 @@ add_subdirectory(DocFormats) add_subdirectory(consumers/dftest/src) add_subdirectory(consumers/dfconvert/src) add_subdirectory(consumers/dfutil/src) -if(DEFINED NONCONFORM_APACHE) - add_subdirectory(consumers/corinthia/src) -endif(DEFINED NONCONFORM_APACHE) - add_subdirectory(experiments/flat/src) +add_subdirectory(experiments/editorframework) http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/26f461e7/experiments/Editor/src/3rdparty/showdown/license.txt ---------------------------------------------------------------------- diff --git a/experiments/Editor/src/3rdparty/showdown/license.txt b/experiments/Editor/src/3rdparty/showdown/license.txt deleted file mode 100644 index e9c8672..0000000 --- a/experiments/Editor/src/3rdparty/showdown/license.txt +++ /dev/null @@ -1,34 +0,0 @@ -Copyright (c) 2007, John Fraser - -All rights reserved. - -Original Markdown copyright (c) 2004, John Gruber - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the name "Markdown" nor the names of its contributors may - be used to endorse or promote products derived from this software - without specific prior written permission. - -This software is provided by the copyright holders and contributors "as -is" and any express or implied warranties, including, but not limited -to, the implied warranties of merchantability and fitness for a -particular purpose are disclaimed. In no event shall the copyright owner -or contributors be liable for any direct, indirect, incidental, special, -exemplary, or consequential damages (including, but not limited to, -procurement of substitute goods or services; loss of use, data, or -profits; or business interruption) however caused and on any theory of -liability, whether in contract, strict liability, or tort (including -negligence or otherwise) arising in any way out of the use of this -software, even if advised of the possibility of such damage. http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/26f461e7/experiments/Editor/src/3rdparty/showdown/showdown.js ---------------------------------------------------------------------- diff --git a/experiments/Editor/src/3rdparty/showdown/showdown.js b/experiments/Editor/src/3rdparty/showdown/showdown.js deleted file mode 100644 index 734dabb..0000000 --- a/experiments/Editor/src/3rdparty/showdown/showdown.js +++ /dev/null @@ -1,1302 +0,0 @@ -// -// showdown.js -- A javascript port of Markdown. -// -// Copyright (c) 2007 John Fraser. -// -// Original Markdown Copyright (c) 2004-2005 John Gruber -// -// -// Redistributable under a BSD-style open source license. -// See license.txt for more information. -// -// The full source distribution is at: -// -// A A L -// T C A -// T K B -// -// -// - -// -// Wherever possible, Showdown is a straight, line-by-line port -// of the Perl version of Markdown. -// -// This is not a normal parser design; it's basically just a -// series of string substitutions. It's hard to read and -// maintain this way, but keeping Showdown close to the original -// design makes it easier to port new features. -// -// More importantly, Showdown behaves like markdown.pl in most -// edge cases. So web applications can do client-side preview -// in Javascript, and then build identical HTML on the server. -// -// This port needs the new RegExp functionality of ECMA 262, -// 3rd Edition (i.e. Javascript 1.5). Most modern web browsers -// should do fine. Even with the new regular expression features, -// We do a lot of work to emulate Perl's regex functionality. -// The tricky changes in this file mostly have the "attacklab:" -// label. Major or self-explanatory changes don't. -// -// Smart diff tools like Araxis Merge will be able to match up -// this file with markdown.pl in a useful way. A little tweaking -// helps: in a copy of markdown.pl, replace "#" with "//" and -// replace "$text" with "text". Be sure to ignore whitespace -// and line endings. -// - - -// -// Showdown usage: -// -// var text = "Markdown *rocks*."; -// -// var converter = new Showdown.converter(); -// var html = converter.makeHtml(text); -// -// alert(html); -// -// Note: move the sample code to the bottom of this -// file before uncommenting it. -// - - -// -// Showdown namespace -// -var Showdown = {}; - -// -// converter -// -// Wraps all "globals" so that the only thing -// exposed is makeHtml(). -// -Showdown.converter = function() { - -// -// Globals: -// - -// Global hashes, used by various utility routines -var g_urls; -var g_titles; -var g_html_blocks; - -// Used to track when we're inside an ordered or unordered list -// (see _ProcessListItems() for details): -var g_list_level = 0; - - -this.makeHtml = function(text) { -// -// Main function. The order in which other subs are called here is -// essential. Link and image substitutions need to happen before -// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the -// and tags get encoded. -// - - // Clear the global hashes. If we don't clear these, you get conflicts - // from other articles when generating a page which contains more than - // one article (e.g. an index page that shows the N most recent - // articles): - g_urls = new Array(); - g_titles = new Array(); - g_html_blocks = new Array(); - - // attacklab: Replace ~ with ~T - // This lets us use tilde as an escape char to avoid md5 hashes - // The choice of character is arbitray; anything that isn't - // magic in Markdown will work. - text = text.replace(/~/g,"~T"); - - // attacklab: Replace $ with ~D - // RegExp interprets $ as a special character - // when it's in a replacement string - text = text.replace(/\$/g,"~D"); - - // Standardize line endings - text = text.replace(/\r\n/g,"\n"); // DOS to Unix - text = text.replace(/\r/g,"\n"); // Mac to Unix - - // Make sure text begins and ends with a couple of newlines: - text = "\n\n" + text + "\n\n"; - - // Convert all tabs to spaces. - text = _Detab(text); - - // Strip any lines consisting only of spaces and tabs. - // This makes subsequent regexen easier to write, because we can - // match consecutive blank lines with /\n+/ instead of something - // contorted like /[ \t]*\n+/ . - text = text.replace(/^[ \t]+$/mg,""); - - // Turn block-level HTML blocks into hash entries - text = _HashHTMLBlocks(text); - - // Strip link definitions, store in hashes. - text = _StripLinkDefinitions(text); - - text = _RunBlockGamut(text); - - text = _UnescapeSpecialChars(text); - - // attacklab: Restore dollar signs - text = text.replace(/~D/g,"$$"); - - // attacklab: Restore tildes - text = text.replace(/~T/g,"~"); - - return text; -} - - -var _StripLinkDefinitions = function(text) { -// -// Strips link definitions from text, stores the URLs and titles in -// hash references. -// - - // Link defs are in the form: ^[id]: url "optional title" - - /* - var text = text.replace(/ - ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1 - [ \t]* - \n? // maybe *one* newline - [ \t]* - ? // url = $2 - [ \t]* - \n? // maybe one newline - [ \t]* - (?: - (\n*) // any lines skipped = $3 attacklab: lookbehind removed - ["(] - (.+?) // title = $4 - [")] - [ \t]* - )? // title is optional - (?:\n+|$) - /gm, - function(){...}); - */ - var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm, - function (wholeMatch,m1,m2,m3,m4) { - m1 = m1.toLowerCase(); - g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive - if (m3) { - // Oops, found blank lines, so it's not a title. - // Put back the parenthetical statement we stole. - return m3+m4; - } else if (m4) { - g_titles[m1] = m4.replace(/"/g,"""); - } - - // Completely remove the definition from the text - return ""; - } - ); - - return text; -} - - -var _HashHTMLBlocks = function(text) { - // attacklab: Double up blank lines to reduce lookaround - text = text.replace(/\n/g,"\n\n"); - - // Hashify HTML blocks: - // We only want to do this for block-level HTML tags, such as headers, - // lists, and tables. That's because we still want to wrap

s around - // "paragraphs" that are wrapped in non-block-level tags, such as anchors, - // phrase emphasis, and spans. The list of tags we're looking for is - // hard-coded: - var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del" - var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math" - - // First, look for nested blocks, e.g.: - //

- //
- // tags for inner block must be indented. - //
- //
- // - // The outermost tags must start at the left margin for this to match, and - // the inner nested divs must be indented. - // We need to do this before the next, more liberal match, because the next - // match will start at the first `
` and stop at the first `
`. - - // attacklab: This regex can be expensive when it fails. - /* - var text = text.replace(/ - ( // save in $1 - ^ // start of line (with /m) - <($block_tags_a) // start tag = $2 - \b // word break - // attacklab: hack around khtml/pcre bug... - [^\r]*?\n // any number of lines, minimally matching - // the matching end tag - [ \t]* // trailing spaces/tabs - (?=\n+) // followed by a newline - ) // attacklab: there are sentinel newlines at end of document - /gm,function(){...}}; - */ - text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement); - - // - // Now match more liberally, simply from `\n` to `\n` - // - - /* - var text = text.replace(/ - ( // save in $1 - ^ // start of line (with /m) - <($block_tags_b) // start tag = $2 - \b // word break - // attacklab: hack around khtml/pcre bug... - [^\r]*? // any number of lines, minimally matching - .* // the matching end tag - [ \t]* // trailing spaces/tabs - (?=\n+) // followed by a newline - ) // attacklab: there are sentinel newlines at end of document - /gm,function(){...}}; - */ - text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement); - - // Special case just for
. It was easier to make a special case than - // to make the other regex more complicated. - - /* - text = text.replace(/ - ( // save in $1 - \n\n // Starting after a blank line - [ ]{0,3} - (<(hr) // start tag = $2 - \b // word break - ([^<>])*? // - \/?>) // the matching end tag - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement); - - // Special case for standalone HTML comments: - - /* - text = text.replace(/ - ( // save in $1 - \n\n // Starting after a blank line - [ ]{0,3} // attacklab: g_tab_width - 1 - - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/(\n\n[ ]{0,3}[ \t]*(?=\n{2,}))/g,hashElement); - - // PHP and ASP-style processor instructions ( and <%...%>) - - /* - text = text.replace(/ - (?: - \n\n // Starting after a blank line - ) - ( // save in $1 - [ ]{0,3} // attacklab: g_tab_width - 1 - (?: - <([?%]) // $2 - [^\r]*? - \2> - ) - [ \t]* - (?=\n{2,}) // followed by a blank line - ) - /g,hashElement); - */ - text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement); - - // attacklab: Undo double lines (see comment at top of this function) - text = text.replace(/\n\n/g,"\n"); - return text; -} - -var hashElement = function(wholeMatch,m1) { - var blockText = m1; - - // Undo double lines - blockText = blockText.replace(/\n\n/g,"\n"); - blockText = blockText.replace(/^\n/,""); - - // strip trailing blank lines - blockText = blockText.replace(/\n+$/g,""); - - // Replace the element text with a marker ("~KxK" where x is its key) - blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n"; - - return blockText; -}; - -var _RunBlockGamut = function(text) { -// -// These are all the transformations that form block-level -// tags like paragraphs, headers, and list items. -// - text = _DoHeaders(text); - - // Do Horizontal Rules: - var key = hashBlock("
"); - text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key); - text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key); - text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key); - - text = _DoLists(text); - text = _DoCodeBlocks(text); - text = _DoBlockQuotes(text); - - // We already ran _HashHTMLBlocks() before, in Markdown(), but that - // was to escape raw HTML in the original Markdown source. This time, - // we're escaping the markup we've just created, so that we don't wrap - //

tags around block-level tags. - text = _HashHTMLBlocks(text); - text = _FormParagraphs(text); - - return text; -} - - -var _RunSpanGamut = function(text) { -// -// These are all the transformations that occur *within* block-level -// tags like paragraphs, headers, and list items. -// - - text = _DoCodeSpans(text); - text = _EscapeSpecialCharsWithinTagAttributes(text); - text = _EncodeBackslashEscapes(text); - - // Process anchor and image tags. Images must come first, - // because ![foo][f] looks like an anchor. - text = _DoImages(text); - text = _DoAnchors(text); - - // Make links out of things like `` - // Must come after _DoAnchors(), because you can use < and > - // delimiters in inline links like [this](). - text = _DoAutoLinks(text); - text = _EncodeAmpsAndAngles(text); - text = _DoItalicsAndBold(text); - - // Do hard breaks: - text = text.replace(/ +\n/g,"
\n"); - - return text; -} - -var _EscapeSpecialCharsWithinTagAttributes = function(text) { -// -// Within tags -- meaning between < and > -- encode [\ ` * _] so they -// don't conflict with their use in Markdown for code, italics and strong. -// - - // Build a regex to find HTML tags and comments. See Friedl's - // "Mastering Regular Expressions", 2nd Ed., pp. 200-201. - var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|)/gi; - - text = text.replace(regex, function(wholeMatch) { - var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`"); - tag = escapeCharacters(tag,"\\`*_"); - return tag; - }); - - return text; -} - -var _DoAnchors = function(text) { -// -// Turn Markdown link shortcuts into XHTML
tags. -// - // - // First, handle reference-style links: [link text] [id] - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[] // or anything else - )* - ) - \] - - [ ]? // one optional space - (?:\n[ ]*)? // one optional newline followed by spaces - - \[ - (.*?) // id = $3 - \] - )()()()() // pad remaining backreferences - /g,_DoAnchors_callback); - */ - text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag); - - // - // Next, inline-style links: [link text](url "optional title") - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ( - (?: - \[[^\]]*\] // allow brackets nested one level - | - [^\[\]] // or anything else - ) - ) - \] - \( // literal paren - [ \t]* - () // no id, so leave $3 empty - ? // href = $4 - [ \t]* - ( // $5 - (['"]) // quote char = $6 - (.*?) // Title = $7 - \6 // matching quote - [ \t]* // ignore any spaces/tabs between closing quote and ) - )? // title is optional - \) - ) - /g,writeAnchorTag); - */ - text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag); - - // - // Last, handle reference-style shortcuts: [link text] - // These must come last in case you've also got [link test][1] - // or [link test](/foo) - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - \[ - ([^\[\]]+) // link text = $2; can't contain '[' or ']' - \] - )()()()()() // pad rest of backreferences - /g, writeAnchorTag); - */ - text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag); - - return text; -} - -var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) { - if (m7 == undefined) m7 = ""; - var whole_match = m1; - var link_text = m2; - var link_id = m3.toLowerCase(); - var url = m4; - var title = m7; - - if (url == "") { - if (link_id == "") { - // lower-case and turn embedded newlines into spaces - link_id = link_text.toLowerCase().replace(/ ?\n/g," "); - } - url = "#"+link_id; - - if (g_urls[link_id] != undefined) { - url = g_urls[link_id]; - if (g_titles[link_id] != undefined) { - title = g_titles[link_id]; - } - } - else { - if (whole_match.search(/\(\s*\)$/m)>-1) { - // Special case for explicit empty url - url = ""; - } else { - return whole_match; - } - } - } - - url = escapeCharacters(url,"*_"); - var result = ""; - - return result; -} - - -var _DoImages = function(text) { -// -// Turn Markdown image shortcuts into tags. -// - - // - // First, handle reference-style labeled images: ![alt text][id] - // - - /* - text = text.replace(/ - ( // wrap whole match in $1 - !\[ - (.*?) // alt text = $2 - \] - - [ ]? // one optional space - (?:\n[ ]*)? // one optional newline followed by spaces - - \[ - (.*?) // id = $3 - \] - )()()()() // pad rest of backreferences - /g,writeImageTag); - */ - text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag); - - // - // Next, handle inline images: ![alt text](url "optional title") - // Don't forget: encode * and _ - - /* - text = text.replace(/ - ( // wrap whole match in $1 - !\[ - (.*?) // alt text = $2 - \] - \s? // One optional whitespace character - \( // literal paren - [ \t]* - () // no id, so leave $3 empty - ? // src url = $4 - [ \t]* - ( // $5 - (['"]) // quote char = $6 - (.*?) // title = $7 - \6 // matching quote - [ \t]* - )? // title is optional - \) - ) - /g,writeImageTag); - */ - text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag); - - return text; -} - -var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) { - var whole_match = m1; - var alt_text = m2; - var link_id = m3.toLowerCase(); - var url = m4; - var title = m7; - - if (!title) title = ""; - - if (url == "") { - if (link_id == "") { - // lower-case and turn embedded newlines into spaces - link_id = alt_text.toLowerCase().replace(/ ?\n/g," "); - } - url = "#"+link_id; - - if (g_urls[link_id] != undefined) { - url = g_urls[link_id]; - if (g_titles[link_id] != undefined) { - title = g_titles[link_id]; - } - } - else { - return whole_match; - } - } - - alt_text = alt_text.replace(/"/g,"""); - url = escapeCharacters(url,"*_"); - var result = "\""' + _RunSpanGamut(m1) + "");}); - - text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm, - function(matchFound,m1){return hashBlock('

' + _RunSpanGamut(m1) + "

");}); - - // atx-style headers: - // # Header 1 - // ## Header 2 - // ## Header 2 with closing hashes ## - // ... - // ###### Header 6 - // - - /* - text = text.replace(/ - ^(\#{1,6}) // $1 = string of #'s - [ \t]* - (.+?) // $2 = Header text - [ \t]* - \#* // optional closing #'s (not counted) - \n+ - /gm, function() {...}); - */ - - text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm, - function(wholeMatch,m1,m2) { - var h_level = m1.length; - return hashBlock("' + _RunSpanGamut(m2) + ""); - }); - - function headerId(m) { - return m.replace(/[^\w]/g, '').toLowerCase(); - } - return text; -} - -// This declaration keeps Dojo compressor from outputting garbage: -var _ProcessListItems; - -var _DoLists = function(text) { -// -// Form HTML ordered (numbered) and unordered (bulleted) lists. -// - - // attacklab: add sentinel to hack around khtml/safari bug: - // http://bugs.webkit.org/show_bug.cgi?id=11231 - text += "~0"; - - // Re-usable pattern to match any entirel ul or ol list: - - /* - var whole_list = / - ( // $1 = whole list - ( // $2 - [ ]{0,3} // attacklab: g_tab_width - 1 - ([*+-]|\d+[.]) // $3 = first list item marker - [ \t]+ - ) - [^\r]+? - ( // $4 - ~0 // sentinel for workaround; should be $ - | - \n{2,} - (?=\S) - (?! // Negative lookahead for another list item marker - [ \t]* - (?:[*+-]|\d+[.])[ \t]+ - ) - ) - )/g - */ - var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm; - - if (g_list_level) { - text = text.replace(whole_list,function(wholeMatch,m1,m2) { - var list = m1; - var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol"; - - // Turn double returns into triple returns, so that we can make a - // paragraph for the last item in a list, if necessary: - list = list.replace(/\n{2,}/g,"\n\n\n");; - var result = _ProcessListItems(list); - - // Trim any trailing whitespace, to put the closing `` - // up on the preceding line, to get it past the current stupid - // HTML block parser. This is a hack to work around the terrible - // hack that is the HTML block parser. - result = result.replace(/\s+$/,""); - result = "<"+list_type+">" + result + "\n"; - return result; - }); - } else { - whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g; - text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) { - var runup = m1; - var list = m2; - - var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol"; - // Turn double returns into triple returns, so that we can make a - // paragraph for the last item in a list, if necessary: - var list = list.replace(/\n{2,}/g,"\n\n\n");; - var result = _ProcessListItems(list); - result = runup + "<"+list_type+">\n" + result + "\n"; - return result; - }); - } - - // attacklab: strip sentinel - text = text.replace(/~0/,""); - - return text; -} - -_ProcessListItems = function(list_str) { -// -// Process the contents of a single ordered or unordered list, splitting it -// into individual list items. -// - // The $g_list_level global keeps track of when we're inside a list. - // Each time we enter a list, we increment it; when we leave a list, - // we decrement. If it's zero, we're not in a list anymore. - // - // We do this because when we're not inside a list, we want to treat - // something like this: - // - // I recommend upgrading to version - // 8. Oops, now this line is treated - // as a sub-list. - // - // As a single paragraph, despite the fact that the second line starts - // with a digit-period-space sequence. - // - // Whereas when we're inside a list (or sub-list), that line will be - // treated as the start of a sub-list. What a kludge, huh? This is - // an aspect of Markdown's syntax that's hard to parse perfectly - // without resorting to mind-reading. Perhaps the solution is to - // change the syntax rules such that sub-lists must start with a - // starting cardinal number; e.g. "1." or "a.". - - g_list_level++; - - // trim trailing blank lines: - list_str = list_str.replace(/\n{2,}$/,"\n"); - - // attacklab: add sentinel to emulate \z - list_str += "~0"; - - /* - list_str = list_str.replace(/ - (\n)? // leading line = $1 - (^[ \t]*) // leading whitespace = $2 - ([*+-]|\d+[.]) [ \t]+ // list marker = $3 - ([^\r]+? // list item text = $4 - (\n{1,2})) - (?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+)) - /gm, function(){...}); - */ - list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm, - function(wholeMatch,m1,m2,m3,m4){ - var item = m4; - var leading_line = m1; - var leading_space = m2; - - if (leading_line || (item.search(/\n{2,}/)>-1)) { - item = _RunBlockGamut(_Outdent(item)); - } - else { - // Recursion for sub-lists: - item = _DoLists(_Outdent(item)); - item = item.replace(/\n$/,""); // chomp(item) - item = _RunSpanGamut(item); - } - - return "
  • " + item + "
  • \n"; - } - ); - - // attacklab: strip sentinel - list_str = list_str.replace(/~0/g,""); - - g_list_level--; - return list_str; -} - - -var _DoCodeBlocks = function(text) { -// -// Process Markdown `
    ` blocks.
    -//  
    -
    -	/*
    -		text = text.replace(text,
    -			/(?:\n\n|^)
    -			(								// $1 = the code block -- one or more lines, starting with a space/tab
    -				(?:
    -					(?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
    -					.*\n+
    -				)+
    -			)
    -			(\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
    -		/g,function(){...});
    -	*/
    -
    -	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
    -	text += "~0";
    -	
    -	text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
    -		function(wholeMatch,m1,m2) {
    -			var codeblock = m1;
    -			var nextChar = m2;
    -		
    -			codeblock = _EncodeCode( _Outdent(codeblock));
    -			codeblock = _Detab(codeblock);
    -			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
    -			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
    -
    -			codeblock = "
    " + codeblock + "\n
    "; - - return hashBlock(codeblock) + nextChar; - } - ); - - // attacklab: strip sentinel - text = text.replace(/~0/,""); - - return text; -} - -var hashBlock = function(text) { - text = text.replace(/(^\n+|\n+$)/g,""); - return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n"; -} - - -var _DoCodeSpans = function(text) { -// -// * Backtick quotes are used for spans. -// -// * You can use multiple backticks as the delimiters if you want to -// include literal backticks in the code span. So, this input: -// -// Just type ``foo `bar` baz`` at the prompt. -// -// Will translate to: -// -//

    Just type foo `bar` baz at the prompt.

    -// -// There's no arbitrary limit to the number of backticks you -// can use as delimters. If you need three consecutive backticks -// in your code, use four for delimiters, etc. -// -// * You can use spaces to get literal backticks at the edges: -// -// ... type `` `bar` `` ... -// -// Turns to: -// -// ... type `bar` ... -// - - /* - text = text.replace(/ - (^|[^\\]) // Character before opening ` can't be a backslash - (`+) // $2 = Opening run of ` - ( // $3 = The code block - [^\r]*? - [^`] // attacklab: work around lack of lookbehind - ) - \2 // Matching closer - (?!`) - /gm, function(){...}); - */ - - text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, - function(wholeMatch,m1,m2,m3,m4) { - var c = m3; - c = c.replace(/^([ \t]*)/g,""); // leading whitespace - c = c.replace(/[ \t]*$/g,""); // trailing whitespace - c = _EncodeCode(c); - return m1+""+c+""; - }); - - return text; -} - - -var _EncodeCode = function(text) { -// -// Encode/escape certain characters inside Markdown code runs. -// The point is that in code, these characters are literals, -// and lose their special Markdown meanings. -// - // Encode all ampersands; HTML entities are not - // entities within a Markdown code span. - text = text.replace(/&/g,"&"); - - // Do the angle bracket song and dance: - text = text.replace(//g,">"); - - // Now, escape characters that are magic in Markdown: - text = escapeCharacters(text,"\*_{}[]\\",false); - -// jj the line above breaks this: -//--- - -//* Item - -// 1. Subitem - -// special char: * -//--- - - return text; -} - - -var _DoItalicsAndBold = function(text) { - - // must go first: - text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g, - "$2"); - - text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g, - "$2"); - - return text; -} - - -var _DoBlockQuotes = function(text) { - - /* - text = text.replace(/ - ( // Wrap whole match in $1 - ( - ^[ \t]*>[ \t]? // '>' at the start of a line - .+\n // rest of the first line - (.+\n)* // subsequent consecutive lines - \n* // blanks - )+ - ) - /gm, function(){...}); - */ - - text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm, - function(wholeMatch,m1) { - var bq = m1; - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - - bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0"); // trim one level of quoting - - // attacklab: clean up hack - bq = bq.replace(/~0/g,""); - - bq = bq.replace(/^[ \t]+$/gm,""); // trim whitespace-only lines - bq = _RunBlockGamut(bq); // recurse - - bq = bq.replace(/(^|\n)/g,"$1 "); - // These leading spaces screw with
     content, so we need to fix that:
    -			bq = bq.replace(
    -					/(\s*
    [^\r]+?<\/pre>)/gm,
    -				function(wholeMatch,m1) {
    -					var pre = m1;
    -					// attacklab: hack around Konqueror 3.5.4 bug:
    -					pre = pre.replace(/^  /mg,"~0");
    -					pre = pre.replace(/~0/g,"");
    -					return pre;
    -				});
    -			
    -			return hashBlock("
    \n" + bq + "\n
    "); - }); - return text; -} - - -var _FormParagraphs = function(text) { -// -// Params: -// $text - string to process with html

    tags -// - - // Strip leading and trailing lines: - text = text.replace(/^\n+/g,""); - text = text.replace(/\n+$/g,""); - - var grafs = text.split(/\n{2,}/g); - var grafsOut = new Array(); - - // - // Wrap

    tags. - // - var end = grafs.length; - for (var i=0; i= 0) { - grafsOut.push(str); - } - else if (str.search(/\S/) >= 0) { - str = _RunSpanGamut(str); - str = str.replace(/^([ \t]*)/g,"

    "); - str += "

    " - grafsOut.push(str); - } - - } - - // - // Unhashify HTML blocks - // - end = grafsOut.length; - for (var i=0; i= 0) { - var blockText = g_html_blocks[RegExp.$1]; - blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs - grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText); - } - } - - return grafsOut.join("\n\n"); -} - - -var _EncodeAmpsAndAngles = function(text) { -// Smart processing for ampersands and angle brackets that need to be encoded. - - // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: - // http://bumppo.net/projects/amputator/ - text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&"); - - // Encode naked <'s - text = text.replace(/<(?![a-z\/?\$!])/gi,"<"); - - return text; -} - - -var _EncodeBackslashEscapes = function(text) { -// -// Parameter: String. -// Returns: The string, with after processing the following backslash -// escape sequences. -// - - // attacklab: The polite way to do this is with the new - // escapeCharacters() function: - // - // text = escapeCharacters(text,"\\",true); - // text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); - // - // ...but we're sidestepping its use of the (slow) RegExp constructor - // as an optimization for Firefox. This function gets called a LOT. - - text = text.replace(/\\(\\)/g,escapeCharacters_callback); - text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback); - return text; -} - - -var _DoAutoLinks = function(text) { - - text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"
    $1"); - - // Email addresses: - - /* - text = text.replace(/ - < - (?:mailto:)? - ( - [-.\w]+ - \@ - [-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+ - ) - > - /gi, _DoAutoLinks_callback()); - */ - text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, - function(wholeMatch,m1) { - return _EncodeEmailAddress( _UnescapeSpecialChars(m1) ); - } - ); - - return text; -} - - -var _EncodeEmailAddress = function(addr) { -// -// Input: an email address, e.g. "foo@example.com" -// -// Output: the email address as a mailto link, with each character -// of the address encoded as either a decimal or hex entity, in -// the hopes of foiling most address harvesting spam bots. E.g.: -// -// foo -// @example.com -// -// Based on a filter by Matthew Wickline, posted to the BBEdit-Talk -// mailing list: -// - - // attacklab: why can't javascript speak hex? - function char2hex(ch) { - var hexDigits = '0123456789ABCDEF'; - var dec = ch.charCodeAt(0); - return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15)); - } - - var encode = [ - function(ch){return "&#"+ch.charCodeAt(0)+";";}, - function(ch){return "&#x"+char2hex(ch)+";";}, - function(ch){return ch;} - ]; - - addr = "mailto:" + addr; - - addr = addr.replace(/./g, function(ch) { - if (ch == "@") { - // this *must* be encoded. I insist. - ch = encode[Math.floor(Math.random()*2)](ch); - } else if (ch !=":") { - // leave ':' alone (to spot mailto: later) - var r = Math.random(); - // roughly 10% raw, 45% hex, 45% dec - ch = ( - r > .9 ? encode[2](ch) : - r > .45 ? encode[1](ch) : - encode[0](ch) - ); - } - return ch; - }); - - addr = "" + addr + ""; - addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part - - return addr; -} - - -var _UnescapeSpecialChars = function(text) { -// -// Swap back in all the special characters we've hidden. -// - text = text.replace(/~E(\d+)E/g, - function(wholeMatch,m1) { - var charCodeToReplace = parseInt(m1); - return String.fromCharCode(charCodeToReplace); - } - ); - return text; -} - - -var _Outdent = function(text) { -// -// Remove one level of line-leading tabs or spaces -// - - // attacklab: hack around Konqueror 3.5.4 bug: - // "----------bug".replace(/^-/g,"") == "bug" - - text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width - - // attacklab: clean up hack - text = text.replace(/~0/g,"") - - return text; -} - -var _Detab = function(text) { -// attacklab: Detab's completely rewritten for speed. -// In perl we could fix it by anchoring the regexp with \G. -// In javascript we're less fortunate. - - // expand first n-1 tabs - text = text.replace(/\t(?=\t)/g," "); // attacklab: g_tab_width - - // replace the nth with two sentinels - text = text.replace(/\t/g,"~A~B"); - - // use the sentinel to anchor our regex so it doesn't explode - text = text.replace(/~B(.+?)~A/g, - function(wholeMatch,m1,m2) { - var leadingText = m1; - var numSpaces = 4 - leadingText.length % 4; // attacklab: g_tab_width - - // there *must* be a better way to do this: - for (var i=0; i "+getNodeText(this.span); - } - - var correctionsByNode = null; - var correctionList = null; - - // private - function docNodeInserted(event) - { - try { - recurse(event.target); - } - catch (e) { - Editor_error(e); - } - - function recurse(node) - { - if (isAutoCorrectNode(node)) - AutoCorrect_addCorrection(node); - for (var child = node.firstChild; child != null; child = child.nextSibling) - recurse(child); - } - } - - // private - function docNodeRemoved(event) - { - try { - recurse(event.target); - } - catch (e) { - Editor_error(e); - } - - function recurse(node) - { - if (isAutoCorrectNode(node)) - AutoCorrect_removeCorrection(node); - for (var child = node.firstChild; child != null; child = child.nextSibling) - recurse(child); - } - } - - AutoCorrect_init = function() - { - correctionsByNode = new NodeMap(); - correctionList = new Array(); - document.addEventListener("DOMNodeInserted",docNodeInserted); - document.addEventListener("DOMNodeRemoved",docNodeRemoved); - } - - // public (for the undo tests, when they report results) - AutoCorrect_removeListeners = function() - { - document.removeEventListener("DOMNodeInserted",docNodeInserted); - document.removeEventListener("DOMNodeRemoved",docNodeRemoved); - } - - AutoCorrect_addCorrection = function(span) - { - var correction = new Correction(span); - correctionsByNode.put(span,correction); - correctionList.push(correction); - Editor_updateAutoCorrect(); - - span.addEventListener("DOMSubtreeModified",correction.modificationListener); - } - - AutoCorrect_removeCorrection = function(span) - { - var correction = correctionsByNode.get(span); - if (correction == null) - throw new Error("No autocorrect entry for "+JSON.stringify(getNodeText(span))); - - var index = null; - for (var i = 0; i < correctionList.length; i++) { - if (correctionList[i].span == span) { - index = i; - break; - } - } - if (index == null) - throw new Error("Correction "+correction+" not found in correctionList"); - correctionList.splice(index,1); - Editor_updateAutoCorrect(); - - span.removeEventListener("DOMSubtreeModified",correction.modificationListener); - correctionsByNode.remove(span); - } - - AutoCorrect_getCorrections = function() - { - var result = new Array(); - for (var i = 0; i < correctionList.length; i++) { - var correction = correctionList[i]; - result.push({ original: correction.span.getAttribute("original"), - replacement: getNodeText(correction.span)}); - } - return result; - } - - AutoCorrect_correctPrecedingWord = function(numChars,replacement,confirmed) - { - Selection_preserveWhileExecuting(function() { - var selRange = Selection_get(); - if ((selRange == null) && !Range_isEmpty(selRange)) - return; - - var node = selRange.start.node; - var offset = selRange.start.offset; - if (node.nodeType != Node.TEXT_NODE) - return; - - var original = node.nodeValue.substring(offset-numChars,offset); - - if (confirmed) { - DOM_replaceCharacters(node,offset-numChars,offset,replacement); - return; - } - - UndoManager_newGroup("Auto-correct"); - var before = node.nodeValue.substring(0,offset-numChars); - var beforeText = DOM_createTextNode(document,before); - var replacementText = DOM_createTextNode(document,replacement); - var span = DOM_createElement(document,"SPAN"); - DOM_setAttribute(span,"class",Keys.AUTOCORRECT_CLASS); - DOM_setAttribute(span,"original",original); - DOM_appendChild(span,replacementText); - DOM_insertBefore(node.parentNode,beforeText,node); - DOM_insertBefore(node.parentNode,span,node); - DOM_deleteCharacters(node,0,offset); - // Add the new group in a postponed action, so that the change to the style element - // is not counted as a separate action - PostponedActions_add(UndoManager_newGroup); - }); - } - - AutoCorrect_getCorrection = function() - { - var correction = getCurrent(); - if (correction == null) - return null; - - return { original: correction.span.getAttribute("original"), - replacement: getNodeText(correction.span) }; - } - - AutoCorrect_getCorrectionCoords = function() - { - var correction = getCurrent(); - if (correction == null) - return null; - - var textNode = correction.span.firstChild; - if ((textNode == null) || (textNode.nodeType != Node.TEXT_NODE)) - return null; - - var offset = Math.floor(textNode.nodeValue.length/2); - Selection_set(textNode,offset,textNode,offset); - Cursor_ensureCursorVisible(); - var rect = Position_displayRectAtPos(new Position(textNode,offset)); - - if (rect == null) // FIXME: pos - throw new Error("no rect for pos "+(new Position(textNode,offset))); - - if (rect == null) - return null; - - return { x: rect.left, y: rect.top }; - } - - function getCurrent() - { - var range = Selection_get(); - if (range != null) { - var endNode = Position_closestActualNode(range.end); - for (; endNode != null; endNode = endNode.parentNode) { - if (isAutoCorrectNode(endNode)) - return correctionsByNode.get(endNode); - } - } - - if (correctionList.length > 0) - return correctionList[correctionList.length-1]; - - return null; - } - - AutoCorrect_acceptCorrection = function() - { - UndoManager_newGroup("Accept"); - var correction = getCurrent(); - if (correction == null) - return; - - removeCorrectionSpan(correction.span); - UndoManager_newGroup(); - } - - AutoCorrect_revertCorrection = function() - { - var correction = getCurrent(); - if (correction == null) - return; - - AutoCorrect_replaceCorrection(correction.span.getAttribute("original")); - } - - AutoCorrect_replaceCorrection = function(replacement) - { - UndoManager_newGroup("Replace"); - var correction = getCurrent(); - if (correction == null) - return; - - Selection_preserveWhileExecuting(function() { - var text = DOM_createTextNode(document,replacement); - DOM_insertBefore(correction.span.parentNode,text,correction.span); - DOM_deleteNode(correction.span); - Formatting_mergeWithNeighbours(text,{}); - }); - UndoManager_newGroup(); - } - -})(); http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/26f461e7/experiments/Editor/src/ChangeTracking.js ---------------------------------------------------------------------- diff --git a/experiments/Editor/src/ChangeTracking.js b/experiments/Editor/src/ChangeTracking.js deleted file mode 100644 index ba25a44..0000000 --- a/experiments/Editor/src/ChangeTracking.js +++ /dev/null @@ -1,127 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. - -var ChangeTracking_showChanges; -var ChangeTracking_trackChanges; -var ChangeTracking_setShowChanges; -var ChangeTracking_setTrackChanges; -var ChangeTracking_acceptSelectedChanges; - -(function() { - - var showChangesEnabled = false; - var trackChangesEnabled = false; - - ChangeTracking_showChanges = function() - { - return showChangesEnabled; - } - - ChangeTracking_trackChanges = function() - { - return trackChangesEnabled; - } - - ChangeTracking_setShowChanges = function(enabled) - { - showChangesEnabled = enabled; - } - - ChangeTracking_setTrackChanges = function(enabled) - { - trackChangesEnabled = enabled; - } - - ChangeTracking_acceptSelectedChanges = function() - { - var selRange = Selection_get(); - if (selRange == null) - return; - - var outermost = Range_getOutermostNodes(selRange,true); - var checkEmpty = new Array(); - - Selection_preserveWhileExecuting(function() { - for (var i = 0; i < outermost.length; i++) { - recurse(outermost[i]); - - var next; - for (ancestor = outermost[i].parentNode; ancestor != null; ancestor = next) { - next = ancestor.parentNode; - if (ancestor._type == HTML_DEL) { - checkEmpty.push(ancestor.parentNode); - DOM_deleteNode(ancestor); - } - else if (ancestor._type == HTML_INS) - DOM_removeNodeButKeepChildren(ancestor); - } - } - - for (var i = 0; i < checkEmpty.length; i++) { - var node = checkEmpty[i]; - if (node == null) - continue; - var empty = true; - for (var child = node.firstChild; child != null; child = child.nextSibling) { - if (!isWhitespaceTextNode(child)) { - empty = false; - break; - } - } - if (empty) { - switch (node._type) { - case HTML_LI: - case HTML_UL: - case HTML_OL: - checkEmpty.push(node.parentNode); - DOM_deleteNode(node); - break; - } - } - } - }); - - var selRange = Selection_get(); - if (selRange != null) { - var start = Position_closestMatchForwards(selRange.start,Position_okForInsertion); - var end = Position_closestMatchBackwards(selRange.end,Position_okForInsertion); - if (!Range_isForwards(new Range(start.node,start.offset,end.node,end.offset))) - end = Position_closestMatchForwards(selRange.end,Position_okForInsertion); - Selection_set(start.node,start.offset,end.node,end.offset); - } - - function recurse(node) - { - if (node._type == HTML_DEL) { - checkEmpty.push(node.parentNode); - DOM_deleteNode(node); - return; - } - - var next; - for (var child = node.firstChild; child != null; child = next) { - next = child.nextSibling; - recurse(child); - } - - if (node._type == HTML_INS) { - DOM_removeNodeButKeepChildren(node); - } - } - } - -})(); http://git-wip-us.apache.org/repos/asf/incubator-corinthia/blob/26f461e7/experiments/Editor/src/Clipboard.js ---------------------------------------------------------------------- diff --git a/experiments/Editor/src/Clipboard.js b/experiments/Editor/src/Clipboard.js deleted file mode 100644 index 03efdcc..0000000 --- a/experiments/Editor/src/Clipboard.js +++ /dev/null @@ -1,757 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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. - -var Markdown_htmlToMarkdown; -var Clipboard_htmlToText; -var Clipboard_cut; -var Clipboard_copy; -var Clipboard_pasteText; -var Clipboard_pasteHTML; -var Clipboard_pasteNodes; - -(function() { - - // private - function blockToText(md,node,indent,nextIndent,listType,listNo) - { - var linesBetweenChildren = 1; - var childIndent = indent; - switch (node._type) { - case HTML_LI: - if (listType == "OL") { - var listMarker; - if (listNo.value < 10) - listMarker = listNo.value+". "; - else - listMarker = listNo.value+". "; - beginParagraph(md,0,indent,nextIndent,listMarker); - nextIndent += " "; - } - else { - beginParagraph(md,0,indent,nextIndent," - "); - nextIndent += " "; - } - listNo.value++; - break; - case HTML_UL: - listType = "UL"; - listNo = { value: 1 }; - beginParagraph(md,1,indent,nextIndent); - linesBetweenChildren = 0; - break; - case HTML_OL: - listType = "OL"; - listNo = { value: 1 }; - beginParagraph(md,1,indent,nextIndent); - linesBetweenChildren = 0; - break; - case HTML_H1: - beginParagraph(md,1,indent,nextIndent,"# "," #"); - break; - case HTML_H2: - beginParagraph(md,1,indent,nextIndent,"## "," ##"); - break; - case HTML_H3: - beginParagraph(md,1,indent,nextIndent,"### "," ###"); - break; - case HTML_H4: - beginParagraph(md,1,indent,nextIndent,"#### "," ####"); - break; - case HTML_H5: - beginParagraph(md,1,indent,nextIndent,"##### "," #####"); - break; - case HTML_H6: - beginParagraph(md,1,indent,nextIndent,"###### "," ######"); - break; - case HTML_BLOCKQUOTE: - beginParagraph(md,1,indent,nextIndent,"> "); - nextIndent += "> "; - break; - case HTML_PRE: - md.preDepth++; - break; - } - - var foundNonWhitespaceChild = false; - for (var child = node.firstChild; child != null; child = child.nextSibling) { - if (isContainerNode(child) || isParagraphNode(child)) { - beginParagraph(md,linesBetweenChildren,indent,nextIndent); - blockToText(md,child,indent,nextIndent,listType,listNo); - beginParagraph(md,linesBetweenChildren); - indent = nextIndent; - foundNonWhitespaceChild = false; - } - else { - if (!foundNonWhitespaceChild) { - if (isWhitespaceTextNode(child)) - continue; - beginParagraph(md,0,indent,nextIndent); - indent = nextIndent; - foundNonWhitespaceChild = true; - } - - inlineToText(md,child); - } - } - - if (node._type == HTML_PRE) - md.preDepth--; - } - - // private - function shipOutParagraph(md) - { - var text = md.buildParagraph.join(""); - if (md.buildPre) { - text = text.replace(/\n$/,""); - text = " "+text.replace(/\n/g,"\n"+md.nextIndent+" "); - } - else { - text = normalizeWhitespace(text); - } - if (md.allText.length > 0) { - for (var i = 0; i < md.buildLines; i++) - md.allText.push("\n"); - } - md.allText.push(md.indent+md.buildPrefix+text+md.buildSuffix+"\n"); - resetBuild(md); - } - - // private - function beginParagraph(md,blankLines,indent,nextIndent,paraPrefix,paraSuffix) - { - if (blankLines == null) - blankLines = 1; - if (indent == null) - indent = ""; - if (nextIndent == null) - nextIndent = ""; - if (paraPrefix == null) - paraPrefix = ""; - if (paraSuffix == null) - paraSuffix = ""; - - if (md == null) - throw new Error("beginParagraph: md is null"); - if (md.buildParagraph == null) - throw new Error("beginParagraph: md.buildParagraph is null"); - - if (md.buildParagraph.length > 0) { - shipOutParagraph(md); - } - - if (md.buildLines < blankLines) - md.buildLines = blankLines; - if (md.indent.length < indent.length) - md.indent = indent; - if (md.nextIndent.length < nextIndent.length) - md.nextIndent = nextIndent; - md.buildPrefix += paraPrefix; - md.buildSuffix = paraSuffix + md.buildSuffix; - if (md.preDepth > 0) - md.buildPre = true; - } - - // private - function inlineToText(md,node) - { - switch (node._type) { - case HTML_TEXT: { - var text = node.nodeValue; - if (md.preDepth == 0) { - text = text.replace(/\\/g,"\\\\"); - text = text.replace(/\*/g,"\\*"); - text = text.replace(/\[/g,"\\["); - text = text.replace(/\]/g,"\\]"); - } - md.buildParagraph.push(text); - break; - } - case HTML_I: - case HTML_EM: - md.buildParagraph.push("*"); - processChildren(); - md.buildParagraph.push("*"); - break; - case HTML_B: - case HTML_STRONG: - md.buildParagraph.push("**"); - processChildren(); - md.buildParagraph.push("**"); - break; - case HTML_A: - if (node.hasAttribute("href")) { - md.buildParagraph.push("["); - processChildren(); - md.buildParagraph.push("]("+node.getAttribute("href")+")"); - } - break; - default: - processChildren(); - break; - } - - function processChildren() - { - for (var child = node.firstChild; child != null; child = child.nextSibling) { - inlineToText(md,child); - } - } - } - - // private - function resetBuild(md) - { - md.buildParagraph = new Array(); - md.buildLines = 0; - md.buildPrefix = ""; - md.buildSuffix = ""; - md.buildPre = false; - md.indent = ""; - md.nextIndent = ""; - } - - // private - function MarkdownBuilder() - { - } - - // public - Markdown_htmlToMarkdown = function(node) - { - var md = new MarkdownBuilder(); - md.allText = new Array(); - md.preDepth = 0; - resetBuild(md); - - if (isContainerNode(node) || isParagraphNode(node)) { - blockToText(md,node,"","","UL",{value: 1}); - beginParagraph(md); - return md.allText.join(""); - } - else { - inlineToText(md,node); - return normalizeWhitespace(md.buildParagraph.join("")); - } - } - -})(); - -(function() { - - function expandRangeForCopy(range) - { - if (range == null) - return range; - - var startInLI = null; - for (var node = range.start.node; node != null; node = node.parentNode) { - if (node._type == HTML_LI) - startInLI = node; - } - - var endInLI = null; - for (var node = range.end.node; node != null; node = node.parentNode) { - if (node._type == HTML_LI) - endInLI = node; - } - - if ((startInLI != null) && (startInLI == endInLI)) { - var beforeRange = new Range(startInLI,0, - range.start.node,range.start.offset); - var afterRange = new Range(range.end.node,range.end.offset, - endInLI,DOM_maxChildOffset(endInLI)); - var contentBefore = Range_hasContent(beforeRange); - var contentAfter = Range_hasContent(afterRange); - - if (!contentBefore && !contentAfter) { - var li = startInLI; - var offset = DOM_nodeOffset(li); - range = new Range(li.parentNode,offset,li.parentNode,offset+1); - } - } - return range; - } - - function copyRange(range) - { - var html = ""; - var text = ""; - - if (range != null) { - var nodes; - var region = Tables_regionFromRange(range); - if (region != null) { - nodes = [Tables_cloneRegion(region)]; - } - else { - nodes = Range_cloneContents(range); - }; - - var div = DOM_createElement(document,"DIV"); - for (var i = 0; i < nodes.length; i++) - DOM_appendChild(div,nodes[i]); - Main_removeSpecial(div); - - html = div.innerHTML; - text = Clipboard_htmlToText(div); - } - - return { "text/html": html, - "text/plain": text }; - } - - // public (FIXME: temp: for testing) - Clipboard_htmlToText = function(node) - { - return Markdown_htmlToMarkdown(node); - } - - // public - Clipboard_cut = function() - { - UndoManager_newGroup("Cut"); - var content; - - var range = Selection_get(); - range = expandRangeForCopy(range); - content = copyRange(range); - - Selection_set(range.start.node,range.start.offset,range.end.node,range.end.offset); - Selection_deleteContents(false); - var selRange = Selection_get(); - if (selRange != null) { - Range_trackWhileExecuting(selRange,function() { - var node = Position_closestActualNode(selRange.start); - while (node != null) { - var parent = node.parentNode; - switch (node._type) { - case HTML_LI: - if (!nodeHasContent(node)) - DOM_deleteNode(node); - break; - case HTML_UL: - case HTML_OL: { - var haveLI = false; - for (var c = node.firstChild; c != null; c = c.nextSibling) { - if (c._type == HTML_LI) { - haveLI = true; - break; - } - } - if (!haveLI) - DOM_deleteNode(node); - break; - } - } - node = parent; - } - }); - - var pos = Position_closestMatchForwards(selRange.start,Position_okForMovement); - Selection_set(pos.node,pos.offset,pos.node,pos.offset); - } - - Cursor_ensureCursorVisible(); - - PostponedActions_perform(UndoManager_newGroup); - return content; - } - - // public - Clipboard_copy = function() - { - var range = Selection_get(); - range = expandRangeForCopy(range); - return copyRange(range); - } - - // public - Clipboard_pasteText = function(text) - { - var converter = new Showdown.converter(); - var html = converter.makeHtml(text); - UndoManager_newGroup("Paste"); - Clipboard_pasteHTML(html); - UndoManager_newGroup(); - } - - // public - Clipboard_pasteHTML = function(html) - { - if (html.match(/^\s*"; - else if (html.match(/^\s*"; - else if (html.match(/^\s*"; - else if (html.match(/^\s*"; - else if (html.match(/^\s*"; - else if (html.match(/^\s*"; - else if (html.match(/^\s*
  • "; - - var div = DOM_createElement(document,"DIV"); - div.innerHTML = html; - for (var child = div.firstChild; child != null; child = child.nextSibling) - DOM_assignNodeIds(child); - - var nodes = new Array(); - for (var child = div.firstChild; child != null; child = child.nextSibling) - nodes.push(child); - - UndoManager_newGroup("Paste"); - var region = Tables_regionFromRange(Selection_get(),true); - if ((region != null) && (nodes.length == 1) && (nodes[0]._type == HTML_TABLE)) - pasteTable(nodes[0],region); - else - Clipboard_pasteNodes(nodes); - UndoManager_newGroup(); - } - - function pasteTable(srcTable,dest) - { - var src = Tables_analyseStructure(srcTable); - - // In the destination table, the region into which we will paste the cells will the - // the same size as that of the source table, regardless of how many rows and columns - // were selected - i.e. we only pay attention to the top-left most cell, ignoring - // whatever the bottom-right is set to - dest.bottom = dest.top + src.numRows - 1; - dest.right = dest.left + src.numCols - 1; - - // Make sure the destination table is big enough to hold all the cells we want to paste. - // This will add rows and columns as appropriate, with empty cells that only contain a - //


    (to ensure they have non-zero height) - if (dest.structure.numRows < dest.bottom + 1) - dest.structure.numRows = dest.bottom + 1; - if (dest.structure.numCols < dest.right + 1) - dest.structure.numCols = dest.right + 1; - dest.structure = Table_fix(dest.structure); - - // To simplify the paste, split any merged cells that are in the region of the destination - // table we're pasting into. We have to re-analyse the table structure after this to - // get the correct cell array. - TableRegion_splitCells(dest); - dest.structure = Tables_analyseStructure(dest.structure.element); - - // Do the actual paste - Selection_preserveWhileExecuting(function() { - replaceCells(src,dest.structure,dest.top,dest.left); - }); - - // If any new columns were added, calculate a width for them - Table_fixColumnWidths(dest.structure); - - // Remove duplicate ids - var found = new Object(); - removeDuplicateIds(dest.structure.element,found); - - // Place the cursor in the bottom-right cell that was pasted - var bottomRightCell = Table_get(dest.structure,dest.bottom,dest.right); - var node = bottomRightCell.element; - Selection_set(node,node.childNodes.length,node,node.childNodes.length); - } - - function replaceCells(src,dest,destRow,destCol) - { - // By this point, all of the cells have been split. So it is guaranteed that every cell - // in dest will have rowspan = 1 and colspan = 1. - for (var srcRow = 0; srcRow < src.numRows; srcRow++) { - for (var srcCol = 0; srcCol < src.numCols; srcCol++) { - var srcCell = Table_get(src,srcRow,srcCol); - var destCell = Table_get(dest,srcRow+destRow,srcCol+destCol); - - if ((srcRow != srcCell.row) || (srcCol != srcCell.col)) - continue; - - if (destCell.rowspan != 1) - throw new Error("unexpected rowspan: "+destCell.rowspan); - if (destCell.colspan != 1) - throw new Error("unexpected colspan: "+destCell.colspan); - - DOM_insertBefore(destCell.element.parentNode,srcCell.element,destCell.element); - - var destTop = destRow + srcRow; - var destLeft = destCol + srcCol; - var destBottom = destTop + srcCell.rowspan - 1; - var destRight = destLeft + srcCell.colspan - 1; - Table_setRegion(dest,destTop,destLeft,destBottom,destRight,srcCell); - } - } - } - - function insertChildrenBefore(parent,child,nextSibling,pastedNodes) - { - var next; - for (var grandChild = child.firstChild; grandChild != null; grandChild = next) { - next = grandChild.nextSibling; - pastedNodes.push(grandChild); - DOM_insertBefore(parent,grandChild,nextSibling); - } - } - - function fixParagraphStyles(node,paragraphClass) - { - if (isParagraphNode(node)) { - if (node._type == HTML_P) { - var className = DOM_getAttribute(node,"class"); - if ((className == null) || (className == "")) { - debug("Setting paragraph class to "+paragraphClass); - DOM_setAttribute(node,"class",paragraphClass); - } - } - } - else { - for (var child = node.firstChild; child != null; child = child.nextSibling) { - fixParagraphStyles(child,paragraphClass); - } - } - } - - // public - Clipboard_pasteNodes = function(nodes) - { - if (nodes.length == 0) - return; - - var paragraphClass = Styles_getParagraphClass(); - if (paragraphClass != null) { - for (var i = 0; i < nodes.length; i++) { - fixParagraphStyles(nodes[i],paragraphClass); - } - } - - // Remove any elements which don't belong in the document body (in case an entire - // HTML document is being pasted in) - var i = 0; - while (i < nodes.length) { - switch (nodes[i]._type) { - case HTML_HTML: - case HTML_BODY: - case HTML_META: - case HTML_TITLE: - case HTML_SCRIPT: - case HTML_STYLE: - nodes.splice(i,1); - break; - default: - i++; - } - } - - var found = new Object(); - for (var i = 0; i < nodes.length; i++) - removeDuplicateIds(nodes[i],found); - -// if ((nodes.length == 0) && (nodes[0]._type == HTML_TABLE)) { -// // FIXME: this won't work; selectionRange is not defined -// var fromRegion = Tables_getTableRegionFromTable(nodes[0]); -// var toRegion = Tables_regionFromRange(selectionRange); -// if (toRegion != null) { -// return; -// } -// } - - Selection_deleteContents(true); - var range = Selection_get(); - if (range == null) - throw new Error("No current selection"); - - var parent; - var previousSibling; - var nextSibling; - - var start = range.start; - start = Position_preferElementPosition(start); - if (start.node.nodeType == Node.ELEMENT_NODE) { - parent = start.node; - nextSibling = start.node.childNodes[start.offset]; - previousSibling = start.node.childNodes[start.offset-1]; - } - else { - Formatting_splitTextAfter(start); - parent = start.node.parentNode; - nextSibling = start.node.nextSibling; - previousSibling = start.node; - } - - var prevLI = null; - var inItem = null; - var inList = null; - var containerParent = null; - - for (var temp = parent; temp != null; temp = temp.parentNode) { - if (isContainerNode(temp)) { - switch (temp._type) { - case HTML_LI: - inItem = temp; - break; - case HTML_UL: - case HTML_OL: - inList = temp; - break; - } - containerParent = temp.parentNode; - break; - } - } - - var pastedNodes; - if (inItem) { - pastedNodes = new Array(); - for (var i = 0; i < nodes.length; i++) { - var child = nodes[i]; - - var offset = DOM_nodeOffset(nextSibling,parent); - - switch (child._type) { - case HTML_UL: - case HTML_OL: - Formatting_movePreceding(new Position(parent,offset), - function(x) { return (x == containerParent); }); - insertChildrenBefore(inItem.parentNode,child,inItem,pastedNodes); - break; - case HTML_LI: - Formatting_movePreceding(new Position(parent,offset), - function(x) { return (x == containerParent); }); - DOM_insertBefore(inItem.parentNode,child,inItem); - pastedNodes.push(child); - break; - default: - DOM_insertBefore(parent,child,nextSibling); - pastedNodes.push(child); - break; - } - } - } - else if (inList) { - pastedNodes = new Array(); - for (var i = 0; i < nodes.length; i++) { - var child = nodes[i]; - - var offset = DOM_nodeOffset(nextSibling,parent); - - switch (child._type) { - case HTML_UL: - case HTML_OL: - insertChildrenBefore(parent,child,nextSibling,pastedNodes); - prevLI = null; - break; - case HTML_LI: - DOM_insertBefore(parent,child,nextSibling); - pastedNodes.push(child); - prevLI = null; - break; - default: - if (!isWhitespaceTextNode(child)) { - if (prevLI == null) - prevLI = DOM_createElement(document,"LI"); - DOM_appendChild(prevLI,child); - DOM_insertBefore(parent,prevLI,nextSibling); - pastedNodes.push(child); - } - } - } - } - else { - pastedNodes = nodes; - for (var i = 0; i < nodes.length; i++) { - var child = nodes[i]; - DOM_insertBefore(parent,child,nextSibling); - } - } - - var prevOffset; - if (previousSibling == null) - prevOffset = 0; - else - prevOffset = DOM_nodeOffset(previousSibling); - var nextOffset = DOM_nodeOffset(nextSibling,parent); - - var origRange = new Range(parent,prevOffset,parent,nextOffset); - - var firstPasted = pastedNodes[0]; - var lastPasted = pastedNodes[pastedNodes.length-1]; - var pastedRange = new Range(firstPasted,0,lastPasted,DOM_maxChildOffset(lastPasted)); - Range_trackWhileExecuting(origRange,function() { - Range_trackWhileExecuting(pastedRange,function() { - if (previousSibling != null) - Formatting_mergeWithNeighbours(previousSibling,Formatting_MERGEABLE_INLINE); - if (nextSibling != null) - Formatting_mergeWithNeighbours(nextSibling,Formatting_MERGEABLE_INLINE); - - Cursor_updateBRAtEndOfParagraph(parent); - - Range_ensureValidHierarchy(pastedRange,true); - })}); - - var pos = new Position(origRange.end.node,origRange.end.offset); - Range_trackWhileExecuting(pastedRange,function() { - Position_trackWhileExecuting(pos,function() { - while (true) { - if (pos.node == document.body) - break; - if (isContainerNode(pos.node) && (pos.node._type != HTML_LI)) - break; - if (!nodeHasContent(pos.node)) { - var oldNode = pos.node; - pos = new Position(pos.node.parentNode,DOM_nodeOffset(pos.node)); - DOM_deleteNode(oldNode); - } - else - break; - } - }); - }); - - pos = new Position(pastedRange.end.node,pastedRange.end.offset); - while (isOpaqueNode(pos.node)) - pos = new Position(pos.node.parentNode,DOM_nodeOffset(pos.node)+1); - pos = Position_closestMatchBackwards(pos,Position_okForInsertion); - - Selection_set(pos.node,pos.offset,pos.node,pos.offset); - Cursor_ensureCursorVisible(); - } - - function removeDuplicateIds(node,found) - { - if ((node.nodeType == Node.ELEMENT_NODE) && node.hasAttribute("id")) { - var id = node.getAttribute("id"); - - var existing = document.getElementById(id); - if (existing == null) - existing = found[id]; - - if ((existing != null) && (existing != node)) - DOM_removeAttribute(node,"id"); - else - found[id] = node; - } - for (var child = node.firstChild; child != null; child = child.nextSibling) - removeDuplicateIds(child,found); - } - - function pasteImage(href) - { - // FIXME - } - -})();