Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(650)

Unified Diff: utils/apidoc/mdn/extract.dart

Issue 1361163002: remove docgen remnants from repo, update CHANGELOG (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: remove unused code Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « utils/apidoc/mdn/data/domTypes.json ('k') | utils/apidoc/mdn/extract.sh » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: utils/apidoc/mdn/extract.dart
diff --git a/utils/apidoc/mdn/extract.dart b/utils/apidoc/mdn/extract.dart
deleted file mode 100644
index 210e84cc208ecd3abd70afe226cc8eb10241e05e..0000000000000000000000000000000000000000
--- a/utils/apidoc/mdn/extract.dart
+++ /dev/null
@@ -1,1321 +0,0 @@
-// 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:convert';
-import 'dart:html';
-
-// 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.encode(dbEntry);
- // workaround bug in JSON.decode.
- 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.decode(req.responseText);
- dbEntry = {'members': [], 'srcUrl': pageUrl};
- run();
- });
-}
« no previous file with comments | « utils/apidoc/mdn/data/domTypes.json ('k') | utils/apidoc/mdn/extract.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698