diff --git a/src/static/js/ace2_inner.js b/src/static/js/ace2_inner.js index 6d8c58bbc..0aa368764 100644 --- a/src/static/js/ace2_inner.js +++ b/src/static/js/ace2_inner.js @@ -2839,69 +2839,7 @@ function Ace2Inner(){ function doCreateDomLine(nonEmpty) { - if (browser.msie && (!nonEmpty)) - { - var result = { - node: null, - appendSpan: noop, - prepareForAdd: noop, - notifyAdded: noop, - clearSpans: noop, - finishUpdate: noop, - lineMarker: 0 - }; - - var lineElem = doc.createElement("div"); - result.node = lineElem; - - result.notifyAdded = function() - { - // magic -- settng an empty div's innerHTML to the empty string - // keeps it from collapsing. Apparently innerHTML must be set *after* - // adding the node to the DOM. - // Such a div is what IE 6 creates naturally when you make a blank line - // in a document of divs. However, when copy-and-pasted the div will - // contain a space, so we note its emptiness with a property. - lineElem.innerHTML = " "; // Frist we set a value that isnt blank - // a primitive-valued property survives copy-and-paste - setAssoc(lineElem, "shouldBeEmpty", true); - // an object property doesn't - setAssoc(lineElem, "unpasted", {}); - lineElem.innerHTML = ""; // Then we make it blank.. New line and no space = Awesome :) - }; - var lineClass = 'ace-line'; - result.appendSpan = function(txt, cls) - { - if ((!txt) && cls) - { - // gain a whole-line style (currently to show insertion point in CSS) - lineClass = domline.addToLineClass(lineClass, cls); - } - // otherwise, ignore appendSpan, this is an empty line - }; - result.clearSpans = function() - { - lineClass = ''; // non-null to cause update - }; - - var writeClass = function() - { - if (lineClass !== null) lineElem.className = lineClass; - }; - - result.prepareForAdd = writeClass; - result.finishUpdate = writeClass; - result.getInnerHTML = function() - { - return ""; - }; - - return result; - } - else - { - return domline.createDomLine(nonEmpty, doesWrap, browser, doc); - } + return domline.createDomLine(nonEmpty, doesWrap, browser, doc); } function textify(str) diff --git a/src/static/js/contentcollector.js b/src/static/js/contentcollector.js index 645b7fce4..19222bf27 100644 --- a/src/static/js/contentcollector.js +++ b/src/static/js/contentcollector.js @@ -30,6 +30,41 @@ var Changeset = require('./Changeset'); var hooks = require('./pluginfw/hooks'); var _ = require('./underscore'); +var DOMInterface = { + isNodeText: function(n) + { + return (n.nodeType == 3); + }, + nodeTagName: function(n) + { + return n.tagName; + }, + nodeValue: function(n) + { + return n.nodeValue; + }, + nodeNumChildren: function(n) + { + return n.childNodes.length; + }, + nodeChild: function(n, i) + { + return n.childNodes.item(i); + }, + nodeProp: function(n, p) + { + return n[p]; + }, + nodeAttr: function(n, a) + { + return n.getAttribute(a); + }, + optNodeInnerHTML: function(n) + { + return n.innerHTML; + } +}; + function sanitizeUnicode(s) { return UNorm.nfc(s).replace(/[\uffff\ufffe\ufeff\ufdd0-\ufdef\ud800-\udfff]/g, '?'); @@ -39,40 +74,7 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class { browser = browser || {}; - var dom = domInterface || { - isNodeText: function(n) - { - return (n.nodeType == 3); - }, - nodeTagName: function(n) - { - return n.tagName; - }, - nodeValue: function(n) - { - return n.nodeValue; - }, - nodeNumChildren: function(n) - { - return n.childNodes.length; - }, - nodeChild: function(n, i) - { - return n.childNodes.item(i); - }, - nodeProp: function(n, p) - { - return n[p]; - }, - nodeAttr: function(n, a) - { - return n.getAttribute(a); - }, - optNodeInnerHTML: function(n) - { - return n.innerHTML; - } - }; + var dom = domInterface || DOMInterface; var _blockElems = { "div": 1, @@ -729,5 +731,6 @@ function makeContentCollector(collectStyles, browser, apool, domInterface, class return cc; } +exports.DOMInterface = DOMInterface; exports.sanitizeUnicode = sanitizeUnicode; exports.makeContentCollector = makeContentCollector; diff --git a/src/static/js/domline.js b/src/static/js/domline.js index 43b5f21a3..fe43b56ce 100644 --- a/src/static/js/domline.js +++ b/src/static/js/domline.js @@ -32,10 +32,7 @@ var _ = require('./underscore'); var lineAttributeMarker = require('./linestylefilter').lineAttributeMarker; var noop = function(){}; - -var domline = {}; - -domline.addToLineClass = function(lineClass, cls) +function addToLineClass(lineClass, cls) { // an "empty span" at any point can be used to add classes to // the line, using line:className. otherwise, we ignore @@ -51,49 +48,66 @@ domline.addToLineClass = function(lineClass, cls) return lineClass; } -// if "document" is falsy we don't create a DOM node, just -// an object with innerHTML and className -domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) -{ - var result = { - node: null, - appendSpan: noop, - prepareForAdd: noop, - notifyAdded: noop, - clearSpans: noop, - finishUpdate: noop, - lineMarker: 0 - }; - - var browser = (optBrowser || {}); - var document = optDocument; +function DOMLine(nonEmpty, doesWrap, browser, document) { + this.node = null; + this.lineMarker = 0; + this.nonEmpty = nonEmpty; + this.doesWrap = doesWrap; + this.browser = browser; + this.document = document; + // if "document" is falsy we don't create a DOM node, just + // an object with innerHTML and className if (document) { - result.node = document.createElement("div"); + this.node = document.createElement("div"); } else { - result.node = { + this.node = { innerHTML: '', className: '' }; } - var html = []; - var preHtml = '', - postHtml = ''; - var curHTML = null; + this.html = []; + this.preHtml = ''; + this.postHtml = ''; + this.curHTML = null; - function processSpaces(s) - { - return domline.processSpaces(s, doesWrap); + this.lineClass = 'ace-line'; + + // Apparently overridden at the instance level sometimes... + this.notifyAdded = function () {this._notifyAdded()}; + this.finishUpdate = function () {this._finishUpdate()}; +} + +DOMLine.prototype = {}; +(function () { + + this.perTextNodeProcess = function (s) { + if (this.doesWrap) { + return _.identity(s); + } else { + return this.processSpaces(s); + } } - var perTextNodeProcess = (doesWrap ? _.identity : processSpaces); - var perHtmlLineProcess = (doesWrap ? processSpaces : _.identity); - var lineClass = 'ace-line'; - result.appendSpan = function(txt, cls) + this.perHtmlLineProcess = function (s) { + if (this.doesWrap) { + return this.processSpaces(s); + } else { + return _.identity(s); + } + } + + this.processSpaces = function(s) + { + return processSpaces(s, this.doesWrap); + } + this._notifyAdded = function () {}; + + this.appendSpan = function(txt, cls) { var processedMarker = false; // Handle lineAttributeMarker, if present @@ -109,30 +123,30 @@ domline.createDomLine = function(nonEmpty, doesWrap, optBrowser, optDocument) { if(listType.indexOf("number") < 0) { - preHtml = '