Inline docs provider.

@param {!Editor} editor
@param {!{line:Number, ch:Number}} pos
@return {?$.Promise} resolved with an InlineWidget; null if we're not going to provide anything
541654
function inlineProvider(hostEditor, pos) {
        var jsonFile, propInfo,
            propQueue = [], // priority queue of propNames to try
            langId = hostEditor.getLanguageForSelection().getId(),
            supportedLangs = {
                "css": true,
                "scss": true,
                "less": true,
                "html": true
            },
            isQuickDocAvailable = langId ? supportedLangs[langId] : -1; // fail if langId is falsy

        // Only provide docs when cursor is in supported language
        if (!isQuickDocAvailable) {
            return null;
        }

        // Send analytics data for Quick Doc open
        HealthLogger.sendAnalyticsData(
            "cssQuickDoc",
            "usage",
            "quickDoc",
            "open"
        );

        // Only provide docs if the selection is within a single line
        var sel = hostEditor.getSelection();
        if (sel.start.line !== sel.end.line) {
            return null;
        }

        if (langId === "html") { // HTML
            jsonFile = "html.json";
            propInfo = HTMLUtils.getTagInfo(hostEditor, sel.start);
            if (propInfo.position.tokenType === HTMLUtils.ATTR_NAME && propInfo.attr && propInfo.attr.name) {
                // we're on an HTML attribute (and not on its value)
                propQueue.push(propInfo.attr.name.toLowerCase());
            }
            if (propInfo.tagName) { // we're somehow on an HTML tag (no matter where exactly)
                propInfo = propInfo.tagName.toLowerCase();
                propQueue.push("<" + propInfo + ">");
            }
        } else { // CSS-like language
            jsonFile = "css.json";
            propInfo = CSSUtils.getInfoAtPos(hostEditor, sel.start);
            if (propInfo.name) {
                propQueue.push(propInfo.name);
                // remove possible vendor prefixes
                propQueue.push(propInfo.name.replace(/^-(?:webkit|moz|ms|o)-/, ""));
            }
        }

        // Are we on a supported property? (no matter if info is available for the property)
        if (propQueue.length) {
            var result = new $.Deferred();

            // Load JSON file if not done yet
            getDocs(jsonFile)
                .done(function (docs) {
                    // Construct inline widget (if we have docs for this property)

                    var displayName, propDetails,
                        propName = _.find(propQueue, function (propName) { // find the first property where info is available
                            return docs.hasOwnProperty(propName);
                        });

                    if (propName) {
                        propDetails = docs[propName];
                        displayName = propName.substr(propName.lastIndexOf("/") + 1);
                    }
                    if (propDetails) {
                        var inlineWidget = new InlineDocsViewer(displayName, propDetails);
                        inlineWidget.load(hostEditor);
                        result.resolve(inlineWidget);
                    } else {
                        result.reject();
                    }
                })
                .fail(function () {
                    result.reject();
                });

            return result.promise();

        } else {
            return null;
        }
    }
510010
function (editor) {
        var self = this, editors = self.editors;

        // Add named and index editor instance
        editors[editor.id] = editor;
        editors.push(editor);

        toggleGlobalEvents(editors, true);

        // Doesn't call setActive method since we don't want
        // to fire a bunch of activate/deactivate calls while initializing
        self.activeEditor = editor;

        self.fire('AddEditor', { editor: editor });

        if (!beforeUnloadDelegate) {
          beforeUnloadDelegate = function () {
            self.fire('BeforeUnload');
          };

          DOM.bind(window, 'beforeunload', beforeUnloadDelegate);
        }

        return editor;
      }
