// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:collection";
import 'dart:html';
import 'dart:json' as json;

// Workaround for HTML lib missing feature.
Range newRange() {
  return document.createRange();
}

// Temporary range object to optimize performance computing client rects
// from text nodes.
Range _tempRange;
// Hacks because ASYNC measurement is annoying when just writing a script.
ClientRect getClientRect(Node n) {
  if (n is Element) {
    return n.$dom_getBoundingClientRect();
  } else {
    // Crazy hacks that works for nodes.... create a range and measure it.
    if (_tempRange == null) {
      _tempRange = newRange();
    }
    _tempRange.setStartBefore(n);
    _tempRange.setEndAfter(n);
     return _tempRange.getBoundingClientRect();
  }
}

/**
 * CSS class that is added to elements in the DOM to indicate that they should
 * be removed when extracting blocks of documentation.  This is helpful when
 * running this script in a web browser as it is easy to visually see what
 * blocks of information were extracted when using CSS such as DEBUG_CSS
 * which highlights elements that should be removed.
 */
const DART_REMOVED = "dart-removed";

const DEBUG_CSS = """
<style type="text/css">
  .dart-removed {
    background-color: rgba(255, 0, 0, 0.5);
   }
</style>""";

const MIN_PIXELS_DIFFERENT_LINES = 10;

const IDL_SELECTOR = "pre.eval, pre.idl";

Map data;

