diff --git a/src/node/utils/ExportHtml.js b/src/node/utils/ExportHtml.js index 85d5e7a29..a94c4d97a 100644 --- a/src/node/utils/ExportHtml.js +++ b/src/node/utils/ExportHtml.js @@ -305,10 +305,12 @@ function getHTMLFromAtext(pad, atext, authorColors) // want to deal gracefully with blank lines. // => keeps track of the parents level of indentation var lists = []; // e.g. [[1,'bullet'], [3,'bullet'], ...] + var listLevels = [] for (var i = 0; i < textLines.length; i++) { var line = _analyzeLine(textLines[i], attribLines[i], apool); var lineContent = getLineHTML(line.text, line.aline); + listLevels.push(line.listLevel) if (line.listLevel)//If we are inside a list { @@ -328,13 +330,27 @@ function getHTMLFromAtext(pad, atext, authorColors) if (whichList >= lists.length)//means we are on a deeper level of indentation than the previous line { + if(lists.length > 0){ + pieces.push('') + } lists.push([line.listLevel, line.listTypeName]); + + // if there is a previous list we need to open x tags, where x is the difference of the levels + // if there is no previous list we need to open x tags, where x is the wanted level + var toOpen = lists.length > 1 ? line.listLevel - lists[lists.length - 2][0] - 1 : line.listLevel - 1 + if(line.listTypeName == "number") { + if(toOpen > 0){ + pieces.push(new Array(toOpen + 1).join('
    ')) + } pieces.push('
    1. ', lineContent || '
      '); } else { + if(toOpen > 0){ + pieces.push(new Array(toOpen + 1).join('
        ')) + } pieces.push('
        • ', lineContent || '
          '); } } @@ -363,37 +379,40 @@ function getHTMLFromAtext(pad, atext, authorColors) pieces.push('

          '); } }*/ - else//means we are getting closer to the lowest level of indentation + else//means we are getting closer to the lowest level of indentation or are at the same level { - while (whichList < lists.length - 1) - { + var toClose = lists.length > 0 ? listLevels[listLevels.length - 2] - line.listLevel : 0 + if( toClose > 0){ + pieces.push('
        • ') if(lists[lists.length - 1][1] == "number") { - pieces.push('
    '); + pieces.push(new Array(toClose+1).join('