715766
function compile(pos) {
  var values = []

  if (!pos) {
    return null
  }

  values = [[pos.line || 1, pos.column || 1].join(':')]

  if ('offset' in pos) {
    values.push(String(pos.offset || 0))
  }

  return values
}
979057
function getCarouselItemPosition(pos) {
        var carousel    = this,
            itemsPerRow = carousel._cols,
            itemsPerCol = carousel._rows,
            page,
            sz,
            isVertical,
            itemsCol,
            itemsRow,
            sentinel,
            delta = 0,
            top,
            left,
            rsz,
            styles = {},
            index = 0,
            itemsTable = carousel._itemsTable,
            items = itemsTable.items,
            loading = itemsTable.loading;

        isVertical = carousel.get("isVertical");
        sz  = getCarouselItemSize.call(carousel,
                isVertical ? "height" : "width");
        rsz = getRevealSize.call(carousel);

        // adjust for items not yet loaded
        while (index < pos) {
            if (!items[index] && !loading[index]) {
                delta++;
            }
            index++;
        }
        pos -= delta;

        if (itemsPerCol) {
            page = this.getPageForItem(pos);
            if (isVertical) {
                itemsRow = Math.floor(pos/itemsPerRow);
                delta = itemsRow;
                top = delta * sz;
                styles.top  = (top + rsz) + "px";

                sz  = getCarouselItemSize.call(carousel, "width");

                itemsCol = pos % itemsPerRow;
                delta = itemsCol;
                left = delta * sz;
                styles.left = left + "px";
            } else {
                itemsCol = pos % itemsPerRow;
                sentinel = (page - 1) * itemsPerRow;
                delta = itemsCol + sentinel;
                left = delta * sz;
                styles.left = (left + rsz) + "px";

                sz  = getCarouselItemSize.call(carousel, "height");

                itemsRow = Math.floor(pos/itemsPerRow);
                sentinel = (page - 1) * itemsPerCol;
                delta = itemsRow - sentinel;
                top = delta * sz;

                styles.top  = top + "px";
            }
        } else {
        if (isVertical) {
            styles.left = 0;
            styles.top  = ((pos * sz) + rsz) + "px";
        } else {
            styles.top  = 0;
            styles.left = ((pos * sz) + rsz) + "px";
        }
        }

        return styles;
    }
651308
function(content, pos) {
			var lineRange = this.findNewlineBounds(content, pos);
			return this.getLinePadding(lineRange.substring(content));
		}
681450
function( editor ) {
			var elementPath = editor.elementPath(),
				activePath = elementPath && elementPath.elements,
				pathMember, ret;

			// IE8: upon initialization if there is no path elementPath() returns null.
			if ( elementPath ) {
				for ( var i = 0; i < activePath.length; i++ ) {
					pathMember = activePath[ i ];

					if ( !ret && pathMember.getName() == 'span' && pathMember.hasAttribute( 'dir' ) && pathMember.hasAttribute( 'lang' ) )
						ret = pathMember;
				}
			}

			return ret;
		}
97949
function(name, value, pos) {
			// this is abstract implementation
			var item = new EditElement(name, value);
			this._children.push(item);
			return item;
		}
