Auto-fixing block-less content by wrapping paragraph (#3190), prevent
non-exitable-block by padding extra br.(#3189)
327349
function onSelectionChangeFixBody( evt )
	{
		var editor = evt.editor,
			path = evt.data.path,
			blockLimit = path.blockLimit,
			selection = evt.data.selection,
			range = selection.getRanges()[0],
			body = editor.document.getBody(),
			enterMode = editor.config.enterMode;

		if ( CKEDITOR.env.gecko )
		{
			activateEditing( editor );

			// Ensure bogus br could help to move cursor (out of styles) to the end of block. (#7041)
			var pathBlock = path.block || path.blockLimit,
				lastNode = pathBlock && pathBlock.getLast( isNotEmpty );

			// Check some specialities of the current path block:
			// 1. It is really displayed as block; (#7221)
			// 2. It doesn't end with one inner block; (#7467)
			// 3. It doesn't have bogus br yet.
			if ( pathBlock
					&& pathBlock.isBlockBoundary()
					&& !( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() )
					&& !pathBlock.is( 'pre' )
					&& !pathBlock.getBogus() )
			{
				pathBlock.appendBogus();
			}
		}

		// When we're in block enter mode, a new paragraph will be established
		// to encapsulate inline contents right under body. (#3657)
		if ( editor.config.autoParagraph !== false
				&& enterMode != CKEDITOR.ENTER_BR
				&& range.collapsed
				&& blockLimit.getName() == 'body'
				&& !path.block )
		{
			var fixedBlock = range.fixBlock( true,
					editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'  );

			// For IE, we should remove any filler node which was introduced before.
			if ( CKEDITOR.env.ie )
			{
				var first = fixedBlock.getFirst( isNotEmpty );
				first && isNbsp( first ) && first.remove();
			}

			// If the fixed block is actually blank and is already followed by an exitable blank
			// block, we should revert the fix and move into the existed one. (#3684)
			if ( isBlankParagraph( fixedBlock ) )
			{
				var element = fixedBlock.getNext( isNotWhitespace );
				if ( element &&
					 element.type == CKEDITOR.NODE_ELEMENT &&
					 !nonEditable( element ) )
				{
					range.moveToElementEditStart( element );
					fixedBlock.remove();
				}
				else
				{
					element = fixedBlock.getPrevious( isNotWhitespace );
					if ( element &&
						 element.type == CKEDITOR.NODE_ELEMENT &&
						 !nonEditable( element ) )
					{
						range.moveToElementEditEnd( element );
						fixedBlock.remove();
					}
				}
			}

			range.select();
			// Cancel this selection change in favor of the next (correct).  (#6811)
			evt.cancel();
		}

		// Browsers are incapable of moving cursor out of certain block elements (e.g. table, div, pre)
		// at the end of document, makes it unable to continue adding content, we have to make this
		// easier by opening an new empty paragraph.
		var testRange = new CKEDITOR.dom.range( editor.document );
		testRange.moveToElementEditEnd( editor.document.getBody() );
		var testPath = new CKEDITOR.dom.elementPath( testRange.startContainer );
		if ( !testPath.blockLimit.is( 'body') )
		{
			var paddingBlock;
			if ( enterMode != CKEDITOR.ENTER_BR )
				paddingBlock = body.append( editor.document.createElement( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) );
			else
				paddingBlock = body;

			if ( !CKEDITOR.env.ie )
				paddingBlock.appendBogus();
		}
	}
348555
function tokenizeAnnotatedBlockquote(eat, value, silent) {
    var self = this;
    var offsets = self.offset;
    var tokenizers = self.blockTokenizers;
    var interruptors = self.interruptBlockquote;
    var now = eat.now();
    var currentLine = now.line;
    var length = value.length;
    var values = [];
    var contents = [];
    var indents = [];
    var add;
    var index = 0;
    var character;
    var rest;
    var nextIndex;
    var content;
    var line;
    var startIndex;
    var prefixed;
    var exit;
    var blockType;

    while (index < length) {
        character = value.charAt(index);

        if (
            character !== space &&
            character !== tab &&
            !character.match(/[A-Z]/)
        ) {
            break;
        }

        // store the block type
        if (character.match(/[A-Z]/)) {
            switch (character) {
                case "A":
                    blockType = "aside";
                    break;
                case "W":
                    blockType = "warning";
                    break;
                case "T":
                    blockType = "tip";
                    break;
                case "E":
                    blockType = "error";
                    break;
                case "I":
                    blockType = "information";
                    break;
                case "Q":
                    blockType = "questions";
                    break;
                case "D":
                    blockType = "discussions";
                    break;
                case "X":
                    blockType = "exercises";
                    break;
                default:
                    blockType = "generic";
            }
        }

        index++;
    }

    if (value.charAt(index) !== greaterThan) {
        return;
    }

    if (silent) {
        return true;
    }

    index = 0;

    while (index < length) {
        nextIndex = value.indexOf(lineFeed, index);
        startIndex = index;
        prefixed = false;

        if (nextIndex === -1) {
            nextIndex = length;
        }

        while (index < length) {
            character = value.charAt(index);

            if (
                character !== space &&
                character !== tab &&
                !character.match(/[A-Z]/)
            ) {
                break;
            }

            index++;
        }

        if (value.charAt(index) === greaterThan) {
            index++;
            prefixed = true;

            if (value.charAt(index) === space) {
                index++;
            }
        } else {
            index = startIndex;
        }

        content = value.slice(index, nextIndex);

        if (!prefixed && !trim(content)) {
            index = startIndex;
            break;
        }

        if (!prefixed) {
            rest = value.slice(index);

            // Check if the following code contains a possible block.
            if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) {
                break;
            }
        }

        line =
            startIndex === index ? content : value.slice(startIndex, nextIndex);

        indents.push(index - startIndex);
        values.push(line);
        contents.push(content);

        index = nextIndex + 1;
    }

    index = -1;
    length = indents.length;
    add = eat(values.join(lineFeed));

    while (++index < length) {
        offsets[currentLine] = (offsets[currentLine] || 0) + indents[index];
        currentLine++;
    }

    exit = self.enterBlock();
    contents = self.tokenizeBlock(contents.join(lineFeed), now);
    exit();

    return add({
        type: "blockquote",
        blockType: blockType,
        children: contents
    });
}
913945
@SuppressWarnings("fallthrough")
    private void inlineContent() {

        skipWhitespace();
        int pos = bp;
        int depth = 1;

        loop:
        while (bp < buflen) {

            switch (ch) {
                case '\n': case '\r': case '\f':
                    newline = true;
                    // fall through

                case ' ': case '\t':
                    nextChar();
                    break;

                case '&':
                    entity(null);
                    break;

                case '<':
                    newline = false;
                    html();
                    break;

                case '{':
                    newline = false;
                    depth++;
                    nextChar();
                    break;

                case '}':
                    newline = false;
                    if (--depth == 0) {
                        nextChar();
                        return;
                    }
                    nextChar();
                    break;

                case '@':
                    if (newline)
                        break loop;
                    // fallthrough

                default:
                    nextChar();
                    break;
            }
        }

    }
594888
function _wrapMatchesInNode(textNode) {
    var parentNode  = textNode.parentNode,
        nodeValue   = wysihtml5.lang.string(textNode.data).escapeHTML(),
        tempElement = _getTempElement(parentNode.ownerDocument);

    // We need to insert an empty/temporary <span /> to fix IE quirks
    // Elsewise IE would strip white space in the beginning
    tempElement.innerHTML = "<span></span>" + _convertUrlsToLinks(nodeValue);
    tempElement.removeChild(tempElement.firstChild);

    while (tempElement.firstChild) {
      // inserts tempElement.firstChild before textNode
      parentNode.insertBefore(tempElement.firstChild, textNode);
    }
    parentNode.removeChild(textNode);
  }
754075
function stripBlock( element, enterTag, toBeChecked ) {
		var children = element.children;

		// First, check if element's children may be wrapped with <p/div>.
		// Ignore that <p/div> may not be allowed in element.parent.
		// This will be fixed when removing parent or by toBeChecked rule.
		if ( checkChildren( children, enterTag ) ) {
			element.name = enterTag;
			element.attributes = {};
			// Check if this p/div was put in correct context.
			// If not - strip parent.
			toBeChecked.push( { check: 'parent-down', el: element } );
			return;
		}

		var parent = element.parent,
			shouldAutoP = parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT || parent.name == 'body',
			i, child, p;

		for ( i = children.length; i > 0; ) {
			child = children[ --i ];

			// If parent requires auto paragraphing and child is inline node,
			// insert this child into newly created paragraph.
			if ( shouldAutoP && inlineNode( child )  ) {
				if ( !p ) {
					p = new CKEDITOR.htmlParser.element( enterTag );
					p.insertAfter( element );

					// Check if this p/div was put in correct context.
					// If not - strip parent.
					toBeChecked.push( { check: 'parent-down', el: p } );
				}
				p.add( child, 0 );
			}
			// Child which doesn't need to be auto paragraphed.
			else {
				p = null;
				child.insertAfter( element );
				// If inserted into invalid context, mark it and check
				// after removing all elements.
				if ( parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT &&
					child.type == CKEDITOR.NODE_ELEMENT &&
					!DTD[ parent.name ][ child.name ]
				)
					toBeChecked.push( { check: 'el-up', el: child } );
			}
		}

		// All children have been moved to element's parent, so remove it.
		element.remove();
	}
441872
function safeEndingTags(content) {
  var MJElements = [].concat(WHITELISTED_GLOBAL_TAG);

  (0, _forEach2.default)(_extends({}, _MJMLElementsCollection2.default, _MJMLHead2.default), function (element, name) {
    var tagName = element.tagName || name;

    MJElements.push(tagName);
  });

  var safeContent = (0, _parseAttributes2.default)(MJElements, content.replace(/\$/g, '&#36;'));

  (0, _concat2.default)(_MJMLElementsCollection.endingTags, _MJMLHead.endingTags).forEach(function (tag) {
    safeContent = safeContent.replace(regexTag(tag), _dom2.default.replaceContentByCdata(tag));
  });

  return safeContent;
}
155506
def process_block_elements (out)
      re = '\\s+(<\\/?(?:area|base(?:font)?|blockquote|body' +
        '|caption|center|cite|col(?:group)?|dd|dir|div|dl|dt|fieldset|form' +
        '|frame(?:set)?|h[1-6]|head|hr|html|legend|li|link|map|menu|meta' +
        '|ol|opt(?:group|ion)|p|param|t(?:able|body|head|d|h|r|foot|itle)' +
        '|ul)\\b[^>]*>)'

      re = Regexp.new(re)
      out.gsub!(re, '\\1')

      # remove whitespaces outside of all elements
      out.gsub! />([^<]+)</ do |m|
        m.gsub(/^\s+|\s+$/, ' ')
      end

      out
    end
929542
function deindentBlocks(input) {
  var indent = detectIndent(input).indent
  return input.replace(regex.blocks, function (match, start, body, end) {
    return start + deindent(body, indent) + end
  })
}
115336
def _highlighBlocks(self, fromBlock, atLeastUntilBlock, timeout):
        endTime = time.time() + timeout

        block = fromBlock
        lineData = self._lineData(block.previous())

        while block.isValid() and block != atLeastUntilBlock:
            if time.time() >= endTime:  # time is over, schedule parsing later and release event loop
                self._pendingBlockNumber = block.blockNumber()
                self._pendingAtLeastUntilBlockNumber = atLeastUntilBlock.blockNumber()
                self._globalTimer.scheduleCallback(self._onContinueHighlighting)
                return

            contextStack = lineData[0] if lineData is not None else None
            if block.length() < 4096:
                lineData, highlightedSegments = self._syntax.highlightBlock(block.text(), contextStack)
            else:
                """Parser freezes for a long time, if line is too long
                invalid parsing results are still better, than freeze
                """
                lineData, highlightedSegments = None, []
            if lineData is not None:
                block.setUserData(_TextBlockUserData(lineData))
            else:
                block.setUserData(None)

            self._applyHighlightedSegments(block, highlightedSegments)
            block = block.next()

        # reached atLeastUntilBlock, now parse next only while data changed
        prevLineData = self._lineData(block)
        while block.isValid():
            if time.time() >= endTime:  # time is over, schedule parsing later and release event loop
                self._pendingBlockNumber = block.blockNumber()
                self._pendingAtLeastUntilBlockNumber = atLeastUntilBlock.blockNumber()
                self._globalTimer.scheduleCallback(self._onContinueHighlighting)
                return
            contextStack = lineData[0] if lineData is not None else None
            lineData, highlightedSegments = self._syntax.highlightBlock(block.text(), contextStack)
            if lineData is not None:
                block.setUserData(_TextBlockUserData(lineData))
            else:
                block.setUserData(None)

            self._applyHighlightedSegments(block, highlightedSegments)
            if prevLineData == lineData:
                break

            block = block.next()
            prevLineData = self._lineData(block)

        # sucessfully finished, reset pending tasks
        self._pendingBlockNumber = None
        self._pendingAtLeastUntilBlockNumber = None

        
        documentLayout = self._textEdit.document().documentLayout()
        documentLayout.documentSizeChanged.emit(documentLayout.documentSize())
225811
def autoIndentBlock(self, block, char='\n'):
        
        currentText = block.text()
        spaceAtStartLen = len(currentText) - len(currentText.lstrip())
        currentIndent = currentText[:spaceAtStartLen]
        indent = self._smartIndenter.computeIndent(block, char)
        if indent is not None and indent != currentIndent:
            self._qpart.replaceText(block.position(), spaceAtStartLen, indent)
1350450
function fixContainer ( container ) {
    var children = container.childNodes,
        doc = container.ownerDocument,
        wrapper = null,
        i, l, child, isBR,
        config = getSquireInstance( doc )._config;

    for ( i = 0, l = children.length; i < l; i += 1 ) {
        child = children[i];
        isBR = child.nodeName === 'BR';
        if ( !isBR && isInline( child ) ) {
            if ( !wrapper ) {
                 wrapper = createElement( doc,
                    config.blockTag, config.blockAttributes );
            }
            wrapper.appendChild( child );
            i -= 1;
            l -= 1;
        } else if ( isBR || wrapper ) {
            if ( !wrapper ) {
                wrapper = createElement( doc,
                    config.blockTag, config.blockAttributes );
            }
            fixCursor( wrapper );
            if ( isBR ) {
                container.replaceChild( wrapper, child );
            } else {
                container.insertBefore( wrapper, child );
                i += 1;
                l += 1;
            }
            wrapper = null;
        }
        if ( isContainer( child ) ) {
            fixContainer( child );
        }
    }
    if ( wrapper ) {
        container.appendChild( fixCursor( wrapper ) );
    }
    return container;
}
376721
function ( clipboardData, node, root ) {
    var body = node.ownerDocument.body;
    var html, text;

    // Firefox will add an extra new line for BRs at the end of block when
    // calculating innerText, even though they don't actually affect display.
    // So we need to remove them first.
    cleanupBRs( node, root, true );

    node.setAttribute( 'style',
                       'position:fixed;overflow:hidden;bottom:100%;right:100%;' );
    body.appendChild( node );
    html = node.innerHTML;
    text = node.innerText || node.textContent;

    // Firefox (and others?) returns unix line endings (\n) even on Windows.
    // If on Windows, normalise to \r\n, since Notepad and some other crappy
    // apps do not understand just \n.
    if ( isWin ) {
      text = text.replace( /\r?\n/g, '\r\n' );
    }

    clipboardData.setData( 'text/html', html );
    clipboardData.setData( 'text/plain', text );

    body.removeChild( node );
  }
919231
function reflow(BlockFrameDecorator $block = null)
    {
        $fixed_children = array();
        $prev_child = null;
        $child = $this->_frame->get_first_child();
        $current_page = 0;

        while ($child) {
            $this->apply_page_style($this->_frame, $current_page + 1);

            $style = $this->_frame->get_style();

            // Pages are only concerned with margins
            $cb = $this->_frame->get_containing_block();
            $left = (float)$style->length_in_pt($style->margin_left, $cb["w"]);
            $right = (float)$style->length_in_pt($style->margin_right, $cb["w"]);
            $top = (float)$style->length_in_pt($style->margin_top, $cb["h"]);
            $bottom = (float)$style->length_in_pt($style->margin_bottom, $cb["h"]);

            $content_x = $cb["x"] + $left;
            $content_y = $cb["y"] + $top;
            $content_width = $cb["w"] - $left - $right;
            $content_height = $cb["h"] - $top - $bottom;

            // Only if it's the first page, we save the nodes with a fixed position
            if ($current_page == 0) {
                $children = $child->get_children();
                foreach ($children as $onechild) {
                    if ($onechild->get_style()->position === "fixed") {
                        $fixed_children[] = $onechild->deep_copy();
                    }
                }
                $fixed_children = array_reverse($fixed_children);
            }

            $child->set_containing_block($content_x, $content_y, $content_width, $content_height);

            // Check for begin reflow callback
            $this->_check_callbacks("begin_page_reflow", $child);

            //Insert a copy of each node which have a fixed position
            if ($current_page >= 1) {
                foreach ($fixed_children as $fixed_child) {
                    $child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child());
                }
            }

            $child->reflow();
            $next_child = $child->get_next_sibling();

            // Check for begin render callback
            $this->_check_callbacks("begin_page_render", $child);

            // Render the page
            $this->_frame->get_renderer()->render($child);

            // Check for end render callback
            $this->_check_callbacks("end_page_render", $child);

            if ($next_child) {
                $this->_frame->next_page();
            }

            // Wait to dispose of all frames on the previous page
            // so callback will have access to them
            if ($prev_child) {
                $prev_child->dispose(true);
            }
            $prev_child = $child;
            $child = $next_child;
            $current_page++;
        }

        // Dispose of previous page if it still exists
        if ($prev_child) {
            $prev_child->dispose(true);
        }
    }
1322426
function(block, in_tight_list) {
  var tag;
  var attr;
  var info_words;
  switch (block.t) {
    case 'Document':
      var whole_doc = this.renderBlocks(block.children);
      return (whole_doc === '' ? '' : whole_doc + '\n');
    case 'Paragraph':
      if (in_tight_list) {
        return this.renderInlines(block.inline_content);
      } else {
        return inTags('p', [], this.renderInlines(block.inline_content));
      }
      break;
    case 'BlockQuote':
      var filling = this.renderBlocks(block.children);
      return inTags('blockquote', [], filling === '' ? this.innersep :
          this.innersep + this.renderBlocks(block.children) + this.innersep);
    case 'ListItem':
      return inTags('li', [], this.renderBlocks(block.children, in_tight_list).trim());
    case 'List':
      tag = block.list_data.type == 'Bullet' ? 'ul' : 'ol';
      attr = (!block.list_data.start || block.list_data.start == 1) ?
              [] : [['start', block.list_data.start.toString()]];
      return inTags(tag, attr, this.innersep +
                    this.renderBlocks(block.children, block.tight) +
                    this.innersep);
    case 'ATXHeader':
    case 'SetextHeader':
      tag = 'h' + block.level;
      return inTags(tag, [], this.renderInlines(block.inline_content));
    case 'IndentedCode':
      return inTags('pre', [],
              inTags('code', [], this.escape(block.string_content)));
    case 'FencedCode':
      info_words = block.info.split(/ +/);
      attr = info_words.length === 0 || info_words[0].length === 0 ?
                   [] : [['class','language-' +
                                   this.escape(info_words[0],true)]];
      return inTags('pre', [],
              inTags('code', attr, this.escape(block.string_content)));
    case 'HtmlBlock':
      return block.string_content;
    case 'ReferenceDef':
      return "";
    case 'HorizontalRule':
      return inTags('hr',[],"",true);
    default:
      console.log("Uknown block type " + block.t);
      return "";
  }
}
887534
function nonCharactersBoundary( node ) {
		return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( CKEDITOR.tools.extend( {}, CKEDITOR.dtd.$empty, CKEDITOR.dtd.$nonEditable ) ) );
	}