// TODO(rnystrom): Hack! Copied from domTypes.json. Instead of hard-coding
// these, should use the same mapping that the DOM/HTML code generators use.
var domTypes;
const domTypesRaw = const [
  "AbstractWorker", "ArrayBuffer", "ArrayBufferView", "Attr",
  "AudioBuffer", "AudioBufferSourceNode", "AudioChannelMerger",
  "AudioChannelSplitter", "AudioContext", "AudioDestinationNode",
  "AudioGain", "AudioGainNode", "AudioListener", "AudioNode",
  "AudioPannerNode", "AudioParam", "AudioProcessingEvent",
  "AudioSourceNode", "BarInfo", "BeforeLoadEvent", "BiquadFilterNode",
  "Blob", "CDATASection", "CSSCharsetRule", "CSSFontFaceRule",
  "CSSImportRule", "CSSMediaRule", "CSSPageRule", "CSSPrimitiveValue",
  "CSSRule", "CSSRuleList", "CSSStyleDeclaration", "CSSStyleRule",
  "CSSStyleSheet", "CSSUnknownRule", "CSSValue", "CSSValueList",
  "CanvasGradient", "CanvasPattern", "CanvasPixelArray",
  "CanvasRenderingContext", "CanvasRenderingContext2D",
  "CharacterData", "ClientRect", "ClientRectList", "Clipboard",
  "CloseEvent", "Comment", "CompositionEvent", "Console",
  "ConvolverNode", "Coordinates", "Counter", "Crypto", "CustomEvent",
  "DOMApplicationCache", "DOMException", "DOMFileSystem",
  "DOMFileSystemSync", "DOMFormData", "DOMImplementation",
  "DOMMimeType", "DOMMimeTypeArray", "DOMParser", "DOMPlugin",
  "DOMPluginArray", "DOMSelection", "DOMSettableTokenList",
  "DOMTokenList", "DOMURL", "DOMWindow", "DataTransferItem",
  "DataTransferItemList", "DataView", "Database", "DatabaseSync",
  "DedicatedWorkerContext", "DelayNode", "DeviceMotionEvent",
  "DeviceOrientationEvent", "DirectoryEntry", "DirectoryEntrySync",
  "DirectoryReader", "DirectoryReaderSync", "Document",
  "DocumentFragment", "DocumentType", "DynamicsCompressorNode",
  "Element", "ElementTimeControl", "ElementTraversal", "Entity",
  "EntityReference", "Entry", "EntryArray", "EntryArraySync",
  "EntrySync", "ErrorEvent", "Event", "EventException", "EventSource",
  "EventTarget", "File", "FileEntry", "FileEntrySync", "FileError",
  "FileException", "FileList", "FileReader", "FileReaderSync",
  "FileWriter", "FileWriterSync", "Float32Array", "Float64Array",
  "Geolocation", "Geoposition", "HTMLAllCollection",
  "HTMLAnchorElement", "HTMLAppletElement", "HTMLAreaElement",
  "HTMLAudioElement", "HTMLBRElement", "HTMLBaseElement",
  "HTMLBaseFontElement", "HTMLBodyElement", "HTMLButtonElement",
  "HTMLCanvasElement", "HTMLCollection", "HTMLDListElement",
  "HTMLDataListElement", "HTMLDetailsElement", "HTMLDirectoryElement",
  "HTMLDivElement", "HTMLDocument", "HTMLElement", "HTMLEmbedElement",
  "HTMLFieldSetElement", "HTMLFontElement", "HTMLFormElement",
  "HTMLFrameElement", "HTMLFrameSetElement", "HTMLHRElement",
  "HTMLHeadElement", "HTMLHeadingElement", "HTMLHtmlElement",
  "HTMLIFrameElement", "HTMLImageElement", "HTMLInputElement",
  "HTMLIsIndexElement", "HTMLKeygenElement", "HTMLLIElement",
  "HTMLLabelElement", "HTMLLegendElement", "HTMLLinkElement",
  "HTMLMapElement", "HTMLMarqueeElement", "HTMLMediaElement",
  "HTMLMenuElement", "HTMLMetaElement", "HTMLMeterElement",
  "HTMLModElement", "HTMLOListElement", "HTMLObjectElement",
  "HTMLOptGroupElement", "HTMLOptionElement", "HTMLOptionsCollection",
  "HTMLOutputElement", "HTMLParagraphElement", "HTMLParamElement",
  "HTMLPreElement", "HTMLProgressElement", "HTMLQuoteElement",
  "HTMLScriptElement", "HTMLSelectElement", "HTMLSourceElement",
  "HTMLSpanElement", "HTMLStyleElement", "HTMLTableCaptionElement",
  "HTMLTableCellElement", "HTMLTableColElement", "HTMLTableElement",
  "HTMLTableRowElement", "HTMLTableSectionElement",
  "HTMLTextAreaElement", "HTMLTitleElement", "HTMLTrackElement",
  "HTMLUListElement", "HTMLUnknownElement", "HTMLVideoElement",
  "HashChangeEvent", "HighPass2FilterNode", "History", "IDBAny",
  "IDBCursor", "IDBCursorWithValue", "IDBDatabase",
  "IDBDatabaseError", "IDBDatabaseException", "IDBFactory",
  "IDBIndex", "IDBKey", "IDBKeyRange", "IDBObjectStore", "IDBRequest",
  "IDBTransaction", "IDBVersionChangeEvent",
  "IDBVersionChangeRequest", "ImageData", "InjectedScriptHost",
  "InspectorFrontendHost", "Int16Array", "Int32Array", "Int8Array",
  "JavaScriptAudioNode", "JavaScriptCallFrame", "KeyboardEvent",
  "Location", "LowPass2FilterNode", "MediaElementAudioSourceNode",
  "MediaError", "MediaList", "MediaQueryList",
  "MediaQueryListListener", "MemoryInfo", "MessageChannel",
  "MessageEvent", "MessagePort", "Metadata", "MouseEvent",
  "MutationCallback", "MutationEvent", "MutationRecord",
  "NamedNodeMap", "Navigator", "NavigatorUserMediaError",
  "NavigatorUserMediaSuccessCallback", "Node", "NodeFilter",
  "NodeIterator", "NodeList", "NodeSelector", "Notation",
  "Notification", "NotificationCenter", "OESStandardDerivatives",
  "OESTextureFloat", "OESVertexArrayObject",
  "OfflineAudioCompletionEvent", "OperationNotAllowedException",
  "OverflowEvent", "PageTransitionEvent", "Performance",
  "PerformanceNavigation", "PerformanceTiming", "PopStateEvent",
  "PositionError", "ProcessingInstruction", "ProgressEvent",
  "RGBColor", "Range", "RangeException", "RealtimeAnalyserNode",
  "Rect", "SQLError", "SQLException", "SQLResultSet",
  "SQLResultSetRowList", "SQLTransaction", "SQLTransactionSync",
  "SVGAElement", "SVGAltGlyphDefElement", "SVGAltGlyphElement",
  "SVGAltGlyphItemElement", "SVGAngle", "SVGAnimateColorElement",
  "SVGAnimateElement", "SVGAnimateMotionElement",
  "SVGAnimateTransformElement", "SVGAnimatedAngle",
  "SVGAnimatedBoolean", "SVGAnimatedEnumeration",
  "SVGAnimatedInteger", "SVGAnimatedLength", "SVGAnimatedLengthList",
  "SVGAnimatedNumber", "SVGAnimatedNumberList",
  "SVGAnimatedPreserveAspectRatio", "SVGAnimatedRect",
  "SVGAnimatedString", "SVGAnimatedTransformList",
  "SVGAnimationElement", "SVGCircleElement", "SVGClipPathElement",
  "SVGColor", "SVGComponentTransferFunctionElement",
  "SVGCursorElement", "SVGDefsElement", "SVGDescElement",
  "SVGDocument", "SVGElement", "SVGElementInstance",
  "SVGElementInstanceList", "SVGEllipseElement", "SVGException",
  "SVGExternalResourcesRequired", "SVGFEBlendElement",
  "SVGFEColorMatrixElement", "SVGFEComponentTransferElement",
  "SVGFECompositeElement", "SVGFEConvolveMatrixElement",
  "SVGFEDiffuseLightingElement", "SVGFEDisplacementMapElement",
  "SVGFEDistantLightElement", "SVGFEDropShadowElement",
  "SVGFEFloodElement", "SVGFEFuncAElement", "SVGFEFuncBElement",
  "SVGFEFuncGElement", "SVGFEFuncRElement",
  "SVGFEGaussianBlurElement", "SVGFEImageElement",
  "SVGFEMergeElement", "SVGFEMergeNodeElement",
  "SVGFEMorphologyElement", "SVGFEOffsetElement",
  "SVGFEPointLightElement", "SVGFESpecularLightingElement",
  "SVGFESpotLightElement", "SVGFETileElement",
  "SVGFETurbulenceElement", "SVGFilterElement",
  "SVGFilterPrimitiveStandardAttributes", "SVGFitToViewBox",
  "SVGFontElement", "SVGFontFaceElement", "SVGFontFaceFormatElement",
  "SVGFontFaceNameElement", "SVGFontFaceSrcElement",
  "SVGFontFaceUriElement", "SVGForeignObjectElement", "SVGGElement",
  "SVGGlyphElement", "SVGGlyphRefElement", "SVGGradientElement",
  "SVGHKernElement", "SVGImageElement", "SVGLangSpace", "SVGLength",
  "SVGLengthList", "SVGLineElement", "SVGLinearGradientElement",
  "SVGLocatable", "SVGMPathElement", "SVGMarkerElement",
  "SVGMaskElement", "SVGMatrix", "SVGMetadataElement",
  "SVGMissingGlyphElement", "SVGNumber", "SVGNumberList", "SVGPaint",
  "SVGPathElement", "SVGPathSeg", "SVGPathSegArcAbs",
  "SVGPathSegArcRel", "SVGPathSegClosePath",
  "SVGPathSegCurvetoCubicAbs", "SVGPathSegCurvetoCubicRel",
  "SVGPathSegCurvetoCubicSmoothAbs",
  "SVGPathSegCurvetoCubicSmoothRel", "SVGPathSegCurvetoQuadraticAbs",
  "SVGPathSegCurvetoQuadraticRel",
  "SVGPathSegCurvetoQuadraticSmoothAbs",
  "SVGPathSegCurvetoQuadraticSmoothRel", "SVGPathSegLinetoAbs",
  "SVGPathSegLinetoHorizontalAbs", "SVGPathSegLinetoHorizontalRel",
  "SVGPathSegLinetoRel", "SVGPathSegLinetoVerticalAbs",
  "SVGPathSegLinetoVerticalRel", "SVGPathSegList",
  "SVGPathSegMovetoAbs", "SVGPathSegMovetoRel", "SVGPatternElement",
  "SVGPoint", "SVGPointList", "SVGPolygonElement",
  "SVGPolylineElement", "SVGPreserveAspectRatio",
  "SVGRadialGradientElement", "SVGRect", "SVGRectElement",
  "SVGRenderingIntent", "SVGSVGElement", "SVGScriptElement",
  "SVGSetElement", "SVGStopElement", "SVGStringList", "SVGStylable",
  "SVGStyleElement", "SVGSwitchElement", "SVGSymbolElement",
  "SVGTRefElement", "SVGTSpanElement", "SVGTests",
  "SVGTextContentElement", "SVGTextElement", "SVGTextPathElement",
  "SVGTextPositioningElement", "SVGTitleElement", "SVGTransform",
  "SVGTransformList", "SVGTransformable", "SVGURIReference",
  "SVGUnitTypes", "SVGUseElement", "SVGVKernElement",
  "SVGViewElement", "SVGViewSpec", "SVGZoomAndPan", "SVGZoomEvent",
  "Screen", "ScriptProfile", "ScriptProfileNode", "SharedWorker",
  "SharedWorkercontext", "SpeechInputEvent", "SpeechInputResult",
  "SpeechInputResultList", "Storage", "StorageEvent", "StorageInfo",
  "StyleMedia", "StyleSheet", "StyleSheetList", "Text", "TextEvent",
  "TextMetrics", "TextTrack", "TextTrackCue", "TextTrackCueList",
  "TimeRanges", "Touch", "TouchEvent", "TouchList", "TreeWalker",
  "UIEvent", "Uint16Array", "Uint32Array", "Uint8Array",
  "ValidityState", "VoidCallback", "WaveShaperNode",
  "WebGLActiveInfo", "WebGLBuffer", "WebGLContextAttributes",
  "WebGLContextEvent", "WebGLDebugRendererInfo", "WebGLDebugShaders",
  "WebGLFramebuffer", "WebGLProgram", "WebGLRenderbuffer",
  "WebGLRenderingContext", "WebGLShader", "WebGLTexture",
  "WebGLUniformLocation", "WebGLVertexArrayObjectOES",
  "WebKitAnimation", "WebKitAnimationEvent", "WebKitAnimationList",
  "WebKitBlobBuilder", "WebKitCSSFilterValue",
  "WebKitCSSKeyframeRule", "WebKitCSSKeyframesRule",
  "WebKitCSSMatrix", "WebKitCSSTransformValue", "WebKitFlags",
  "WebKitLoseContext", "WebKitMutationObserver", "WebKitPoint",
  "WebKitTransitionEvent", "WebSocket", "WheelEvent", "Worker",
  "WorkerContext", "WorkerLocation", "WorkerNavigator",
  "XMLHttpRequest", "XMLHttpRequestException",
  "XMLHttpRequestProgressEvent", "XMLHttpRequestUpload",
  "XMLSerializer", "XPathEvaluator", "XPathException",
  "XPathExpression", "XPathNSResolver", "XPathResult",
  "XSLTProcessor", "AudioBufferCallback", "DatabaseCallback",
  "EntriesCallback", "EntryCallback", "ErrorCallback", "FileCallback",
  "FileSystemCallback", "FileWriterCallback", "MetadataCallback",
  "NavigatorUserMediaErrorCallback", "PositionCallback",
  "PositionErrorCallback", "SQLStatementCallback",
  "SQLStatementErrorCallback", "SQLTransactionCallback",
  "SQLTransactionErrorCallback", "SQLTransactionSyncCallback",
  "StorageInfoErrorCallback", "StorageInfoQuotaCallback",
  "StorageInfoUsageCallback", "StringCallback"
];

