diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/editor/plugins/removeformatting.js')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/editor/plugins/removeformatting.js | 772 |
1 files changed, 0 insertions, 772 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/editor/plugins/removeformatting.js b/contexts/data/lib/closure-library/closure/goog/editor/plugins/removeformatting.js deleted file mode 100644 index d5cc810..0000000 --- a/contexts/data/lib/closure-library/closure/goog/editor/plugins/removeformatting.js +++ /dev/null @@ -1,772 +0,0 @@ -// Copyright 2008 The Closure Library Authors. All Rights Reserved. -// -// 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. -// All Rights Reserved. - -/** - * @fileoverview Plugin to handle Remove Formatting. - * - */ - -goog.provide('goog.editor.plugins.RemoveFormatting'); - -goog.require('goog.dom'); -goog.require('goog.dom.NodeType'); -goog.require('goog.dom.Range'); -goog.require('goog.dom.TagName'); -goog.require('goog.editor.BrowserFeature'); -goog.require('goog.editor.Plugin'); -goog.require('goog.editor.node'); -goog.require('goog.editor.range'); -goog.require('goog.string'); - - - -/** - * A plugin to handle removing formatting from selected text. - * @constructor - * @extends {goog.editor.Plugin} - */ -goog.editor.plugins.RemoveFormatting = function() { - goog.editor.Plugin.call(this); - - /** - * Optional function to perform remove formatting in place of the - * provided removeFormattingWorker_. - * @type {?function(string): string} - * @private - */ - this.optRemoveFormattingFunc_ = null; -}; -goog.inherits(goog.editor.plugins.RemoveFormatting, goog.editor.Plugin); - - -/** - * The editor command this plugin in handling. - * @type {string} - */ -goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND = - '+removeFormat'; - - -/** - * Regular expression that matches a block tag name. - * @type {RegExp} - * @private - */ -goog.editor.plugins.RemoveFormatting.BLOCK_RE_ = - /^(DIV|TR|LI|BLOCKQUOTE|H\d|PRE|XMP)/; - - -/** - * Appends a new line to a string buffer. - * @param {Array.<string>} sb The string buffer to add to. - * @private - */ -goog.editor.plugins.RemoveFormatting.appendNewline_ = function(sb) { - sb.push('<br>'); -}; - - -/** - * Create a new range delimited by the start point of the first range and - * the end point of the second range. - * @param {goog.dom.AbstractRange} startRange Use the start point of this - * range as the beginning of the new range. - * @param {goog.dom.AbstractRange} endRange Use the end point of this - * range as the end of the new range. - * @return {goog.dom.AbstractRange} The new range. - * @private - */ -goog.editor.plugins.RemoveFormatting.createRangeDelimitedByRanges_ = function( - startRange, endRange) { - return goog.dom.Range.createFromNodes( - startRange.getStartNode(), startRange.getStartOffset(), - endRange.getEndNode(), endRange.getEndOffset()); -}; - - -/** @override */ -goog.editor.plugins.RemoveFormatting.prototype.getTrogClassId = function() { - return 'RemoveFormatting'; -}; - - -/** @override */ -goog.editor.plugins.RemoveFormatting.prototype.isSupportedCommand = function( - command) { - return command == - goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND; -}; - - -/** @override */ -goog.editor.plugins.RemoveFormatting.prototype.execCommandInternal = - function(command, var_args) { - if (command == - goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND) { - this.removeFormatting_(); - } -}; - - -/** @override */ -goog.editor.plugins.RemoveFormatting.prototype.handleKeyboardShortcut = - function(e, key, isModifierPressed) { - if (!isModifierPressed) { - return false; - } - - if (key == ' ') { - this.getFieldObject().execCommand( - goog.editor.plugins.RemoveFormatting.REMOVE_FORMATTING_COMMAND); - return true; - } - - return false; -}; - - -/** - * Removes formatting from the current selection. Removes basic formatting - * (B/I/U) using the browser's execCommand. Then extracts the html from the - * selection to convert, calls either a client's specified removeFormattingFunc - * callback or trogedit's general built-in removeFormattingWorker_, - * and then replaces the current selection with the converted text. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.removeFormatting_ = function() { - var range = this.getFieldObject().getRange(); - if (range.isCollapsed()) { - return; - } - - // Get the html to format and send it off for formatting. Built in - // removeFormat only strips some inline elements and some inline CSS styles - var convFunc = this.optRemoveFormattingFunc_ || - goog.bind(this.removeFormattingWorker_, this); - this.convertSelectedHtmlText_(convFunc); - - // Do the execCommand last as it needs block elements removed to work - // properly on background/fontColor in FF. There are, unfortunately, still - // cases where background/fontColor are not removed here. - var doc = this.getFieldDomHelper().getDocument(); - doc.execCommand('RemoveFormat', false, undefined); - - if (goog.editor.BrowserFeature.ADDS_NBSPS_IN_REMOVE_FORMAT) { - // WebKit converts spaces to non-breaking spaces when doing a RemoveFormat. - // See: https://bugs.webkit.org/show_bug.cgi?id=14062 - this.convertSelectedHtmlText_(function(text) { - // This loses anything that might have legitimately been a non-breaking - // space, but that's better than the alternative of only having non- - // breaking spaces. - // Old versions of WebKit (Safari 3, Chrome 1) incorrectly match /u00A0 - // and newer versions properly match . - var nbspRegExp = goog.userAgent.isVersion('528') ? / /g : /\u00A0/g; - return text.replace(nbspRegExp, ' '); - }); - } -}; - - -/** - * Finds the nearest ancestor of the node that is a table. - * @param {Node} nodeToCheck Node to search from. - * @return {Node} The table, or null if one was not found. - * @private - */ -goog.editor.plugins.RemoveFormatting.getTableAncestor_ = function(nodeToCheck) { - return goog.dom.getAncestor(nodeToCheck, - function(node) { return node.tagName == goog.dom.TagName.TABLE; }, true); -}; - - -/** - * Replaces the contents of the selection with html. Does its best to maintain - * the original selection. Also does its best to result in a valid DOM. - * - * TODO(user): See if there's any way to make this work on Ranges, and then - * move it into goog.editor.range. The Firefox implementation uses execCommand - * on the document, so must work on the actual selection. - * - * @param {string} html The html string to insert into the range. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.pasteHtml_ = function(html) { - var range = this.getFieldObject().getRange(); - - var dh = this.getFieldDomHelper(); - // Use markers to set the extent of the selection so that we can reselect it - // afterwards. This works better than builtin range manipulation in FF and IE - // because their implementations are so self-inconsistent and buggy. - var startSpanId = goog.string.createUniqueString(); - var endSpanId = goog.string.createUniqueString(); - html = '<span id="' + startSpanId + '"></span>' + html + - '<span id="' + endSpanId + '"></span>'; - var dummyNodeId = goog.string.createUniqueString(); - var dummySpanText = '<span id="' + dummyNodeId + '"></span>'; - - if (goog.editor.BrowserFeature.HAS_IE_RANGES) { - // IE's selection often doesn't include the outermost tags. - // We want to use pasteHTML to replace the range contents with the newly - // unformatted text, so we have to check to make sure we aren't just - // pasting into some stray tags. To do this, we first clear out the - // contents of the range and then delete all empty nodes parenting the now - // empty range. This way, the pasted contents are never re-embedded into - // formated nodes. Pasting purely empty html does not work, since IE moves - // the selection inside the next node, so we insert a dummy span. - var textRange = range.getTextRange(0).getBrowserRangeObject(); - textRange.pasteHTML(dummySpanText); - var parent; - while ((parent = textRange.parentElement()) && - goog.editor.node.isEmpty(parent) && - !goog.editor.node.isEditableContainer(parent)) { - var tag = parent.nodeName; - // We can't remove these table tags as it will invalidate the table dom. - if (tag == goog.dom.TagName.TD || - tag == goog.dom.TagName.TR || - tag == goog.dom.TagName.TH) { - break; - } - - goog.dom.removeNode(parent); - } - textRange.pasteHTML(html); - var dummySpan = dh.getElement(dummyNodeId); - // If we entered the while loop above, the node has already been removed - // since it was a child of parent and parent was removed. - if (dummySpan) { - goog.dom.removeNode(dummySpan); - } - } else if (goog.editor.BrowserFeature.HAS_W3C_RANGES) { - // insertHtml and range.insertNode don't merge blocks correctly. - // (e.g. if your selection spans two paragraphs) - dh.getDocument().execCommand('insertImage', false, dummyNodeId); - var dummyImageNodePattern = new RegExp('<[^<]*' + dummyNodeId + '[^>]*>'); - var parent = this.getFieldObject().getRange().getContainerElement(); - if (parent.nodeType == goog.dom.NodeType.TEXT) { - // Opera sometimes returns a text node here. - // TODO(user): perhaps we should modify getParentContainer? - parent = parent.parentNode; - } - - // We have to search up the DOM because in some cases, notably when - // selecting li's within a list, execCommand('insertImage') actually splits - // tags in such a way that parent that used to contain the selection does - // not contain inserted image. - while (!dummyImageNodePattern.test(parent.innerHTML)) { - parent = parent.parentNode; - } - - // Like the IE case above, sometimes the selection does not include the - // outermost tags. For Gecko, we have already expanded the range so that - // it does, so we can just replace the dummy image with the final html. - // For WebKit, we use the same approach as we do with IE - we - // inject a dummy span where we will eventually place the contents, and - // remove parentNodes of the span while they are empty. - - if (goog.userAgent.GECKO) { - parent.innerHTML = - parent.innerHTML.replace(dummyImageNodePattern, html); - } else { - parent.innerHTML = - parent.innerHTML.replace(dummyImageNodePattern, dummySpanText); - var dummySpan = dh.getElement(dummyNodeId); - parent = dummySpan; - while ((parent = dummySpan.parentNode) && - goog.editor.node.isEmpty(parent) && - !goog.editor.node.isEditableContainer(parent)) { - var tag = parent.nodeName; - // We can't remove these table tags as it will invalidate the table dom. - if (tag == goog.dom.TagName.TD || - tag == goog.dom.TagName.TR || - tag == goog.dom.TagName.TH) { - break; - } - - // We can't just remove parent since dummySpan is inside it, and we need - // to keep dummy span around for the replacement. So we move the - // dummySpan up as we go. - goog.dom.insertSiblingAfter(dummySpan, parent); - goog.dom.removeNode(parent); - } - parent.innerHTML = - parent.innerHTML.replace(new RegExp(dummySpanText, 'i'), html); - } - } - - var startSpan = dh.getElement(startSpanId); - var endSpan = dh.getElement(endSpanId); - goog.dom.Range.createFromNodes(startSpan, 0, endSpan, - endSpan.childNodes.length).select(); - goog.dom.removeNode(startSpan); - goog.dom.removeNode(endSpan); -}; - - -/** - * Gets the html inside the selection to send off for further processing. - * - * TODO(user): Make this general so that it can be moved into - * goog.editor.range. The main reason it can't be moved is becuase we need to - * get the range before we do the execCommand and continue to operate on that - * same range (reasons are documented above). - * - * @param {goog.dom.AbstractRange} range The selection. - * @return {string} The html string to format. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.getHtmlText_ = function(range) { - var div = this.getFieldDomHelper().createDom('div'); - var textRange = range.getBrowserRangeObject(); - - if (goog.editor.BrowserFeature.HAS_W3C_RANGES) { - // Get the text to convert. - div.appendChild(textRange.cloneContents()); - } else if (goog.editor.BrowserFeature.HAS_IE_RANGES) { - // Trim the whitespace on the ends of the range, so that it the container - // will be the container of only the text content that we are changing. - // This gets around issues in IE where the spaces are included in the - // selection, but ignored sometimes by execCommand, and left orphaned. - var rngText = range.getText(); - - // BRs get reported as \r\n, but only count as one character for moves. - // Adjust the string so our move counter is correct. - rngText = rngText.replace(/\r\n/g, '\r'); - - var rngTextLength = rngText.length; - var left = rngTextLength - goog.string.trimLeft(rngText).length; - var right = rngTextLength - goog.string.trimRight(rngText).length; - - textRange.moveStart('character', left); - textRange.moveEnd('character', -right); - - var htmlText = textRange.htmlText; - // Check if in pretag and fix up formatting so that new lines are preserved. - if (textRange.queryCommandValue('formatBlock') == 'Formatted') { - htmlText = goog.string.newLineToBr(textRange.htmlText); - } - div.innerHTML = htmlText; - } - - // Get the innerHTML of the node instead of just returning the text above - // so that its properly html escaped. - return div.innerHTML; -}; - - -/** - * Move the range so that it doesn't include any partially selected tables. - * @param {goog.dom.AbstractRange} range The range to adjust. - * @param {Node} startInTable Table node that the range starts in. - * @param {Node} endInTable Table node that the range ends in. - * @return {goog.dom.SavedCaretRange} Range to use to restore the - * selection after we run our custom remove formatting. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.adjustRangeForTables_ = - function(range, startInTable, endInTable) { - // Create placeholders for the current selection so we can restore it - // later. - var savedCaretRange = goog.editor.range.saveUsingNormalizedCarets(range); - - var startNode = range.getStartNode(); - var startOffset = range.getStartOffset(); - var endNode = range.getEndNode(); - var endOffset = range.getEndOffset(); - var dh = this.getFieldDomHelper(); - - // Move start after the table. - if (startInTable) { - var textNode = dh.createTextNode(''); - goog.dom.insertSiblingAfter(textNode, startInTable); - startNode = textNode; - startOffset = 0; - } - // Move end before the table. - if (endInTable) { - var textNode = dh.createTextNode(''); - goog.dom.insertSiblingBefore(textNode, endInTable); - endNode = textNode; - endOffset = 0; - } - - goog.dom.Range.createFromNodes(startNode, startOffset, - endNode, endOffset).select(); - - return savedCaretRange; -}; - - -/** - * Remove a caret from the dom and hide it in a safe place, so it can - * be restored later via restoreCaretsFromCave. - * @param {goog.dom.SavedCaretRange} caretRange The caret range to - * get the carets from. - * @param {boolean} isStart Whether this is the start or end caret. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.putCaretInCave_ = function( - caretRange, isStart) { - var cavedCaret = goog.dom.removeNode(caretRange.getCaret(isStart)); - if (isStart) { - this.startCaretInCave_ = cavedCaret; - } else { - this.endCaretInCave_ = cavedCaret; - } -}; - - -/** - * Restore carets that were hidden away by adding them back into the dom. - * Note: this does not restore to the original dom location, as that - * will likely have been modified with remove formatting. The only - * guarentees here are that start will still be before end, and that - * they will be in the editable region. This should only be used when - * you don't actually intend to USE the caret again. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.restoreCaretsFromCave_ = - function() { - // To keep start before end, we put the end caret at the bottom of the field - // and the start caret at the start of the field. - var field = this.getFieldObject().getElement(); - if (this.startCaretInCave_) { - field.insertBefore(this.startCaretInCave_, field.firstChild); - this.startCaretInCave_ = null; - } - if (this.endCaretInCave_) { - field.appendChild(this.endCaretInCave_); - this.endCaretInCave_ = null; - } -}; - - -/** - * Gets the html inside the current selection, passes it through the given - * conversion function, and puts it back into the selection. - * - * @param {function(string): string} convertFunc A conversion function that - * transforms an html string to new html string. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.convertSelectedHtmlText_ = - function(convertFunc) { - var range = this.getFieldObject().getRange(); - - // For multiple ranges, it is really hard to do our custom remove formatting - // without invalidating other ranges. So instead of always losing the - // content, this solution at least lets the browser do its own remove - // formatting which works correctly most of the time. - if (range.getTextRangeCount() > 1) { - return; - } - - if (goog.userAgent.GECKO) { - // Determine if we need to handle tables, since they are special cases. - // If the selection is entirely within a table, there is no extra - // formatting removal we can do. If a table is fully selected, we will - // just blow it away. If a table is only partially selected, we can - // perform custom remove formatting only on the non table parts, since we - // we can't just remove the parts and paste back into it (eg. we can't - // inject html where a TR used to be). - // If the selection contains the table and more, this is automatically - // handled, but if just the table is selected, it can be tricky to figure - // this case out, because of the numerous ways selections can be formed - - // ex. if a table has a single tr with a single td with a single text node - // in it, and the selection is (textNode: 0), (textNode: nextNode.length) - // then the entire table is selected, even though the start and end aren't - // the table itself. We are truly inside a table if the expanded endpoints - // are still inside the table. - - // Expand the selection to include any outermost tags that weren't included - // in the selection, but have the same visible selection. Stop expanding - // if we reach the top level field. - var expandedRange = goog.editor.range.expand(range, - this.getFieldObject().getElement()); - - var startInTable = goog.editor.plugins.RemoveFormatting.getTableAncestor_( - expandedRange.getStartNode()); - var endInTable = goog.editor.plugins.RemoveFormatting.getTableAncestor_( - expandedRange.getEndNode()); - - if (startInTable || endInTable) { - if (startInTable == endInTable) { - // We are fully contained in the same table, there is no extra - // remove formatting that we can do, just return and run browser - // formatting only. - return; - } - - // Adjust the range to not contain any partially selected tables, since - // we don't want to run our custom remove formatting on them. - var savedCaretRange = this.adjustRangeForTables_(range, - startInTable, endInTable); - - // Hack alert!! - // If start is not in a table, then the saved caret will get sent out - // for uber remove formatting, and it will get blown away. This is - // fine, except that we need to be able to re-create a range from the - // savedCaretRange later on. So, we just remove it from the dom, and - // put it back later so we can create a range later (not exactly in the - // same spot, but don't worry we don't actually try to use it later) - // and then it will be removed when we dispose the range. - if (!startInTable) { - this.putCaretInCave_(savedCaretRange, true); - } - if (!endInTable) { - this.putCaretInCave_(savedCaretRange, false); - } - - // Re-fetch the range, and re-expand it, since we just modified it. - range = this.getFieldObject().getRange(); - expandedRange = goog.editor.range.expand(range, - this.getFieldObject().getElement()); - } - - expandedRange.select(); - range = expandedRange; - } - - // Convert the selected text to the format-less version, paste back into - // the selection. - var text = this.getHtmlText_(range); - this.pasteHtml_(convertFunc(text)); - - if (goog.userAgent.GECKO && savedCaretRange) { - // If we moved the selection, move it back so the user can't tell we did - // anything crazy and so the browser removeFormat that we call next - // will operate on the entire originally selected range. - range = this.getFieldObject().getRange(); - this.restoreCaretsFromCave_(); - var realSavedCaretRange = savedCaretRange.toAbstractRange(); - var startRange = startInTable ? realSavedCaretRange : range; - var endRange = endInTable ? realSavedCaretRange : range; - var restoredRange = - goog.editor.plugins.RemoveFormatting.createRangeDelimitedByRanges_( - startRange, endRange); - restoredRange.select(); - savedCaretRange.dispose(); - } -}; - - -/** - * Does a best-effort attempt at clobbering all formatting that the - * browser's execCommand couldn't clobber without being totally inefficient. - * Attempts to convert visual line breaks to BRs. Leaves anchors that contain an - * href and images. - * Adapted from Gmail's MessageUtil's htmlToPlainText. http://go/messageutil.js - * @param {string} html The original html of the message. - * @return {string} The unformatted html, which is just text, br's, anchors and - * images. - * @private - */ -goog.editor.plugins.RemoveFormatting.prototype.removeFormattingWorker_ = - function(html) { - var el = goog.dom.createElement('div'); - el.innerHTML = html; - - // Put everything into a string buffer to avoid lots of expensive string - // concatenation along the way. - var sb = []; - var stack = [el.childNodes, 0]; - - // Keep separate stacks for places where we need to keep track of - // how deeply embedded we are. These are analogous to the general stack. - var preTagStack = []; - var preTagLevel = 0; // Length of the prestack. - var tableStack = []; - var tableLevel = 0; - - // sp = stack pointer, pointing to the stack array. - // decrement by 2 since the stack alternates node lists and - // processed node counts - for (var sp = 0; sp >= 0; sp -= 2) { - // Check if we should pop the table level. - var changedLevel = false; - while (tableLevel > 0 && sp <= tableStack[tableLevel - 1]) { - tableLevel--; - changedLevel = true; - } - if (changedLevel) { - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - } - - - // Check if we should pop the <pre>/<xmp> level. - changedLevel = false; - while (preTagLevel > 0 && sp <= preTagStack[preTagLevel - 1]) { - preTagLevel--; - changedLevel = true; - } - if (changedLevel) { - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - } - - // The list of of nodes to process at the current stack level. - var nodeList = stack[sp]; - // The number of nodes processed so far, stored in the stack immediately - // following the node list for that stack level. - var numNodesProcessed = stack[sp + 1]; - - while (numNodesProcessed < nodeList.length) { - var node = nodeList[numNodesProcessed++]; - var nodeName = node.nodeName; - - var formatted = this.getValueForNode(node); - if (goog.isDefAndNotNull(formatted)) { - sb.push(formatted); - continue; - } - - // TODO(user): Handle case 'EMBED' and case 'OBJECT'. - switch (nodeName) { - case '#text': - // Note that IE does not preserve whitespace in the dom - // values, even in a pre tag, so this is useless for IE. - var nodeValue = preTagLevel > 0 ? - node.nodeValue : - goog.string.stripNewlines(node.nodeValue); - nodeValue = goog.string.htmlEscape(nodeValue); - sb.push(nodeValue); - continue; - - case goog.dom.TagName.P: - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - break; // break (not continue) so that child nodes are processed. - - case goog.dom.TagName.BR: - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - continue; - - case goog.dom.TagName.TABLE: - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - tableStack[tableLevel++] = sp; - break; - - case goog.dom.TagName.PRE: - case 'XMP': - // This doesn't fully handle xmp, since - // it doesn't actually ignore tags within the xmp tag. - preTagStack[preTagLevel++] = sp; - break; - - case goog.dom.TagName.STYLE: - case goog.dom.TagName.SCRIPT: - case goog.dom.TagName.SELECT: - continue; - - case goog.dom.TagName.A: - if (node.href && node.href != '') { - sb.push("<a href='"); - sb.push(node.href); - sb.push("'>"); - sb.push(this.removeFormattingWorker_(node.innerHTML)); - sb.push('</a>'); - continue; // Children taken care of. - } else { - break; // Take care of the children. - } - - case goog.dom.TagName.IMG: - sb.push("<img src='"); - sb.push(node.src); - sb.push("'"); - // border=0 is a common way to not show a blue border around an image - // that is wrapped by a link. If we remove that, the blue border will - // show up, which to the user looks like adding format, not removing. - if (node.border == '0') { - sb.push(" border='0'"); - } - sb.push('>'); - continue; - - case goog.dom.TagName.TD: - // Don't add a space for the first TD, we only want spaces to - // separate td's. - if (node.previousSibling) { - sb.push(' '); - } - break; - - case goog.dom.TagName.TR: - // Don't add a newline for the first TR. - if (node.previousSibling) { - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - } - break; - - case goog.dom.TagName.DIV: - var parent = node.parentNode; - if (parent.firstChild == node && - goog.editor.plugins.RemoveFormatting.BLOCK_RE_.test( - parent.tagName)) { - // If a DIV is the first child of another element that itself is a - // block element, the DIV does not add a new line. - break; - } - // Otherwise, the DIV does add a new line. Fall through. - - default: - if (goog.editor.plugins.RemoveFormatting.BLOCK_RE_.test(nodeName)) { - goog.editor.plugins.RemoveFormatting.appendNewline_(sb); - } - } - - // Recurse down the node. - var children = node.childNodes; - if (children.length > 0) { - // Push the current state on the stack. - stack[sp++] = nodeList; - stack[sp++] = numNodesProcessed; - - // Iterate through the children nodes. - nodeList = children; - numNodesProcessed = 0; - } - } - } - - // Replace with white space. - return goog.string.normalizeSpaces(sb.join('')); -}; - - -/** - * Handle per node special processing if neccessary. If this function returns - * null then standard cleanup is applied. Otherwise this node and all children - * are assumed to be cleaned. - * NOTE(user): If an alternate RemoveFormatting processor is provided - * (setRemoveFormattingFunc()), this will no longer work. - * @param {Element} node The node to clean. - * @return {?string} The HTML strig representation of the cleaned data. - */ -goog.editor.plugins.RemoveFormatting.prototype.getValueForNode = function( - node) { - return null; -}; - - -/** - * Sets a function to be used for remove formatting. - * @param {function(string): string} removeFormattingFunc - A function that - * takes a string of html and returns a string of html that does any other - * formatting changes desired. Use this only if trogedit's behavior doesn't - * meet your needs. - */ -goog.editor.plugins.RemoveFormatting.prototype.setRemoveFormattingFunc = - function(removeFormattingFunc) { - this.optRemoveFormattingFunc_ = removeFormattingFunc; -}; |