1201406
function scrollSyncExtension(editor) {
  const className = 'tui-scrollsync';
  const i18n = editor.i18n;
  const TOOL_TIP = {
    active: i18n.get('Auto scroll enabled'),
    inactive: i18n.get('Auto scroll disabled')
  };

  if (editor.isViewer()) {
    return;
  }

  const cm = editor.getCodeMirror();
  const sectionManager = new SectionManager(cm, editor.preview);
  const scrollManager = new ScrollManager(sectionManager, cm, editor.preview.$el);

  let isScrollable = false;
  let isActive = true;
  let button;
  let $divider;

  // UI
  if (editor.getUI().name === 'default') {
    const toolbar = editor.getUI().getToolbar();

    toolbar.addItem('divider');
    toolbar.addItem({
      type: 'button',
      options: {
        className,
        command: 'scrollSyncToggle',
        tooltip: TOOL_TIP.active,
        $el: $(`<button class="active ${className}" type="button"></button>`)
      }
    });
    const items = toolbar.getItems();
    $divider = items[items.length - 2].$el;
    button = items[items.length - 1];

    changeButtonVisiblityStateIfNeed();
    // hide scroll follow button in wysiwyg
    editor.on('changeMode', changeButtonVisiblityStateIfNeed);
    editor.on('changePreviewStyle', changeButtonVisiblityStateIfNeed);

    // Commands
    editor.addCommand('markdown', {
      name: 'scrollSyncToggle',
      exec() {
        isActive = !isActive;
        button._onOut();
        if (isActive) {
          button.$el.addClass('active');
          button.setTooltip(TOOL_TIP.active);
        } else {
          button.$el.removeClass('active');
          button.setTooltip(TOOL_TIP.inactive);
        }
        button._onOver();
      }
    });
  }

  // Events
  cm.on('change', () => {
    isScrollable = false;
    sectionManager.makeSectionList();
  });

  /**
   * change button visiblity state
   */
  function changeButtonVisiblityStateIfNeed() {
    if (editor.mdPreviewStyle === 'vertical' && editor.currentMode === 'markdown') {
      button.$el.show();
      $divider.show();
    } else {
      button.$el.hide();
      $divider.hide();
    }
  }

  editor.on('previewRenderAfter', () => {
    sectionManager.sectionMatch();
    if (isActive) {
      scrollManager.syncPreviewScrollTopToMarkdown();
    }
    isScrollable = true;
  });

  editor.eventManager.listen('scroll', event => {
    if (!isActive) {
      return;
    }

    if (isScrollable && editor.preview.isVisible()) {
      if (event.source === 'markdown' && !scrollManager.isMarkdownScrollEventBlocked) {
        scrollManager.syncPreviewScrollTopToMarkdown();
      } else if (event.source === 'preview' && !scrollManager.isPreviewScrollEventBlocked) {
        scrollManager.syncMarkdownScrollTopToPreview();
      }
    } else {
      scrollManager.saveScrollInfo();
    }
  });
}
1328536
function( editor ) {
			// Source mode in inline editors is only available through the "sourcedialog" plugin.
			if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )
				return;

			var sourcearea = CKEDITOR.plugins.sourcearea;

			editor.addMode( 'source', function( callback ) {
				var contentsSpace = editor.ui.space( 'contents' ),
					textarea = contentsSpace.getDocument().createElement( 'textarea' );

				textarea.setStyles(
					CKEDITOR.tools.extend( {
						// IE7 has overflow the <textarea> from wrapping table cell.
						width: CKEDITOR.env.ie7Compat ? '99%' : '100%',
						height: '100%',
						resize: 'none',
						outline: 'none',
						'text-align': 'left'
					},
					CKEDITOR.tools.cssVendorPrefix( 'tab-size', editor.config.sourceAreaTabSize || 4 ) ) );

				// Make sure that source code is always displayed LTR,
				// regardless of editor language (#10105).
				textarea.setAttribute( 'dir', 'ltr' );

				textarea.addClass( 'cke_source cke_reset cke_enable_context_menu' );

				editor.ui.space( 'contents' ).append( textarea );

				var editable = editor.editable( new sourceEditable( editor, textarea ) );

				// Fill the textarea with the current editor data.
				editable.setData( editor.getData( 1 ) );

				// Having to make <textarea> fixed sized to conquer the following bugs:
				// 1. The textarea height/width='100%' doesn't constraint to the 'td' in IE6/7.
				// 2. Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor
				// if text content within it has overflowed. (#4762)
				if ( CKEDITOR.env.ie ) {
					editable.attachListener( editor, 'resize', onResize, editable );
					editable.attachListener( CKEDITOR.document.getWindow(), 'resize', onResize, editable );
					CKEDITOR.tools.setTimeout( onResize, 0, editable );
				}

				editor.fire( 'ariaWidget', this );

				callback();
			} );

			editor.addCommand( 'source', sourcearea.commands.source );

			if ( editor.ui.addButton ) {
				editor.ui.addButton( 'Source', {
					label: editor.lang.sourcearea.toolbar,
					command: 'source',
					toolbar: 'mode,10'
				} );
			}

			editor.on( 'mode', function() {
				editor.getCommand( 'source' ).setState( editor.mode == 'source' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
			} );

			var needsFocusHack = CKEDITOR.env.ie && CKEDITOR.env.version == 9;

			function onResize() {
				// We have to do something with focus on IE9, because if sourcearea had focus
				// before being resized, the caret ends somewhere in the editor UI (#11839).
				var wasActive = needsFocusHack && this.equals( CKEDITOR.document.getActive() );

				// Holder rectange size is stretched by textarea,
				// so hide it just for a moment.
				this.hide();
				this.setStyle( 'height', this.getParent().$.clientHeight + 'px' );
				this.setStyle( 'width', this.getParent().$.clientWidth + 'px' );
				// When we have proper holder size, show textarea again.
				this.show();

				if ( wasActive )
					this.focus();
			}
		}
84782
function InlineColorEditor(color, marker) {
        this._color = color;
        this._marker = marker;
        this._isOwnChange = false;
        this._isHostChange = false;
        this._origin = "+InlineColorEditor_" + (lastOriginId++);

        this._handleColorChange = this._handleColorChange.bind(this);
        this._handleHostDocumentChange = this._handleHostDocumentChange.bind(this);

        InlineWidget.call(this);
    }