Map dbEntry;

Map get dartIdl => data['dartIdl'];
String get currentType => data['type'];

String _currentTypeShort;
String get currentTypeShort {
  if (_currentTypeShort == null) {
    _currentTypeShort = currentType;
    _currentTypeShort = trimPrefix(_currentTypeShort, "HTML");
    _currentTypeShort = trimPrefix(_currentTypeShort, "SVG");
    _currentTypeShort = trimPrefix(_currentTypeShort, "DOM");
    _currentTypeShort = trimPrefix(_currentTypeShort, "WebKit");
    _currentTypeShort = trimPrefix(_currentTypeShort, "Webkit");
  }
  return _currentTypeShort;
}

String _currentTypeTiny;
String get currentTypeTiny {
  if (_currentTypeTiny == null) {
    _currentTypeTiny = currentTypeShort;
    _currentTypeTiny = trimEnd(_currentTypeTiny, "Element");
  }
  return _currentTypeTiny;
}

Map get searchResult => data['searchResult'];
String get pageUrl => searchResult['link'];

String _pageDomain;
String get pageDomain {
  if (_pageDomain == null) {
    _pageDomain = pageUrl.substring(0, pageUrl.indexOf("/", "https://".length));
  }
  return _pageDomain;
}

String get pageDir {
  return pageUrl.substring(0, pageUrl.lastIndexOf('/') + 1);
}

String getAbsoluteUrl(AnchorElement anchor) {
  if (anchor == null || anchor.href.length == 0) return '';
  String path = anchor.href;
  RegExp fullUrlRegExp = new RegExp("^https?://");
  if (fullUrlRegExp.hasMatch(path)) return path;
  if (path.startsWith('/')) {
    return "$pageDomain$path";
  } else if (path.startsWith("#")) {
    return "$pageUrl$path";
  } else {
    return "$pageDir$path";
  }
}

bool inTable(Node n) {
  while (n != null) {
    if (n is TableElement) return true;
    n = n.parent;
  }
  return false;
}

String escapeHTML(str) {
  Element e = new Element.tag("div");
  e.text = str;
  return e.innerHTML;
}

List<Text> getAllTextNodes(Element elem) {
  final nodes = <Text>[];
  helper(Node n) {
    if (n is Text) {
      nodes.add(n);
    } else {
      for (Node child in n.nodes) {
        helper(child);
      }
    }
  };

  helper(elem);
  return nodes;
}

/**
 * Whether a node and its children are all types that are safe to skip if the
 * nodes have no text content.
 */
bool isSkippableType(Node n) {
  // TODO(jacobr): are there any types we don't want to skip even if they
  // have no text content?
  if (n is ImageElement || n is CanvasElement || n is InputElement
      || n is ObjectElement) {
    return false;
  }
  if (n is Text) return true;

  for (final child in n.nodes) {
    if (!isSkippableType(child)) {
      return false;
    }
  }
  return true;
}

