// DO NOT EDIT THIS FILE, edit infrastructure/ace/www/domline.js /** * 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. */ var domline = {}; domline.noop = function() {}; domline.identity = function(x) { return x; }; domline.addToLineClass = function(lineClass, cls) { // an "empty span" at any point can be used to add classes to // the line, using line:className. otherwise, we ignore // the span. cls.replace(/\S+/g, function (c) { if (c.indexOf("line:") == 0) { // add class to line lineClass = (lineClass ? lineClass+' ' : '')+c.substring(5); } }); 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: domline.noop, prepareForAdd: domline.noop, notifyAdded: domline.noop, clearSpans: domline.noop, finishUpdate: domline.noop, lineMarker: 0 }; var browser = (optBrowser || {}); var document = optDocument; if (document) { result.node = document.createElement("div"); } else { result.node = {innerHTML: '', className: ''}; } var html = []; var preHtml, postHtml; var curHTML = null; function processSpaces(s) { return domline.processSpaces(s, doesWrap); } var identity = domline.identity; var perTextNodeProcess = (doesWrap ? identity : processSpaces); var perHtmlLineProcess = (doesWrap ? processSpaces : identity); var lineClass = 'ace-line'; result.appendSpan = function(txt, cls) { if (cls.indexOf('list') >= 0) { var listType = /(?:^| )list:(\S+)/.exec(cls); if (listType) { listType = listType[1]; if (listType) { preHtml = ''; } result.lineMarker += txt.length; return; // don't append any text } } var href = null; var simpleTags = null; if (cls.indexOf('url') >= 0) { cls = cls.replace(/(^| )url:(\S+)/g, function(x0, space, url) { href = url; return space+"url"; }); } if (cls.indexOf('tag') >= 0) { cls = cls.replace(/(^| )tag:(\S+)/g, function(x0, space, tag) { if (! simpleTags) simpleTags = []; simpleTags.push(tag.toLowerCase()); return space+tag; }); } if ((! txt) && cls) { lineClass = domline.addToLineClass(lineClass, cls); } else if (txt) { var extraOpenTags = ""; var extraCloseTags = ""; if (href) { extraOpenTags = extraOpenTags+''; extraCloseTags = ''+extraCloseTags; } if (simpleTags) { simpleTags.sort(); extraOpenTags = extraOpenTags+'<'+simpleTags.join('><')+'>'; simpleTags.reverse(); extraCloseTags = ''+extraCloseTags; } html.push('',extraOpenTags, perTextNodeProcess(domline.escapeHTML(txt)), extraCloseTags,''); } }; result.clearSpans = function() { html = []; lineClass = ''; // non-null to cause update result.lineMarker = 0; }; function writeHTML() { var newHTML = perHtmlLineProcess(html.join('')); if (! newHTML) { if ((! document) || (! optBrowser)) { newHTML += ' '; } else if (! browser.msie) { newHTML += '
'; } } if (nonEmpty) { newHTML = (preHtml||'')+newHTML+(postHtml||''); } html = preHtml = postHtml = null; // free memory if (newHTML !== curHTML) { curHTML = newHTML; result.node.innerHTML = curHTML; } if (lineClass !== null) result.node.className = lineClass; } result.prepareForAdd = writeHTML; result.finishUpdate = writeHTML; result.getInnerHTML = function() { return curHTML || ''; }; return result; }; domline.escapeHTML = function(s) { var re = /[&<>'"]/g; /']/; // stupid indentation thing if (! re.MAP) { // persisted across function calls! re.MAP = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; } return s.replace(re, function(c) { return re.MAP[c]; }); }; domline.processSpaces = function(s, doesWrap) { if (s.indexOf("<") < 0 && ! doesWrap) { // short-cut return s.replace(/ /g, ' '); } var parts = []; s.replace(/<[^>]*>?| |[^ <]+/g, function(m) { parts.push(m); }); if (doesWrap) { var endOfLine = true; var beforeSpace = false; // last space in a run is normal, others are nbsp, // end of line is nbsp for(var i=parts.length-1;i>=0;i--) { var p = parts[i]; if (p == " ") { if (endOfLine || beforeSpace) parts[i] = ' '; endOfLine = false; beforeSpace = true; } else if (p.charAt(0) != "<") { endOfLine = false; beforeSpace = false; } } // beginning of line is nbsp for(var i=0;i