1081701
function processBlocks(textString, options, data) {

	var replacer = function replacer(match, $1, $2, $3, $4, $5, $6, offset, input) {
		var out = '',
			dataValue,
			type = String($2),
			key = String($3 || '').trim(),
			blockText = String($5),
			nestedBlocks;

		dataValue = _extract(key, data);

		if (options && typeof options === 'object' && options.strictKeys) {
			if(Number.isNaN(dataValue)) {
				return match;
			}
		}

		nestedBlocks = blockText.match(pattern);
		if (nestedBlocks) {
			blockText = blockText.replace(pattern, function(match, $1, $2, $3, $4, $5, $6, offset, input) {
				var index = match.indexOf($5);
				var length = $5.length;
				var body = $5.replace(/(?:\\*)\[(.+?)(?:\\*)\]/g, "\\[$1]");
				return match.substr(0, index) + body + match.substr(index + length);
			});
		}

		var obj = {}, proto = {}, KEY;
		if (typeof dataValue === 'object' && type === '#') {
			for(KEY in dataValue) {
				obj = {}, proto = {};
				proto.KEY = proto.INDEX = KEY;
				obj[KEY] = proto.VALUE = dataValue[KEY];
				obj.__proto__ = proto;
				if (typeof dataValue[KEY] === 'object' && !isNaN(parseInt(KEY))) {
					obj = dataValue[KEY];
					obj.__proto__ = proto;
				}
				out += renderData(blockText, options, obj, Boolean(options.prefix));
			}
			if (nestedBlocks) {
				out = processBlocks(out, options, data);
			}
		} else if (dataValue && (type === '~' || type === '#')) {
			// block logical truthy
			proto.KEY = proto.INDEX = key;
			proto.VALUE = Boolean(dataValue);
			obj = data;
			obj.__proto__ = proto;

			out += renderData(blockText, options, obj, Boolean(options.prefix));
			if (nestedBlocks) {
				out = processBlocks(out, options, data);
			}
		} else if (!dataValue && (type === '^' || type === '!')) {
			// block logical falsy
			proto.KEY = proto.INDEX = key;
			proto.VALUE = Boolean(dataValue);
			obj = data;
			obj.__proto__ = proto;

			out += renderData(blockText, options, obj, Boolean(options.prefix));
			if (nestedBlocks) {
				out = processBlocks(out, options, data);
			}
		}
		return out;
	};

	var pattern = new RegExp('(\\[\\s*(~|\\^|\\!|#)([^\\r\\n]+)\\s*\\])([\\s]?)([\\s\\S]*?)(\\[\\s*\\/\\3\\s*\\]\\4?)', 'mg');

	if(typeof data === 'object' && data !== null) {
		if (options && typeof options === 'object' && options.prefix) {
			pattern = new RegExp('(\\[\\s*(~|\\^|\\!|#)'+rxquote(String(options.prefix))+'[\\.\\-\\_]([^\\r\\n]+)\\s*\\])(\\s?)([\\s\\S]*?)(\\[\\s*\\/'+rxquote(String(options.prefix))+'[\\.\\-\\_]\\3\\s*\\]\\4?)', 'mg');
		}
		textString = textString.replace(pattern, replacer);
	}

	return textString;
}
617678
function (stopCond, doEscaping) {
    var escaped = false
    while (i < src.length && (!stopCond() || escaped)) {
      if (escaped) {
        escaped = false
      } else if (doEscaping) {
        escaped = c === '\\'
      }

      buff += c
      advance(1)
    }
  }