bool isSkippable(Node n) {
  if (!isSkippableType(n)) return false;
  return n.text.trim().length == 0;
}

void onEnd() {
  // Hideous hack to send JSON back to JS.
  String dbJson = json.stringify(dbEntry);
  // workaround bug in json.parse.
  dbJson = dbJson.replaceAll("ZDARTIUMDOESNTESCAPESLASHNJXXXX", "\\n");

  // Use postMessage to end the JSON to JavaScript. TODO(jacobr): use a simple
  // isolate based Dart-JS interop solution in the future.
  window.postMessage("START_DART_MESSAGE_UNIQUE_IDENTIFIER$dbJson", "*");
}

class SectionParseResult {
  final String html;
  final String url;
  final String idl;
  SectionParseResult(this.html, this.url, this.idl);
}

String genCleanHtml(Element root) {
  for (final e in root.queryAll(".$DART_REMOVED")) {
    e.classes.remove(DART_REMOVED);
  }

  // Ditch inline styles.
  for (final e in root.queryAll('[style]')) {
    e.attributes.remove('style');
  }

  // These elements are just tags that we should suppress.
  for (final e in root.queryAll(".lang.lang-en")) {
    e.remove();
  }

  Element parametersHeader;
  Element returnValueHeader;
  for (final e in root.queryAll("h6")) {
    if (e.text == 'Parameters') {
      parametersHeader = e;
    } else if (e.text == 'Return value') {
      returnValueHeader = e;
    }
  }

  if (parametersHeader != null) {
    int numEmptyParameters = 0;
    final parameterDescriptions = root.queryAll("dd");
    for (Element parameterDescription in parameterDescriptions) {
      if (parameterDescription.text.trim().length == 0) {
        numEmptyParameters++;
      }
    }
    if (numEmptyParameters > 0 &&
        numEmptyParameters == parameterDescriptions.length) {
      // Remove the parameter list as it adds zero value as all descriptions
      // are empty.
      parametersHeader.remove();
      for (final e in root.queryAll("dl")) {
        e.remove();
      }
    } else if (parameterDescriptions.length == 0 &&
        parametersHeader.nextElementSibling != null &&
        parametersHeader.nextElementSibling.text.trim() == 'None.') {
      // No need to display that the function takes 0 parameters.
      parametersHeader.nextElementSibling.remove();
      parametersHeader.remove();
    }
  }

  // Heuristic: if the return value is a single word it is a type name not a
  // useful text description so suppress it.
  if (returnValueHeader != null &&
      returnValueHeader.nextElementSibling != null &&
      returnValueHeader.nextElementSibling.text.trim().split(' ').length < 2) {
    returnValueHeader.nextElementSibling.remove();
    returnValueHeader.remove();
  }

  bool changed = true;
  while (changed) {
    changed = false;
    while (root.nodes.length == 1 && root.nodes.first is Element) {
      root = root.nodes.first;
      changed = true;
    }

    // Trim useless nodes from the front.
    while (root.nodes.length > 0 &&
        isSkippable(root.nodes.first)) {
      root.nodes.first.remove();
      changed = true;
    }

    // Trim useless nodes from the back.
    while (root.nodes.length > 0 &&
        isSkippable(root.nodes.last)) {
      root.nodes.last.remove();
      changed = true;
    }
  }
  return JSONFIXUPHACK(root.innerHTML);
}

String genPrettyHtmlFromElement(Element e) {
  e = e.clone(true);
  return genCleanHtml(e);
}

class PostOrderTraversalIterator implements Iterator<Node> {

  Node _next;
  Node _current;

  PostOrderTraversalIterator(Node start) {
    _next = _leftMostDescendent(start);
  }

  Node get current => _current;
  bool get hasNext => _next != null;

  bool moveNext() {
    _current = _next;
    if (_next == null) return false;
    if (_next.nextNode != null) {
      _next = _leftMostDescendent(_next.nextNode);
    } else {
      _next = _next.parent;
    }
    return true;
  }

  static Node _leftMostDescendent(Node n) {
    while (n.nodes.length > 0) {
      n = n.nodes.first;
    }
    return n;
  }
}

class PostOrderTraversal extends IterableBase<Node> {
  final Node _node;
  PostOrderTraversal(this._node);

  Iterator<Node> get iterator => new PostOrderTraversalIterator(_node);
}

/**
 * Estimate what content represents the first line of text within the [section]
 * range returning null if there isn't a plausible first line of text that
 * contains the string [prop].  We measure the actual rendered client rectangle
 * for the text and use heuristics defining how many pixels text can vary by
 * and still be viewed as being on the same line.
 */
Range findFirstLine(Range section, String prop) {
  final firstLine = newRange();
  firstLine.setStart(section.startContainer, section.startOffset);

  num maxBottom = null;
  for (final n in new PostOrderTraversal(section.startContainer)) {
    int compareResult = section.comparePoint(n, 0);
    if (compareResult == -1) {
      // before range so skip.
      continue;
    } else if (compareResult > 0) {
      // After range so exit.
      break;
    }

    final rect = getClientRect(n);
    num bottom = rect.bottom;
    if (rect.height > 0 && rect.width > 0) {
      if (maxBottom != null &&
          maxBottom + MIN_PIXELS_DIFFERENT_LINES < bottom) {
        break;
      } else if (maxBottom == null || maxBottom > bottom) {
        maxBottom = bottom;
      }
    }

    firstLine.setEndAfter(n);
  }

  // If the first line of text in the section does not contain the property
  // name then we're not confident we are able to extract a high accuracy match
  // so we should not return anything.
  if (!firstLine.toString().contains(stripWebkit(prop))) {
    return null;
  }
  return firstLine;
}

/** Find child anchor elements that contain the text [prop]. */
AnchorElement findAnchorElement(Element root, String prop) {
  for (AnchorElement a in root.queryAll("a")) {
    if (a.text.contains(prop)) {
      return a;
    }
  }
  return null;
}