193313
function(pos) {
    var octx = this.octx,
      options = this.options.crosshair,
      plotOffset = this.plotOffset,
      x = plotOffset.left + Math.round(pos.relX) + 0.5,
      y = plotOffset.top + Math.round(pos.relY) + 0.5;
    
    if (pos.relX < 0 || pos.relY < 0 || pos.relX > this.plotWidth || pos.relY > this.plotHeight) {
      this.el.style.cursor = null;
      D.removeClass(this.el, 'flotr-crosshair');
      return; 
    }
    
    if (options.hideCursor) {
      this.el.style.cursor = 'none';
      D.addClass(this.el, 'flotr-crosshair');
    }
    
    octx.save();
    octx.strokeStyle = options.color;
    octx.lineWidth = 1;
    octx.beginPath();
    
    if (options.mode.indexOf('x') != -1) {
      octx.moveTo(x, plotOffset.top);
      octx.lineTo(x, plotOffset.top + this.plotHeight);
    }
    
    if (options.mode.indexOf('y') != -1) {
      octx.moveTo(plotOffset.left, y);
      octx.lineTo(plotOffset.left + this.plotWidth, y);
    }
    
    octx.stroke();
    octx.restore();
  }
1154523
function CaptionEditor(view) {
    var self = this;
    var attached = false;

    // text input for node edits.
    var $editor = $("<textarea/>", {
      id : "caption-editor",
      "class" : "node-text-behaviour"
    }).bind("keydown", "esc", function() {
      self.stop();
    }).bind("keydown", "return", function() {
      commitText();
    }).mousedown(function(e) {
      // avoid premature canceling
      e.stopPropagation();
    }).blur(function() {
      commitText();
    }).bind(
        "input",
        function() {
          var metrics = textMetrics.getTextMetrics(self.node,
              view.zoomFactor, $editor.val());
          $editor.css(metrics);
          alignBranches();
        });

    function commitText() {
      if (attached && self.commit) {
        self.commit(self.node, $editor.val());
      }
    }

    function alignBranches() {
      // slightly defer execution for better performance on slow
      // browsers
      setTimeout(function() {
        view.redrawNodeConnectors(self.node);
      }, 1);
    }

    /**
     * Attaches the textarea to the node and temporarily removes the
     * original node caption.
     * 
     * @param {mindmaps.Node} node
     * @param {jQuery} $cancelArea
     */
    this.edit = function(node, $cancelArea) {
      if (attached) {
        return;
      }
      this.node = node;
      attached = true;

      // TODO put text into span and hide()
      this.$text = $getNodeCaption(node);
      this.$cancelArea = $cancelArea;

      this.text = this.$text.text();

      this.$text.css({
        width : "auto",
        height : "auto"
      }).empty().addClass("edit");

      // jquery ui prevents blur() event from happening when dragging a
      // draggable. need this
      // workaround to detect click on other draggable
      $cancelArea.bind("mousedown.editNodeCaption", function(e) {
        commitText();
      });

      var metrics = textMetrics.getTextMetrics(self.node,
          view.zoomFactor, this.text);
      $editor.attr({
        value : this.text
      }).css(metrics).appendTo(this.$text).select();

    };

    /**
     * Removes the editor from the node and restores its old text value.
     */
    this.stop = function() {
      if (attached) {
        attached = false;
        this.$text.removeClass("edit");
        $editor.detach();
        this.$cancelArea.unbind("mousedown.editNodeCaption");
        view.setNodeText(this.node, this.text);

        alignBranches();
      }
    };
  }
1324613
function(editorContext, context, astManager) {
	            return astManager.getAST(editorContext).then(function(ast) {
	                var node = Finder.findNode(context.annotation.start, ast, {parents:true});
	                if(node && node.type === 'ArrayExpression') {
	                    var model = new TextModel.TextModel(ast.sourceFile.text.slice(context.annotation.start, context.annotation.end));
	                    var len = node.elements.length;
	                    var idx = len-1;
	                    var item = node.elements[idx];
	                    if(item === null) {
	                        var end = Finder.findToken(node.range[1], ast.tokens);
	                        if(end.value !== ']') {
	                            //for a follow-on token we want the previous - i.e. a token immediately following the ']' that has no space
	                            end = ast.tokens[end.index-1];
	                        }
	                        //wipe all trailing entries first using the ']' token start as the end
	                        for(; idx > -1; idx--) {
	                            item = node.elements[idx];
	                            if(item !== null) {
	                                break;
	                            }
	                        }
	                        if(item === null) {
	                            //whole array is sparse - wipe it
	                            return editorContext.setText('', context.annotation.start+1, context.annotation.end-1);
	                        }
	                        model.setText('', item.range[1]-context.annotation.start, end.range[0]-context.annotation.start);
	                    }
	                    var prev = item;
	                    for(; idx > -1; idx--) {
	                        item = node.elements[idx];
	                        if(item === null || item.range[0] === prev.range[0]) {
	                            continue;
	                        }
	                        model.setText(', ', item.range[1]-context.annotation.start, prev.range[0]-context.annotation.start); //$NON-NLS-1$
	                        prev = item;
	                    }
	                    if(item === null && prev !== null) {
	                        //need to wipe the front of the array
	                        model.setText('', node.range[0]+1-context.annotation.start, prev.range[0]-context.annotation.start);
	                    }
	                    return editorContext.setText(model.getText(), context.annotation.start, context.annotation.end);
	                }
	                return null;
	            });
	        }
