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 Iterable<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();
  });
}