// First surrounding element with an ID is safe enough.
Element findTighterRoot(Element elem, Element root) {
  Element candidate = elem;
  while (root != candidate) {
    candidate = candidate.parent;
    if (candidate.id.length > 0 && candidate.id.indexOf("section_") != 0) {
      break;
    }
  }
  return candidate;
}

// TODO(jacobr): this is very slow and ugly.. consider rewriting or at least
// commenting carefully.
SectionParseResult filteredHtml(Element elem, Element root, String prop,
    Function fragmentGeneratedCallback) {
  // Using a tighter root avoids false positives at the risk of trimming
  // text we shouldn't.
  root = findTighterRoot(elem, root);
  final range = newRange();
  range.setStartBefore(elem);

  Element current = elem;
  while (current != null) {
    range.setEndBefore(current);
    if (current.classes.contains(DART_REMOVED) &&
        range.toString().trim().length > 0) {
      break;
    }
    if (current.firstElementChild != null) {
      current = current.firstElementChild;
    } else {
      while (current != null) {
        range.setEndAfter(current);
        if (current == root) {
          current = null;
          break;
        }
        if (current.nextElementSibling != null) {
          current = current.nextElementSibling;
          break;
        }
        current = current.parent;
      }
    }
  }
  String url = null;
  if (prop != null) {
    Range firstLine = findFirstLine(range, prop);
    if (firstLine != null) {
      range.setStart(firstLine.endContainer, firstLine.endOffset);
      DocumentFragment firstLineClone = firstLine.cloneContents();
      AnchorElement anchor = findAnchorElement(firstLineClone, prop);
      if (anchor != null) {
        url = getAbsoluteUrl(anchor);
      }
    }
  }
  final fragment = range.cloneContents();
  if (fragmentGeneratedCallback != null) {
    fragmentGeneratedCallback(fragment);
  }
  // Strip tags we don't want
  for (Element e in fragment.queryAll("script, object, style")) {
    e.remove();
  }

  // Extract idl
  final idl = new StringBuffer();
  if (prop != null && prop.length > 0) {
    // Only expect properties to have HTML.
    for(Element e in fragment.queryAll(IDL_SELECTOR)) {
      idl.write(e.outerHTML);
      e.remove();
    }
    // TODO(jacobr) this is a very basic regex to see if text looks like IDL
    RegExp likelyIdl = new RegExp(" $prop\\w*\\(");

    for (Element e in fragment.queryAll("pre")) {
      // Check if it looks like idl...
      String txt = e.text.trim();
      if (likelyIdl.hasMatch(txt) && txt.contains("\n") && txt.contains(")")) {
        idl.write(e.outerHTML);
        e.remove();
      }
    }
  }
  return new SectionParseResult(genCleanHtml(fragment), url, idl.toString());
}

/**
 * Find the best child element of [root] that appears to be an API definition
 * for [prop].  [allText] is a list of all text nodes under root computed by
 * the caller to improve performance.
 */
Element findBest(Element root, List<Text> allText, String prop,
    String propType) {
  // Best bet: find a child of root where the id matches the property name.
  Element cand = root.query("#$prop");

  if (cand == null && propType == "methods") {
    cand = root.query("[id=$prop\\(\\)]");
  }
  while (cand != null && cand.text.trim().length == 0) {
    // We found the bookmark for the element but sadly it is just an empty
    // placeholder. Find the first real element.
    cand = cand.nextElementSibling;
  }
  if (cand != null) {
    return cand;
  }

  // If we are at least 70 pixels from the left, something is definitely
  // fishy and we shouldn't even consider this candidate as nobody visually
  // formats API docs like that.
  num candLeft = 70;

  for (Text text in allText) {
    Element proposed = null;

    // TODO(jacobr): does it hurt precision to use the full cleanup?
    String t = fullNameCleanup(text.text);
    if (t == prop) {
      proposed = text.parent;
      ClientRect candRect = getClientRect(proposed);

      // TODO(jacobr): this is a good heuristic
      // if (selObj.selector.indexOf(" > DD ") == -1
      if (candRect.left < candLeft) {
        cand = proposed;
        candLeft = candRect.left;
      }
    }
  }
  return cand;
}

/**
 * Checks whether [e] is tagged as obsolete or deprecated using heuristics
 * for what these tags look like in the MDN docs.
 */
bool isObsolete(Element e) {
  RegExp obsoleteRegExp = new RegExp(r"(^|\s)obsolete(?=\s|$)");
  RegExp deprecatedRegExp = new RegExp(r"(^|\s)deprecated(?=\s|$)");
  for (Element child in e.queryAll("span")) {
    String t = child.text.toLowerCase();
    if (t.startsWith("obsolete") || t.startsWith("deprecated")) return true;
  }

  String text = e.text.toLowerCase();
  return obsoleteRegExp.hasMatch(text) || deprecatedRegExp.hasMatch(text);
}

bool isFirstCharLowerCase(String str) {
  return new RegExp("^[a-z]").hasMatch(str);
}

/**
 * Extracts information from a fragment of HTML only searching under the [root]
 * html node.  [secitonSelector] specifies the query to use to find candidate
 * sections of the document to consider (there may be more than one).
 * [currentType] specifies the name of the current class. [members] specifies
 * the known class members for this class that we are attempting to find
 * documentation for.  [propType] indicates whether we are searching for
 * methods, properties, constants, or constructors.
 */