')) + pieces.push('
  • ', lineContent || '
    '); } else { - pieces.push('
  • '); + pieces.push(new Array(toClose+1).join('')) + pieces.push('
  • ', lineContent || '
    '); } - lists.length--; + lists = lists.slice(0,whichList+1) + } else { + pieces.push('
  • ', lineContent || '
    '); } - pieces.push('
  • ', lineContent || '
    '); } } - else//outside any list + else//outside any list, need to close line.listLevel of lists { - while (lists.length > 0)//if was in a list: close it before - { - if(lists[lists.length - 1][1] == "number") - { + if(lists.length > 0){ + if(lists[lists.length - 1][1] == "number"){ pieces.push('
  • '); - } - else - { + pieces.push(new Array(listLevels[listLevels.length - 2]).join('')) + } else { pieces.push(''); + pieces.push(new Array(listLevels[listLevels.length - 2]).join('')) } - lists.length--; } + lists = [] + var lineContentFromHook = hooks.callAllStr("getLineHTMLForExport", { line: line, diff --git a/tests/frontend/specs/importexport.js b/tests/frontend/specs/importexport.js new file mode 100644 index 000000000..4ba8d57b7 --- /dev/null +++ b/tests/frontend/specs/importexport.js @@ -0,0 +1,234 @@ +describe("import functionality", function(){ + beforeEach(function(cb){ + helper.newPad(cb); // creates a new pad + this.timeout(60000); + }); + + function getinnertext(){ + var inner = helper.padInner$ + var newtext = "" + inner("div").each(function(line,el){ + newtext += el.innerHTML+"\n" + }) + return newtext + } + function importrequest(data,importurl,type){ + var success; + var error; + var result = $.ajax({ + url: importurl, + type: "post", + processData: false, + async: false, + contentType: 'multipart/form-data; boundary=boundary', + accepts: { + text: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + }, + data: 'Content-Type: multipart/form-data; boundary=--boundary\r\n\r\n--boundary\r\nContent-Disposition: form-data; name="file"; filename="import.'+type+'"\r\nContent-Type: text/plain\r\n\r\n' + data + '\r\n\r\n--boundary', + error: function(res){ + error = res + } + }) + expect(error).to.be(undefined) + return result + } + function exportfunc(link){ + var exportresults = [] + $.ajaxSetup({ + async:false + }) + $.get(link+"/export/html",function(data){ + var start = data.indexOf("") + var end = data.indexOf("") + var html = data.substr(start+6,end-start-6) + exportresults.push(["html",html]) + }) + $.get(link+"/export/txt",function(data){ + exportresults.push(["txt",data]) + }) + return exportresults + } + + it("import a pad with newlines from txt", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var textWithNewLines = 'imported text\nnewline' + importrequest(textWithNewLines,importurl,"txt") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('imported text\nnewline\n
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be("imported text
    newline

    ") + expect(results[1][1]).to.be("imported text\nnewline\n\n") + done() + }) + it("import a pad with newlines from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithNewLines = 'htmltext
    newline' + importrequest(htmlWithNewLines,importurl,"html") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('htmltext\nnewline\n
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be("htmltext
    newline

    ") + expect(results[1][1]).to.be("htmltext\nnewline\n\n") + done() + }) + it("import a pad with attributes from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithNewLines = 'htmltext
    newline' + importrequest(htmlWithNewLines,importurl,"html") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('htmltext\nnewline\n
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be('htmltext
    newline

    ') + expect(results[1][1]).to.be('htmltext\nnewline\n\n') + done() + }) + it("import a pad with bullets from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithBullets = '' + importrequest(htmlWithBullets,importurl,"html") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('\ +\n\ +\n\ +\n\ +\n\ +
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be('
    ') + expect(results[1][1]).to.be('\t* bullet line 1\n\t* bullet line 2\n\t\t* bullet2 line 1\n\t\t* bullet2 line 2\n\n') + done() + }) + it("import a pad with bullets and newlines from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithBullets = '

    ' + importrequest(htmlWithBullets,importurl,"html") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('\ +\n\ +
    \n\ +\n\ +\n\ +
    \n\ +\n\ +
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be('


    ') + expect(results[1][1]).to.be('\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t* bullet2 line 2\n\n') + done() + }) + it("import a pad with bullets and newlines and attributes from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithBullets = '

    ' + importrequest(htmlWithBullets,importurl,"html") + helper.waitFor(function(){ + return expect(getinnertext()).to.be('\ +\n\
    \n\ +\n\ +\n
    \n\ +\n\ +\n\ +\n\ +
    \n') + }) + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be('


    ') + expect(results[1][1]).to.be('\t* bullet line 1\n\n\t* bullet line 2\n\t\t* bullet2 line 1\n\n\t\t\t\t* bullet4 line 2 bisu\n\t\t\t\t* bullet4 line 2 bs\n\t\t\t\t* bullet4 line 2 uuis\n\n') + done() + }) + it("import a pad with nested bullets from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithBullets = '' + importrequest(htmlWithBullets,importurl,"html") + var oldtext=getinnertext() + helper.waitFor(function(){ + return oldtext != getinnertext() +// return expect(getinnertext()).to.be('\ +//\n\ +//\n\ +//\n\ +//\n\ +//\n\ +//\n\ +//
    \n') + }) + + var results = exportfunc(helper.padChrome$.window.location.href) + expect(results[0][1]).to.be('
    ') + expect(results[1][1]).to.be('\t* bullet line 1\n\t* bullet line 2\n\t\t* bullet2 line 1\n\t\t\t\t* bullet4 line 2\n\t\t\t\t* bullet4 line 2\n\t\t\t\t* bullet4 line 2\n\t\t\t* bullet3 line 1\n\t* bullet2 line 1\n\n') + done() + }) + it("import a pad with 8 levels of bullets and newlines and attributes from html", function(done){ + var importurl = helper.padChrome$.window.location.href+'/import' + var htmlWithBullets = '