820566
function (elm) {
      return Options.liftN([
        CaretFinder.firstPositionIn(elm),
        CaretFinder.lastPositionIn(elm)
      ], function (firstPos, lastPos) {
        var normalizedFirstPos = InlineUtils.normalizePosition(true, firstPos);
        var normalizedLastPos = InlineUtils.normalizePosition(false, lastPos);

        return CaretFinder.nextPosition(elm, normalizedFirstPos).map(function (pos) {
          return pos.isEqual(normalizedLastPos);
        }).getOr(true);
      }).getOr(true);
    }
601466
function(editor, syntax, profile) {
			var newPoint = findNewEditPoint(editor, 1);
			if (newPoint != -1) {
				editor.setCaretPos(newPoint);
				return true;
			}
			
			return false;
		}
764848
function screenPos( element, refWin ) {
				var pos = { x: 0, y: 0 };

				if ( !( element.is( isQuirks ? 'body' : 'html' ) ) ) {
					var box = element.$.getBoundingClientRect();
					pos.x = box.left, pos.y = box.top;
				}

				var win = element.getWindow();
				if ( !win.equals( refWin ) ) {
					var outerPos = screenPos( CKEDITOR.dom.element.get( win.$.frameElement ), refWin );
					pos.x += outerPos.x, pos.y += outerPos.y;
				}

				return pos;
			}
1279370
function( editor, output ) {
			this.getHolderElement = function() {
				var holder = this._.holder;

				if ( !holder ) {
					if ( this.isFramed ) {
						var iframe = this.document.getById( this.id + '_frame' ),
							parentDiv = iframe.getParent(),
							doc = iframe.getFrameDocument();

						// Make it scrollable on iOS. (#8308)
						CKEDITOR.env.iOS && parentDiv.setStyles( {
							'overflow': 'scroll',
							'-webkit-overflow-scrolling': 'touch'
						} );

						var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev ) {
							this.isLoaded = true;
							if ( this.onLoad )
								this.onLoad();
						}, this ) );

						doc.write( frameDocTpl.output( CKEDITOR.tools.extend( {
							css: CKEDITOR.tools.buildStyleHtml( this.css ),
							onload: 'window.parent.CKEDITOR.tools.callFunction(' + onLoad + ');'
						}, data ) ) );

						var win = doc.getWindow();

						// Register the CKEDITOR global.
						win.$.CKEDITOR = CKEDITOR;

						// Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534).
						doc.on( 'keydown', function( evt ) {
							var keystroke = evt.data.getKeystroke(),
								dir = this.document.getById( this.id ).getAttribute( 'dir' );

							// Delegate key processing to block.
							if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) {
								evt.data.preventDefault();
								return;
							}

							// ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)
							if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) ) {
								if ( this.onEscape && this.onEscape( keystroke ) === false )
									evt.data.preventDefault();
							}
						}, this );

						holder = doc.getBody();
						holder.unselectable();
						CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad );
					} else
						holder = this.document.getById( this.id );

					this._.holder = holder;
				}

				return holder;
			};

			var data = {
				editorId: editor.id,
				id: this.id,
				langCode: editor.langCode,
				dir: editor.lang.dir,
				cls: this.className,
				frame: '',
				env: CKEDITOR.env.cssClass,
				'z-index': editor.config.baseFloatZIndex + 1
			};

			if ( this.isFramed ) {
				// With IE, the custom domain has to be taken care at first,
				// for other browers, the 'src' attribute should be left empty to
				// trigger iframe's 'load' event.
				var src =
					CKEDITOR.env.air ? 'javascript:void(0)' :
					CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent(
						'document.open();' +
						// In IE, the document domain must be set any time we call document.open().
						'(' + CKEDITOR.tools.fixDomain + ')();' +
						'document.close();'
					) + '}())' :
					'';

				data.frame = frameTpl.output( {
					id: this.id + '_frame',
					src: src
				} );
			}

			var html = panelTpl.output( data );

			if ( output )
				output.push( html );

			return html;
		}