void scrapeSection(Element root, String sectionSelector, String currentType,
    List members, String propType) {
  Map expectedProps = dartIdl[propType];

  Set<String> alreadyMatchedProperties = new Set<String>();
  bool onlyConsiderTables = false;
  ElementList allMatches = root.queryAll(sectionSelector);
  if (allMatches.length == 0) {
    // If we can't find any matches to the sectionSelector, we fall back to
    // considering all tables in the document.  This is dangerous so we only
    // allow the safer table matching extraction rules for this case.
    allMatches = root.queryAll(".fullwidth-table");
    onlyConsiderTables = true;
  }
  for (Element matchElement in allMatches) {
    final match = matchElement.parent;
    if (!match.id.startsWith("section") && match.id != "pageText") {
      throw "Unexpected element $match";
    }
    // We don't want to later display this text a second time while for example
    // displaying class level summary information as then we would display
    // the same documentation twice.
    match.classes.add(DART_REMOVED);

    bool foundProps = false;

    // TODO(jacobr): we should really look for the table tag instead
    // add an assert if we are missing something that is a table...
    // TODO(jacobr) ignore tables in tables.
    for (Element t in match.queryAll('.standard-table, .fullwidth-table')) {
      int helpIndex = -1;
      num i = 0;
      for (Element r in t.queryAll("th, td.header")) {
        final txt = r.text.trim().split(" ")[0].toLowerCase();
        if (txt == "description") {
          helpIndex = i;
          break;
        }
        i++;
      }

      // Figure out which column in the table contains member names by
      // tracking how many member names each column contains.
      final numMatches = new List<int>(i);
      for (int j = 0; j < i; j++) {
        numMatches[j] = 0;
      }

      // Find the column that seems to have the most names that look like
      // expected properties.
      for (Element r in t.queryAll("tbody tr")) {
        ElementList row = r.elements;
        if (row.length == 0 || row.first.classes.contains(".header")) {
          continue;
        }

        for (int k = 0; k < numMatches.length && k < row.length; k++) {
          if (expectedProps.containsKey(fullNameCleanup(row[k].text))) {
            numMatches[k]++;
            break;
          }
        }
      }

      int propNameIndex = 0;
      {
        int bestCount = numMatches[0];
        for (int k = 1; k < numMatches.length; k++) {
          if (numMatches[k] > bestCount) {
            bestCount = numMatches[k];
            propNameIndex = k;
          }
        }
      }

      for (Element r in t.queryAll("tbody tr")) {
        final row = r.elements;
        if (row.length > propNameIndex && row.length > helpIndex) {
          if (row.first.classes.contains(".header")) {
            continue;
          }
          // TODO(jacobr): this code for determining the namestr is needlessly
          // messy.
          final nameRow = row[propNameIndex];
          AnchorElement a = nameRow.query("a");
          String goodName = '';
          if (a != null) {
            goodName = a.text.trim();
          }
          String nameStr = nameRow.text;

          Map entry = new Map<String, String>();

          entry["name"] = fullNameCleanup(nameStr.length > 0 ?
              nameStr : goodName);

          final parse = filteredHtml(nameRow, nameRow, entry["name"], null);
          String altHelp = parse.html;

          entry["help"] = (helpIndex == -1 || row[helpIndex] == null) ?
              altHelp : genPrettyHtmlFromElement(row[helpIndex]);
          if (parse.url != null) {
            entry["url"] = parse.url;
          }

          if (parse.idl.length > 0) {
            entry["idl"] = parse.idl;
          }

          entry["obsolete"] = isObsolete(r);

          if (entry["name"].length > 0) {
            cleanupEntry(members, entry);
            alreadyMatchedProperties.add(entry['name']);
            foundProps = true;
          }
        }
      }
    }

    if (onlyConsiderTables) {
      continue;
    }

    // After this point we have higher risk tests that attempt to perform
    // rudimentary page segmentation.  This approach is much more error-prone
    // than using tables because the HTML is far less clearly structured.

    final allText = getAllTextNodes(match);

    final pmap = new Map<String, Element>();
    for (final prop in expectedProps.keys) {
      if (alreadyMatchedProperties.contains(prop)) {
        continue;
      }
      final e = findBest(match, allText, prop, propType);
      if (e != null && !inTable(e)) {
        pmap[prop] = e;
      }
    }

    for (final prop in pmap.keys) {
      pmap[prop].classes.add(DART_REMOVED);
    }

    // The problem is the MDN docs do place documentation for each method in a
    // nice self contained subtree. Instead you will see something like:

    // <h3>drawImage</h3>
    // <p>Draw image is an awesome method</p>
    // some more info on drawImage here
    // <h3>mozDrawWindow</h3>
    // <p>This API cannot currently be used by Web content.
    // It is chrome only.</p>
    // <h3>drawRect</h3>
    // <p>Always call drawRect instead of drawImage</p>
    // some more info on drawRect here...

    // The trouble is we will easily detect that the drawImage and drawRect
    // entries are method definitions because we know to search for these
    // method names but we will not detect that mozDrawWindow is a method
    // definition as that method doesn't exist in our IDL.  Thus if we are not
    // careful the definition for the drawImage method will contain the
    // definition for the mozDrawWindow method as well which would result in
    // broken docs.  We solve this problem by finding all content with similar
    // visual structure to the already found method definitions.  It turns out
    // that using the visual position of each element on the page is much
    // more reliable than using the DOM structure
    // (e.g. section_root > div > h3) for the MDN docs because MDN authors
    // carefully check that the documentation for each method comment is
    // visually consistent but take less care to check that each
    // method comment has identical markup structure.
    for (String prop in pmap.keys) {
      Element e = pmap[prop];
      ClientRect r = getClientRect(e);
      // TODO(jacobr): a lot of these queries are identical and this code
      // could easily be optimized.
      for (final cand in match.queryAll(e.tagName)) {
        // TODO(jacobr): use a negative selector instead.
        if (!cand.classes.contains(DART_REMOVED) && !inTable(cand)) {
          final candRect = getClientRect(cand);
          // Only consider matches that have similar heights and identical left
          // coordinates.
          if (candRect.left == r.left &&
            (candRect.height - r.height).abs() < 5) {
            String propName = fullNameCleanup(cand.text);
            if (isFirstCharLowerCase(propName) && !pmap.containsKey(propName)
                && !alreadyMatchedProperties.contains(propName)) {
              pmap[propName] = cand;
            }
          }
        }
      }
    }

    // We mark these elements in batch to reduce the number of layouts
    // triggered. TODO(jacobr): use new batch based async measurement to make
    // this code flow simpler.
    for (String prop in pmap.keys) {
      Element e = pmap[prop];
      e.classes.add(DART_REMOVED);
    }

    // Find likely "subsections" of the main section and mark them with
    // DART_REMOVED so we don't include them in member descriptions... which
    // would suck.
    for (Element e in match.queryAll("[id]")) {
      if (e.id.contains(matchElement.id)) {
        e.classes.add(DART_REMOVED);
      }
    }

    for (String prop in pmap.keys) {
      Element elem = pmap[prop];
      bool obsolete = false;
      final parse = filteredHtml(
        elem, match, prop,
        (Element e) {
          obsolete = isObsolete(e);
        });
      Map entry = {
        "url" : parse.url,
        "name" : prop,
        "help" : parse.html,
        "obsolete" : obsolete
      };
      if (parse.idl.length > 0) {
        entry["idl"] = parse.idl;
      }
      cleanupEntry(members, entry);
    }
  }
}

String trimHtml(String html) {
  // TODO(jacobr): implement this.  Remove spurious enclosing HTML tags, etc.
  return html;
}

bool maybeName(String name) {
  return new RegExp("^[a-z][a-z0-9A-Z]+\$").hasMatch(name) ||
      new RegExp("^[A-Z][A-Z_]*\$").hasMatch(name);
}

// TODO(jacobr): this element is ugly at the moment but will become easier to
// read once ElementList supports most of the Element functionality.
void markRemoved(var e) {
  if (e != null) {
    if (e is Element) {
      e.classes.add(DART_REMOVED);
    } else {
      for (Element el in e) {
        el.classes.add(DART_REMOVED);
      }
    }
  }
}

// TODO(jacobr): remove this when the dartium JSON parse handles \n correctly.
String JSONFIXUPHACK(String value) {
  return value.replaceAll("\n", "ZDARTIUMDOESNTESCAPESLASHNJXXXX");
}

String mozToWebkit(String name) {
  return name.replaceFirst(new RegExp("^moz"), "webkit");
}

String stripWebkit(String name) {
  return trimPrefix(name, "webkit");
}

// TODO(jacobr): be more principled about this.
String fullNameCleanup(String name) {
  int parenIndex = name.indexOf('(');
  if (parenIndex != -1) {
    name = name.substring(0, parenIndex);
  }
  name = name.split(" ")[0];
  name = name.split("\n")[0];
  name = name.split("\t")[0];
  name = name.split("*")[0];
  name = name.trim();
  name = safeNameCleanup(name);
  return name;
}

// Less agressive than the full name cleanup to avoid overeager matching.
// TODO(jacobr): be more principled about this.
String safeNameCleanup(String name) {
  int parenIndex = name.indexOf('(');
  if (parenIndex != -1 && name.indexOf(")") != -1) {
    // TODO(jacobr): workaround bug in:
    // name = name.split("(")[0];
    name = name.substring(0, parenIndex);
  }
  name = name.trim();
  name = trimPrefix(name, currentType + ".");
  name = trimPrefix(name, currentType.toLowerCase() + ".");
  name = trimPrefix(name, currentTypeShort + ".");
  name = trimPrefix(name, currentTypeShort.toLowerCase() + ".");
  name = trimPrefix(name, currentTypeTiny + ".");
  name = trimPrefix(name, currentTypeTiny.toLowerCase() + ".");
  name = name.trim();
  name = mozToWebkit(name);
  return name;
}

/**
 * Remove h1, h2, and h3 headers.
 */
void removeHeaders(DocumentFragment fragment) {
  for (Element e in fragment.queryAll("h1, h2, h3")) {
    e.remove();
  }
}

/**
 * Given an [entry] representing a single method or property cleanup the
 * values performing some simple normalization and only adding the entry to
 * [members] if it has a valid name.
 */
void cleanupEntry(List members, Map entry) {
  if (entry.containsKey('help')) {
    entry['help'] = trimHtml(entry['help']);
  }
  String name = fullNameCleanup(entry['name']);
  entry['name'] = name;
  if (maybeName(name)) {
    for (String key in entry.keys) {
      var value = entry[key];
      if (value == null) {
        entry.remove(key);
        continue;
      }
      if (value is String) {
        entry[key] = JSONFIXUPHACK(value);
      }
    }
    members.add(entry);
  }
}

// TODO(jacobr) dup with trim start....
String trimPrefix(String str, String prefix) {
  if (str.indexOf(prefix) == 0) {
    return str.substring(prefix.length);
  } else {
    return str;
  }
}

String trimStart(String str, String start) {
  if (str.startsWith(start) && str.length > start.length) {
    return str.substring(start.length);
  }
  return str;
}

String trimEnd(String str, String end) {
  if (str.endsWith(end) && str.length > end.length) {
    return str.substring(0, str.length - end.length);
  }
  return str;
}

/**
 * Extract a section with name [key] using [selector] to find start points for
 * the section in the document.
 */
void extractSection(String selector, String key) {
  for (Element e in document.queryAll(selector)) {
    e = e.parent;
    for (Element skip in e.queryAll("h1, h2, $IDL_SELECTOR")) {
      skip.remove();
    }
    String html = filteredHtml(e, e, null, removeHeaders).html;
    if (html.length > 0) {
      if (dbEntry.containsKey(key)) {
        dbEntry[key] += html;
      } else {
        dbEntry[key] = html;
      }
    }
    e.classes.add(DART_REMOVED);
  }
}

void run() {
  // Inject CSS to ensure lines don't wrap unless they were intended to.
  // This is needed to make the logic to determine what is a single line
  // behave consistently even for very long method names.
  document.head.nodes.add(new Element.html("""
<style type="text/css">
  body {
    width: 10000px;
  }
</style>"""));

  String title = trimEnd(window.document.title.trim(), " - MDN");
  dbEntry['title'] = title;

  // TODO(rnystrom): Clean up the page a bunch. Not sure if this is the best
  // place to do this...
  // TODO(jacobr): move this to right before we extract HTML.

  // Remove the "Introduced in HTML <version>" boxes.
  for (Element e in document.queryAll('.htmlVersionHeaderTemplate')) {
    e.remove();
  }

  // Flatten the list of known DOM types into a faster and case-insensitive
  // map.
  domTypes = {};
  for (final domType in domTypesRaw) {
    domTypes[domType.toLowerCase()] = domType;
  }

  // Fix up links.
  final SHORT_LINK = new RegExp(r'^[\w/]+$');
  final INNER_LINK = new RegExp(r'[Ee]n/(?:[\w/]+/|)([\w#.]+)(?:\(\))?$');
  final MEMBER_LINK = new RegExp(r'(\w+)[.#](\w+)');
  final RELATIVE_LINK = new RegExp(r'^(?:../)*/?[Ee][Nn]/(.+)');

  // - Make relative links absolute.
  // - If we can, take links that point to other MDN pages and retarget them
  //   to appropriate pages in our docs.
  // TODO(rnystrom): Add rel external to links we didn't fix.
  for (AnchorElement a in document.queryAll('a')) {
    // Get the raw attribute because we *don't* want the browser to fully-
    // qualify the name for us since it has the wrong base address for the
    // page.
    var href = a.attributes['href'];

    // Ignore busted links.
    if (href == null) continue;

    // If we can recognize what it's pointing to, point it to our page instead.
    tryToLinkToRealType(maybeType) {
      // See if we know a type with that name.
      final realType = domTypes[maybeType.toLowerCase()];
      if (realType != null) {
        href = '../html/$realType.html';
      }
    }

    // If it's a relative link (that we know how to root), make it absolute.
    var match = RELATIVE_LINK.firstMatch(href);
    if (match != null) {
      href = 'https://developer.mozilla.org/en/${match[1]}';
    }

    // If it's a word link like "foo" find a type or make it absolute.
    match = SHORT_LINK.firstMatch(href);
    if (match != null) {
      href = 'https://developer.mozilla.org/en/DOM/${match[0]}';
    }

    // TODO(rnystrom): This is a terrible way to do this. Should use the real
    // mapping from DOM names to html class names that we use elsewhere in the
    // DOM scripts.
    match = INNER_LINK.firstMatch(href);
    if (match != null) {
      // See if we're linking to a member ("type.name" or "type#name") or just
      // a type ("type").
      final member = MEMBER_LINK.firstMatch(match[1]);
      if (member != null) {
        tryToLinkToRealType(member[1]);
      } else {
        tryToLinkToRealType(match[1]);
      }
    }

    // Put it back into the element.
    a.attributes['href'] = href;
  }

  if (!title.toLowerCase().contains(currentTypeTiny.toLowerCase())) {
    bool foundMatch = false;
    // Test out if the title is really an HTML tag that matches the
    // current class name.
    for (String tag in [title.split(" ")[0], title.split(".").last]) {
      try {
        Element element = new Element.tag(tag);
        // TODO(jacobr): this is a really ugly way of doing this that will
        // stop working at some point soon.
        if (element.typeName == currentType) {
          foundMatch = true;
          break;
        }
      } catch (e) {}
    }
    if (!foundMatch) {
      dbEntry['skipped'] = true;
      dbEntry['cause'] = "Suspect title";
      onEnd();
      return;
    }
  }

  Element root = document.query(".pageText");
  if (root == null) {
    dbEntry['cause'] = '.pageText not found';
    onEnd();
    return;
  }

  markRemoved(root.query("#Notes"));
  List members = dbEntry['members'];

  // This is a laundry list of CSS selectors for boilerplate content on the
  // MDN pages that we should ignore for the purposes of extracting
  // documentation.
  markRemoved(document.queryAll(".pageToc, footer, header, #nav-toolbar"));
  markRemoved(document.queryAll("#article-nav"));
  markRemoved(document.queryAll(".hideforedit"));
  markRemoved(document.queryAll(".navbox"));
  markRemoved(document.query("#Method_overview"));
  markRemoved(document.queryAll("h1, h2"));

  scrapeSection(root, "#Methods", currentType, members, 'methods');
  scrapeSection(root, "#Constants, #Error_codes, #State_constants",
      currentType, members, 'constants');
  // TODO(jacobr): infer tables based on multiple matches rather than
  // using a hard coded list of section ids.
  scrapeSection(root,
      "[id^=Properties], #Notes, [id^=Other_properties], #Attributes, " +
      "#DOM_properties, #Event_handlers, #Event_Handlers",
      currentType, members, 'properties');

  // Avoid doing this till now to avoid messing up the section scrape.
  markRemoved(document.queryAll("h3"));

  ElementList examples = root.queryAll("span[id^=example], span[id^=Example]");

  extractSection("#See_also", 'seeAlso');
  extractSection("#Specification, #Specifications", "specification");

  // TODO(jacobr): actually extract the constructor(s)
  extractSection("#Constructor, #Constructors", 'constructor');
  extractSection("#Browser_compatibility, #Compatibility", 'compatibility');

  // Extract examples.
  List<String> exampleHtml = [];
  for (Element e in examples) {
    e.classes.add(DART_REMOVED);
  }
  for (Element e in examples) {
    String html = filteredHtml(e, root, null,
      (DocumentFragment fragment) {
        removeHeaders(fragment);
        if (fragment.text.trim().toLowerCase() == "example") {
          // Degenerate example.
          fragment.nodes.clear();
        }
      }).html;
    if (html.length > 0) {
      exampleHtml.add(html);
    }
  }
  if (exampleHtml.length > 0) {
    dbEntry['examples'] = exampleHtml;
  }

  // Extract the class summary.
  // Basically everything left over after the #Summary or #Description tag is
  // safe to include in the summary.
  StringBuffer summary = new StringBuffer();
  for (Element e in root.queryAll("#Summary, #Description")) {
    summary.write(filteredHtml(root, e, null, removeHeaders).html);
  }

  if (summary.length == 0) {
    // Remove the "Gecko DOM Reference text"
    Element ref = root.query(".lang.lang-en");
    if (ref != null) {
      ref = ref.parent;
      String refText = ref.text.trim();
      if (refText == "Gecko DOM Reference" ||
          refText == "« Gecko DOM Reference") {
        ref.remove();
      }
    }
    // Risky... this might add stuff we shouldn't.
    summary.write(filteredHtml(root, root, null, removeHeaders).html);
  }

  if (summary.length > 0) {
    dbEntry['summary'] = summary.toString();
  }

  // Inject CSS to aid debugging in the browser.
  // We could avoid doing this if we know we are not running in a browser..
  document.head.nodes.add(new Element.html(DEBUG_CSS));

  onEnd();
}

void main() {
  window.on.load.add(documentLoaded);
}

void documentLoaded(event) {
  // Load the database of expected methods and properties with an HttpRequest.
  new HttpRequest.get('${window.location}.json', (req) {
    data = json.parse(req.responseText);
    dbEntry = {'members': [], 'srcUrl': pageUrl};
    run();
  });
}
