From 55cd32bfaf9ed5bc5418751369e46fa1d7f098e8 Mon Sep 17 00:00:00 2001 From: Jesse Hallett Date: Mon, 6 Jan 2014 10:50:22 -0800 Subject: Moves rule files to src/ --- guidelines/wikipedia/bullets.js | 8 -- guidelines/wikipedia/color.js | 90 ---------------------- guidelines/wikipedia/floatSandwiches.js | 29 ------- guidelines/wikipedia/headingOrder.js | 47 ----------- guidelines/wikipedia/horizontalRule.js | 8 -- guidelines/wikipedia/imageAlt.js | 8 -- guidelines/wikipedia/imageCaption.js | 18 ----- guidelines/wikipedia/imageSize.js | 22 ------ guidelines/wikipedia/inlineStyle.js | 47 ----------- guidelines/wikipedia/layout.js | 7 -- guidelines/wikipedia/paragraphLength.js | 15 ---- guidelines/wikipedia/pseudoHeadings.js | 14 ---- guidelines/wikipedia/pseudoIndent.js | 10 --- guidelines/wikipedia/spaceBetweenListItems.js | 15 ---- guidelines/wikipedia/spaceBetweenParagraphs.js | 28 ------- guidelines/wikipedia/src/bullets.js | 8 ++ guidelines/wikipedia/src/color.js | 90 ++++++++++++++++++++++ guidelines/wikipedia/src/floatSandwiches.js | 29 +++++++ guidelines/wikipedia/src/headingOrder.js | 47 +++++++++++ guidelines/wikipedia/src/horizontalRule.js | 8 ++ guidelines/wikipedia/src/imageAlt.js | 8 ++ guidelines/wikipedia/src/imageCaption.js | 18 +++++ guidelines/wikipedia/src/imageSize.js | 23 ++++++ guidelines/wikipedia/src/inlineStyle.js | 47 +++++++++++ guidelines/wikipedia/src/layout.js | 7 ++ guidelines/wikipedia/src/paragraphLength.js | 15 ++++ guidelines/wikipedia/src/pseudoHeadings.js | 14 ++++ guidelines/wikipedia/src/pseudoIndent.js | 10 +++ guidelines/wikipedia/src/spaceBetweenListItems.js | 15 ++++ guidelines/wikipedia/src/spaceBetweenParagraphs.js | 28 +++++++ guidelines/wikipedia/src/strikeout.js | 14 ++++ guidelines/wikipedia/strikeout.js | 14 ---- guidelines/wikipedia/wikipedia.json | 30 ++++---- 33 files changed, 396 insertions(+), 395 deletions(-) delete mode 100644 guidelines/wikipedia/bullets.js delete mode 100644 guidelines/wikipedia/color.js delete mode 100644 guidelines/wikipedia/floatSandwiches.js delete mode 100644 guidelines/wikipedia/headingOrder.js delete mode 100644 guidelines/wikipedia/horizontalRule.js delete mode 100644 guidelines/wikipedia/imageAlt.js delete mode 100644 guidelines/wikipedia/imageCaption.js delete mode 100644 guidelines/wikipedia/imageSize.js delete mode 100644 guidelines/wikipedia/inlineStyle.js delete mode 100644 guidelines/wikipedia/layout.js delete mode 100644 guidelines/wikipedia/paragraphLength.js delete mode 100644 guidelines/wikipedia/pseudoHeadings.js delete mode 100644 guidelines/wikipedia/pseudoIndent.js delete mode 100644 guidelines/wikipedia/spaceBetweenListItems.js delete mode 100644 guidelines/wikipedia/spaceBetweenParagraphs.js create mode 100644 guidelines/wikipedia/src/bullets.js create mode 100644 guidelines/wikipedia/src/color.js create mode 100644 guidelines/wikipedia/src/floatSandwiches.js create mode 100644 guidelines/wikipedia/src/headingOrder.js create mode 100644 guidelines/wikipedia/src/horizontalRule.js create mode 100644 guidelines/wikipedia/src/imageAlt.js create mode 100644 guidelines/wikipedia/src/imageCaption.js create mode 100644 guidelines/wikipedia/src/imageSize.js create mode 100644 guidelines/wikipedia/src/inlineStyle.js create mode 100644 guidelines/wikipedia/src/layout.js create mode 100644 guidelines/wikipedia/src/paragraphLength.js create mode 100644 guidelines/wikipedia/src/pseudoHeadings.js create mode 100644 guidelines/wikipedia/src/pseudoIndent.js create mode 100644 guidelines/wikipedia/src/spaceBetweenListItems.js create mode 100644 guidelines/wikipedia/src/spaceBetweenParagraphs.js create mode 100644 guidelines/wikipedia/src/strikeout.js delete mode 100644 guidelines/wikipedia/strikeout.js diff --git a/guidelines/wikipedia/bullets.js b/guidelines/wikipedia/bullets.js deleted file mode 100644 index 80c5c4b..0000000 --- a/guidelines/wikipedia/bullets.js +++ /dev/null @@ -1,8 +0,0 @@ -exports.name = "Minimize use of bullet points"; -exports.description = "Bullet points should be minimized in the body and lead of the article, if they are used at all."; - -exports.rule = function(report) { - $5('#mw-content-text > ul, #mw-content-text > ol').each(function() { - report.warning('Minimize use of bullet points.', this); - }); -}; diff --git a/guidelines/wikipedia/color.js b/guidelines/wikipedia/color.js deleted file mode 100644 index b9eb31b..0000000 --- a/guidelines/wikipedia/color.js +++ /dev/null @@ -1,90 +0,0 @@ -exports.name = "Color use"; -exports.description = "Use colors that have sufficient contrast and avoid issues with common forms of color blindness."; - -var fc = fiveui.color; -var AA_NORMAL = 4.5; -var AA_BIG = 3; -var AAA_NORMAL = 7; -var AAA_BIG = 4.5; - - -/** - * Compute the font size in points, assuming 96dpi. - */ -var fontSizePt = function(elt) { - var px = $(elt).css('font-size'); - return parseInt(px) * 72 / 96; -}; - -var isBold = function(elt) { - return $(elt).css('font-weight') == 'bold'; -}; - -/** - * See if the text counts as "large scale" according to the W3C: - * (http://www.w3.org/TR/2008/REC-WCAG20-20081211/#larger-scaledef) - */ -var isLargeScale = function(elt) { - var size = fontSizePt(elt); - var bld = isBold(elt); - return (18 <= size || (14 <= size && bld)); -}; - -var getAARatio = function(elt) { - if (isLargeScale(elt)) { - return AA_BIG; - } - return AA_NORMAL; -}; - -var getAAARatio = function(elt) { - if (isLargeScale(elt)) { - return AAA_BIG; - } - return AAA_NORMAL; -}; - -exports.rule = function (report) { - - $5('#mw-content-text *') - // filter for lowest level elts having non-empty text - .filter(function () { - var $this = $(this); - return $this.children().length === 0 && $.trim($this.text()).length > 0; - }) - .filter(exceptions) - .each(function (i, elt) { - var fg = fc.colorToRGB($(this).css('color')); - var bg = fc.findBGColor($(this)); - if (fg && bg) { - var ratio = fc.contrast(fc.luminance(fg), fc.luminance(bg)); - if (ratio < getAARatio(elt)) { - report.error('Element has poor contrast: ' + ratio + - " ratio should be greater than " + getAARatio(elt), elt); - } else if (ratio < getAAARatio(elt)){ - report.warning('Element has poor contrast: ' + ratio + - " ratio should be greater than " + getAAARatio(elt), elt); - } - } - }); -}; - -function exceptions() { - var $elem = $(this); - return !isStandardLink($elem) && - !isNavboxLink($elem); -} - -function isStandardLink($elem) { - var standard = ['new', 'external', 'extiw']; - var $a = $elem.closest('a'); - return $a.is('a') && standard.some(function(klass) { - return $a.hasClass(klass); - }); -} - -function isNavboxLink($elem) { - var $a = $elem.closest('a'); - var $nav = $a.closest('th.navbox-group'); - return $a.length > 0 && $nav.length > 0; -} diff --git a/guidelines/wikipedia/floatSandwiches.js b/guidelines/wikipedia/floatSandwiches.js deleted file mode 100644 index ecdcdba..0000000 --- a/guidelines/wikipedia/floatSandwiches.js +++ /dev/null @@ -1,29 +0,0 @@ -exports.name = "Floating content on both sides of screen"; -exports.description = "Be careful not to add images or other floating content on both sides of the screen simultaneously."; - -exports.rule = function(report) { - var $topElems = $5('#mw-content-text > *'); - var left = floating($topElems, 'left').toArray().map($); - var right = floating($topElems, 'right').toArray().map($); - - left.forEach(function($l) { - var ltop = $l.offset().top; - var lbottom = ltop + $l.outerHeight(); - - if (right.some(function($r) { - var rtop = $r.offset().top; - var rbottom = rtop + $r.outerHeight(); - - return (rtop > ltop && rtop < lbottom) || - (rbottom > ltop && rbottom < lbottom); - })) { - report.warning('Left and right floating elements overlap vertically.', $l.get(0)); - } - }); -}; - -function floating($elems, leftOrRight) { - return $elems.filter(function() { - return $(this).css('float') === leftOrRight; - }); -} diff --git a/guidelines/wikipedia/headingOrder.js b/guidelines/wikipedia/headingOrder.js deleted file mode 100644 index dfb7777..0000000 --- a/guidelines/wikipedia/headingOrder.js +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Layout rules for Wikipedia article content - */ -exports.name = "Headings should be in order."; -exports.description = "Headers should increase sequentially, or reset to a higher section level."; - -exports.rule = function(report) { - findH1s(report); - - checkHeadingOrder(report); -}; - -/** - * No H1 headings should be used in the article content. - */ -var findH1s = function(report) { - $5('#mw-content-text h1').each( - function(idx, elt){ - report.error("Top-level headings should not be used in article content."); - }); -}; - - -/** - * Check that headers increase one step at a time, or go back to the - * beginning (in this case, heading 2). - * - * Headers using the <header> tag are except from this check. - */ -var checkHeadingOrder = function(report) { - var last=1; - - $5('#mw-content-text :header').each( - function(idx, elt){ - // parse the level out of 'h1', 'h2', 'h3', etc. - var level = parseInt(elt.tagName.substring(1,2)); - - if (level > (last + 1)) { - report.error("Heading is out of order; heading level was: "+level+ - " but last level was: "+last, elt); - } - // set the level regardless, since the error *could* be with the - // prior level heading, so we don't want to cause more errors - // erroniously: - last = level; - }); -}; diff --git a/guidelines/wikipedia/horizontalRule.js b/guidelines/wikipedia/horizontalRule.js deleted file mode 100644 index b16375d..0000000 --- a/guidelines/wikipedia/horizontalRule.js +++ /dev/null @@ -1,8 +0,0 @@ -exports.name = "Horizontal rules are deprecated"; -exports.description = "Horizontal rules (----) are deprecated."; - -exports.rule = function(report) { - $5('#mw-content-text hr').each(function(i, hr) { - report.warning('Remove horizontal rule.', hr); - }); -}; diff --git a/guidelines/wikipedia/imageAlt.js b/guidelines/wikipedia/imageAlt.js deleted file mode 100644 index c54244d..0000000 --- a/guidelines/wikipedia/imageAlt.js +++ /dev/null @@ -1,8 +0,0 @@ -exports.name = "Images should include an alt attribute"; -exports.description = "Images should include an alt attribute, even an empty one, that acts as a substitute for the image (for non-visual users)."; - -exports.rule = function(report) { - $5('#mw-content-text img:not([alt])').each(function(i, img) { - report.warning("Image has no alt attribute.", img); - }); -}; diff --git a/guidelines/wikipedia/imageCaption.js b/guidelines/wikipedia/imageCaption.js deleted file mode 100644 index 6212830..0000000 --- a/guidelines/wikipedia/imageCaption.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.name = "Images should contain a caption"; -exports.description = "Images should contain a caption, either using the built-in image syntax or a secondary line of text."; - -exports.rule = function(report) { - $5('#mw-content-text img') - // Exclude small images, which are probably icons. - .filter(function(i, img) { - var $img = $(img); - return $img.width() > 50 || $img.height() > 50; - }) - .each(function(i, img) { - var $parent = $(img).parents(':not(a, td, tr, .thumbimage):first'); - var text = $.trim($parent.text()); - if (!text) { - report.warning("Does this image have a caption?", img); - } - }); -}; diff --git a/guidelines/wikipedia/imageSize.js b/guidelines/wikipedia/imageSize.js deleted file mode 100644 index 38fef49..0000000 --- a/guidelines/wikipedia/imageSize.js +++ /dev/null @@ -1,22 +0,0 @@ -exports.name = "Large image"; -exports.description = "Images should be sized for comfortable display on the smallest displays in common use."; - -exports.rule = function(report) { - $5('#mw-content-text img').each(function() { - var $img = $(this); - if ($img.width() > 400 && !centered($img) && !locationNone($img)) { - report.warning('Image is more than 400px wide. Consider using the "center" or "none" location options for wide images', this); - } - if ($img.height() > 500) { - report.warning('Image is more than 500px tall.', this); - } - }); -}; - -function centered($img) { - return $img.closest('.center').length > 0; -} - -function locationNone($img) { - return !centered($img) && $img.closest('.tnone').length > 0; -} diff --git a/guidelines/wikipedia/inlineStyle.js b/guidelines/wikipedia/inlineStyle.js deleted file mode 100644 index 261586d..0000000 --- a/guidelines/wikipedia/inlineStyle.js +++ /dev/null @@ -1,47 +0,0 @@ -exports.name = "Do not use in-line styles"; -exports.description = "In-line styles make it much harder for people with specific needs to change the wikimedia styles and to retain consistency."; - -exports.rule = function(report) { - $5('#mw-content-text [style]').filter(excludes).each(function(i, elem) { - report.error("Element contains in-line style rules.", elem); - }); -}; - -function excludes(i, elem) { - var $elem = $(elem); - - // Ignore width rules. - var widthRule = everyStyle($elem, function(s) { - return s === 'width'; - }); - - // It seems that Wikipedia's standard table templates include some - // inline styles. Ignore these. - var table = $elem.is('table, th, td'); - - // The standard reference list template also seems to include some - // inline styles. - var reference = $elem.hasClass('reflist references-column-width') || - $elem.hasClass('error') || - ($elem.is('.citation ~ * *') && !$.trim($elem.text())); //   - - // The [citation needed] template includes a white-space:nowrap style. - var citationNeeded = $elem.hasClass('Template-Fact') && everyStyle($elem, function(s) { - return s === 'white-space'; - }); - - var navboxPadding = $elem.closest('.navbox').length > 0 && everyStyle($elem, function(s) { - return s.slice(0,7) === 'padding'; - }); - - // Ignore hidden microformat fields. - var microformat = $elem.css('display') === 'none' && - $elem.closest('.vcard, .vevent').length > 0; - - return !widthRule && !table && !reference && !citationNeeded && - !navboxPadding && !microformat; -} - -function everyStyle($elem, fn) { - return Array.prototype.every.call($elem.prop('style'), fn); -} diff --git a/guidelines/wikipedia/layout.js b/guidelines/wikipedia/layout.js deleted file mode 100644 index 6139de3..0000000 --- a/guidelines/wikipedia/layout.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Layout rules for Wikipedia article content - */ -exports.name = "Layout rules for headings"; -exports.description = ""; - -exports.rule = function(report) { diff --git a/guidelines/wikipedia/paragraphLength.js b/guidelines/wikipedia/paragraphLength.js deleted file mode 100644 index ba20306..0000000 --- a/guidelines/wikipedia/paragraphLength.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.name = "Avoid single-sentence paragraphs"; -exports.description = "The number of single-sentence paragraphs should be minimized."; - -exports.rule = function(report) { - var sentenceBoundary = /[.?!](?:(?:\[\d+\])|['"])*(?:\s|$)/gm; - - $5('#mw-content-text p').each(function(i, p) { - var $p = $(p); - var text = $.trim($p.text()); - var boundaries = text && text.match(sentenceBoundary); - if (boundaries && boundaries.length === 1) { - report.warning('Paragraph with only one sentence: "' + text +'"', p); - } - }); -}; diff --git a/guidelines/wikipedia/pseudoHeadings.js b/guidelines/wikipedia/pseudoHeadings.js deleted file mode 100644 index bbf7d8d..0000000 --- a/guidelines/wikipedia/pseudoHeadings.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.name = "Do not make pseudo-headings"; -exports.description = "Do not make pseudo-headings using bold or semicolon markup."; - -exports.rule = function(report) { - $5('#mw-content-text p > b:only-child').each(function(i, b) { - var text = $.trim($(b).text()); - report.error('Bold text used as pseudo-heading: '+ text, b); - }); - - $5('#mw-content-text dl:not(:has(dd)) dt').each(function(i, dt) { - var text = $.trim($(dt).text()); - report.error('Semicolon markup used to create pseudo-heading: '+ text, dt); - }); -}; diff --git a/guidelines/wikipedia/pseudoIndent.js b/guidelines/wikipedia/pseudoIndent.js deleted file mode 100644 index 73b1700..0000000 --- a/guidelines/wikipedia/pseudoIndent.js +++ /dev/null @@ -1,10 +0,0 @@ -exports.name = "Do not use colon markup for indentation"; -exports.description = "Preceding text with a colon (:) in wiki markup causes that text to appear to be indented; but the actual result is a definition list with one item without a title."; - -exports.rule = function(report) { - $5('#mw-content-text dl:not(:has(dt)) dd').each(function(i, dd) { - var text = $.trim($(dd).text()); - report.error('Colon markup used to indent text: '+ text, dd); - }); -}; - diff --git a/guidelines/wikipedia/spaceBetweenListItems.js b/guidelines/wikipedia/spaceBetweenListItems.js deleted file mode 100644 index 890b31c..0000000 --- a/guidelines/wikipedia/spaceBetweenListItems.js +++ /dev/null @@ -1,15 +0,0 @@ -exports.name = "Do not separate list items with blank lines"; -exports.description = "Leaving blank lines between list items causes mediawiki to end one list and to start a new one."; - -exports.rule = function(report) { - $5('ol:has(> li:only-of-type) + ol:has(> li:only-of-type)').each(reportWarning); - $5('ul:has(> li:only-of-type) + ul:has(> li:only-of-type)').each(reportWarning); - - $5('dl:has(> dt:only-of-type):has(> dd:only-of-type) + '+ - 'dl:has(> dt:only-of-type):has(> dd:only-of-type)').each(reportWarning); - - function reportWarning(i, list) { - var text = $.trim($(list).text()); - report.warning('List with a single item: '+ text, list); - } -}; diff --git a/guidelines/wikipedia/spaceBetweenParagraphs.js b/guidelines/wikipedia/spaceBetweenParagraphs.js deleted file mode 100644 index ccab3a4..0000000 --- a/guidelines/wikipedia/spaceBetweenParagraphs.js +++ /dev/null @@ -1,28 +0,0 @@ -exports.name = "There should only be one blank line between paragraphs"; -exports.description = "Between sections - as between sections - there should be only a single blank line."; - -exports.rule = function(report) { - var problemPs = []; - - $5('p:has(> br)').each(function(i, p) { - var $p = $(p), prevP; - if ($.trim($p.text()).length === 0) { - prevP = $p.prevAll('p').filter(function(i, pp) { - return $.trim($(pp).text()).length > 0; - }).first(); - - if (prevP.length) { - problemPs.push(prevP.get(0)); - } - else { - report.error('Paragraph contains line breaks but does not contain text.', p); - } - } - }); - - _.uniq(problemPs, false).forEach(function(p) { - var text = $.trim($(p).text()); - report.error('Paragraph is followed by more than one blank line: '+ text, p); - }); -}; - diff --git a/guidelines/wikipedia/src/bullets.js b/guidelines/wikipedia/src/bullets.js new file mode 100644 index 0000000..80c5c4b --- /dev/null +++ b/guidelines/wikipedia/src/bullets.js @@ -0,0 +1,8 @@ +exports.name = "Minimize use of bullet points"; +exports.description = "Bullet points should be minimized in the body and lead of the article, if they are used at all."; + +exports.rule = function(report) { + $5('#mw-content-text > ul, #mw-content-text > ol').each(function() { + report.warning('Minimize use of bullet points.', this); + }); +}; diff --git a/guidelines/wikipedia/src/color.js b/guidelines/wikipedia/src/color.js new file mode 100644 index 0000000..b9eb31b --- /dev/null +++ b/guidelines/wikipedia/src/color.js @@ -0,0 +1,90 @@ +exports.name = "Color use"; +exports.description = "Use colors that have sufficient contrast and avoid issues with common forms of color blindness."; + +var fc = fiveui.color; +var AA_NORMAL = 4.5; +var AA_BIG = 3; +var AAA_NORMAL = 7; +var AAA_BIG = 4.5; + + +/** + * Compute the font size in points, assuming 96dpi. + */ +var fontSizePt = function(elt) { + var px = $(elt).css('font-size'); + return parseInt(px) * 72 / 96; +}; + +var isBold = function(elt) { + return $(elt).css('font-weight') == 'bold'; +}; + +/** + * See if the text counts as "large scale" according to the W3C: + * (http://www.w3.org/TR/2008/REC-WCAG20-20081211/#larger-scaledef) + */ +var isLargeScale = function(elt) { + var size = fontSizePt(elt); + var bld = isBold(elt); + return (18 <= size || (14 <= size && bld)); +}; + +var getAARatio = function(elt) { + if (isLargeScale(elt)) { + return AA_BIG; + } + return AA_NORMAL; +}; + +var getAAARatio = function(elt) { + if (isLargeScale(elt)) { + return AAA_BIG; + } + return AAA_NORMAL; +}; + +exports.rule = function (report) { + + $5('#mw-content-text *') + // filter for lowest level elts having non-empty text + .filter(function () { + var $this = $(this); + return $this.children().length === 0 && $.trim($this.text()).length > 0; + }) + .filter(exceptions) + .each(function (i, elt) { + var fg = fc.colorToRGB($(this).css('color')); + var bg = fc.findBGColor($(this)); + if (fg && bg) { + var ratio = fc.contrast(fc.luminance(fg), fc.luminance(bg)); + if (ratio < getAARatio(elt)) { + report.error('Element has poor contrast: ' + ratio + + " ratio should be greater than " + getAARatio(elt), elt); + } else if (ratio < getAAARatio(elt)){ + report.warning('Element has poor contrast: ' + ratio + + " ratio should be greater than " + getAAARatio(elt), elt); + } + } + }); +}; + +function exceptions() { + var $elem = $(this); + return !isStandardLink($elem) && + !isNavboxLink($elem); +} + +function isStandardLink($elem) { + var standard = ['new', 'external', 'extiw']; + var $a = $elem.closest('a'); + return $a.is('a') && standard.some(function(klass) { + return $a.hasClass(klass); + }); +} + +function isNavboxLink($elem) { + var $a = $elem.closest('a'); + var $nav = $a.closest('th.navbox-group'); + return $a.length > 0 && $nav.length > 0; +} diff --git a/guidelines/wikipedia/src/floatSandwiches.js b/guidelines/wikipedia/src/floatSandwiches.js new file mode 100644 index 0000000..ecdcdba --- /dev/null +++ b/guidelines/wikipedia/src/floatSandwiches.js @@ -0,0 +1,29 @@ +exports.name = "Floating content on both sides of screen"; +exports.description = "Be careful not to add images or other floating content on both sides of the screen simultaneously."; + +exports.rule = function(report) { + var $topElems = $5('#mw-content-text > *'); + var left = floating($topElems, 'left').toArray().map($); + var right = floating($topElems, 'right').toArray().map($); + + left.forEach(function($l) { + var ltop = $l.offset().top; + var lbottom = ltop + $l.outerHeight(); + + if (right.some(function($r) { + var rtop = $r.offset().top; + var rbottom = rtop + $r.outerHeight(); + + return (rtop > ltop && rtop < lbottom) || + (rbottom > ltop && rbottom < lbottom); + })) { + report.warning('Left and right floating elements overlap vertically.', $l.get(0)); + } + }); +}; + +function floating($elems, leftOrRight) { + return $elems.filter(function() { + return $(this).css('float') === leftOrRight; + }); +} diff --git a/guidelines/wikipedia/src/headingOrder.js b/guidelines/wikipedia/src/headingOrder.js new file mode 100644 index 0000000..dfb7777 --- /dev/null +++ b/guidelines/wikipedia/src/headingOrder.js @@ -0,0 +1,47 @@ +/** + * Layout rules for Wikipedia article content + */ +exports.name = "Headings should be in order."; +exports.description = "Headers should increase sequentially, or reset to a higher section level."; + +exports.rule = function(report) { + findH1s(report); + + checkHeadingOrder(report); +}; + +/** + * No H1 headings should be used in the article content. + */ +var findH1s = function(report) { + $5('#mw-content-text h1').each( + function(idx, elt){ + report.error("Top-level headings should not be used in article content."); + }); +}; + + +/** + * Check that headers increase one step at a time, or go back to the + * beginning (in this case, heading 2). + * + * Headers using the <header> tag are except from this check. + */ +var checkHeadingOrder = function(report) { + var last=1; + + $5('#mw-content-text :header').each( + function(idx, elt){ + // parse the level out of 'h1', 'h2', 'h3', etc. + var level = parseInt(elt.tagName.substring(1,2)); + + if (level > (last + 1)) { + report.error("Heading is out of order; heading level was: "+level+ + " but last level was: "+last, elt); + } + // set the level regardless, since the error *could* be with the + // prior level heading, so we don't want to cause more errors + // erroniously: + last = level; + }); +}; diff --git a/guidelines/wikipedia/src/horizontalRule.js b/guidelines/wikipedia/src/horizontalRule.js new file mode 100644 index 0000000..b16375d --- /dev/null +++ b/guidelines/wikipedia/src/horizontalRule.js @@ -0,0 +1,8 @@ +exports.name = "Horizontal rules are deprecated"; +exports.description = "Horizontal rules (----) are deprecated."; + +exports.rule = function(report) { + $5('#mw-content-text hr').each(function(i, hr) { + report.warning('Remove horizontal rule.', hr); + }); +}; diff --git a/guidelines/wikipedia/src/imageAlt.js b/guidelines/wikipedia/src/imageAlt.js new file mode 100644 index 0000000..c54244d --- /dev/null +++ b/guidelines/wikipedia/src/imageAlt.js @@ -0,0 +1,8 @@ +exports.name = "Images should include an alt attribute"; +exports.description = "Images should include an alt attribute, even an empty one, that acts as a substitute for the image (for non-visual users)."; + +exports.rule = function(report) { + $5('#mw-content-text img:not([alt])').each(function(i, img) { + report.warning("Image has no alt attribute.", img); + }); +}; diff --git a/guidelines/wikipedia/src/imageCaption.js b/guidelines/wikipedia/src/imageCaption.js new file mode 100644 index 0000000..6212830 --- /dev/null +++ b/guidelines/wikipedia/src/imageCaption.js @@ -0,0 +1,18 @@ +exports.name = "Images should contain a caption"; +exports.description = "Images should contain a caption, either using the built-in image syntax or a secondary line of text."; + +exports.rule = function(report) { + $5('#mw-content-text img') + // Exclude small images, which are probably icons. + .filter(function(i, img) { + var $img = $(img); + return $img.width() > 50 || $img.height() > 50; + }) + .each(function(i, img) { + var $parent = $(img).parents(':not(a, td, tr, .thumbimage):first'); + var text = $.trim($parent.text()); + if (!text) { + report.warning("Does this image have a caption?", img); + } + }); +}; diff --git a/guidelines/wikipedia/src/imageSize.js b/guidelines/wikipedia/src/imageSize.js new file mode 100644 index 0000000..52b5a3e --- /dev/null +++ b/guidelines/wikipedia/src/imageSize.js @@ -0,0 +1,23 @@ +exports.name = "Large image"; +exports.description = "Images should be sized for comfortable display on the smallest displays in common use."; + +exports.rule = function(report) { + $5('#mw-content-text img').each(function() { + var $img = $(this); + if ($img.width() > 400 && !centered($img) && !locationNone($img)) { + report.warning('Image is more than 400px wide. Consider using the "center" or "none" location options for wide images', this); + } + if ($img.height() > 500) { + report.warning('Image is more than 500px tall.', this); + } + }); +}; + +// Add to prelude. +function centered($img) { + return $img.closest('.center').length > 0; +} + +function locationNone($img) { + return !centered($img) && $img.closest('.tnone').length > 0; +} diff --git a/guidelines/wikipedia/src/inlineStyle.js b/guidelines/wikipedia/src/inlineStyle.js new file mode 100644 index 0000000..261586d --- /dev/null +++ b/guidelines/wikipedia/src/inlineStyle.js @@ -0,0 +1,47 @@ +exports.name = "Do not use in-line styles"; +exports.description = "In-line styles make it much harder for people with specific needs to change the wikimedia styles and to retain consistency."; + +exports.rule = function(report) { + $5('#mw-content-text [style]').filter(excludes).each(function(i, elem) { + report.error("Element contains in-line style rules.", elem); + }); +}; + +function excludes(i, elem) { + var $elem = $(elem); + + // Ignore width rules. + var widthRule = everyStyle($elem, function(s) { + return s === 'width'; + }); + + // It seems that Wikipedia's standard table templates include some + // inline styles. Ignore these. + var table = $elem.is('table, th, td'); + + // The standard reference list template also seems to include some + // inline styles. + var reference = $elem.hasClass('reflist references-column-width') || + $elem.hasClass('error') || + ($elem.is('.citation ~ * *') && !$.trim($elem.text())); //   + + // The [citation needed] template includes a white-space:nowrap style. + var citationNeeded = $elem.hasClass('Template-Fact') && everyStyle($elem, function(s) { + return s === 'white-space'; + }); + + var navboxPadding = $elem.closest('.navbox').length > 0 && everyStyle($elem, function(s) { + return s.slice(0,7) === 'padding'; + }); + + // Ignore hidden microformat fields. + var microformat = $elem.css('display') === 'none' && + $elem.closest('.vcard, .vevent').length > 0; + + return !widthRule && !table && !reference && !citationNeeded && + !navboxPadding && !microformat; +} + +function everyStyle($elem, fn) { + return Array.prototype.every.call($elem.prop('style'), fn); +} diff --git a/guidelines/wikipedia/src/layout.js b/guidelines/wikipedia/src/layout.js new file mode 100644 index 0000000..48896fe --- /dev/null +++ b/guidelines/wikipedia/src/layout.js @@ -0,0 +1,7 @@ +/** + * Layout rules for Wikipedia article content + */ +exports.name = "Layout rules for headings"; +exports.description = ""; + +exports.rule = function(report) {}; diff --git a/guidelines/wikipedia/src/paragraphLength.js b/guidelines/wikipedia/src/paragraphLength.js new file mode 100644 index 0000000..ba20306 --- /dev/null +++ b/guidelines/wikipedia/src/paragraphLength.js @@ -0,0 +1,15 @@ +exports.name = "Avoid single-sentence paragraphs"; +exports.description = "The number of single-sentence paragraphs should be minimized."; + +exports.rule = function(report) { + var sentenceBoundary = /[.?!](?:(?:\[\d+\])|['"])*(?:\s|$)/gm; + + $5('#mw-content-text p').each(function(i, p) { + var $p = $(p); + var text = $.trim($p.text()); + var boundaries = text && text.match(sentenceBoundary); + if (boundaries && boundaries.length === 1) { + report.warning('Paragraph with only one sentence: "' + text +'"', p); + } + }); +}; diff --git a/guidelines/wikipedia/src/pseudoHeadings.js b/guidelines/wikipedia/src/pseudoHeadings.js new file mode 100644 index 0000000..bbf7d8d --- /dev/null +++ b/guidelines/wikipedia/src/pseudoHeadings.js @@ -0,0 +1,14 @@ +exports.name = "Do not make pseudo-headings"; +exports.description = "Do not make pseudo-headings using bold or semicolon markup."; + +exports.rule = function(report) { + $5('#mw-content-text p > b:only-child').each(function(i, b) { + var text = $.trim($(b).text()); + report.error('Bold text used as pseudo-heading: '+ text, b); + }); + + $5('#mw-content-text dl:not(:has(dd)) dt').each(function(i, dt) { + var text = $.trim($(dt).text()); + report.error('Semicolon markup used to create pseudo-heading: '+ text, dt); + }); +}; diff --git a/guidelines/wikipedia/src/pseudoIndent.js b/guidelines/wikipedia/src/pseudoIndent.js new file mode 100644 index 0000000..73b1700 --- /dev/null +++ b/guidelines/wikipedia/src/pseudoIndent.js @@ -0,0 +1,10 @@ +exports.name = "Do not use colon markup for indentation"; +exports.description = "Preceding text with a colon (:) in wiki markup causes that text to appear to be indented; but the actual result is a definition list with one item without a title."; + +exports.rule = function(report) { + $5('#mw-content-text dl:not(:has(dt)) dd').each(function(i, dd) { + var text = $.trim($(dd).text()); + report.error('Colon markup used to indent text: '+ text, dd); + }); +}; + diff --git a/guidelines/wikipedia/src/spaceBetweenListItems.js b/guidelines/wikipedia/src/spaceBetweenListItems.js new file mode 100644 index 0000000..890b31c --- /dev/null +++ b/guidelines/wikipedia/src/spaceBetweenListItems.js @@ -0,0 +1,15 @@ +exports.name = "Do not separate list items with blank lines"; +exports.description = "Leaving blank lines between list items causes mediawiki to end one list and to start a new one."; + +exports.rule = function(report) { + $5('ol:has(> li:only-of-type) + ol:has(> li:only-of-type)').each(reportWarning); + $5('ul:has(> li:only-of-type) + ul:has(> li:only-of-type)').each(reportWarning); + + $5('dl:has(> dt:only-of-type):has(> dd:only-of-type) + '+ + 'dl:has(> dt:only-of-type):has(> dd:only-of-type)').each(reportWarning); + + function reportWarning(i, list) { + var text = $.trim($(list).text()); + report.warning('List with a single item: '+ text, list); + } +}; diff --git a/guidelines/wikipedia/src/spaceBetweenParagraphs.js b/guidelines/wikipedia/src/spaceBetweenParagraphs.js new file mode 100644 index 0000000..ccab3a4 --- /dev/null +++ b/guidelines/wikipedia/src/spaceBetweenParagraphs.js @@ -0,0 +1,28 @@ +exports.name = "There should only be one blank line between paragraphs"; +exports.description = "Between sections - as between sections - there should be only a single blank line."; + +exports.rule = function(report) { + var problemPs = []; + + $5('p:has(> br)').each(function(i, p) { + var $p = $(p), prevP; + if ($.trim($p.text()).length === 0) { + prevP = $p.prevAll('p').filter(function(i, pp) { + return $.trim($(pp).text()).length > 0; + }).first(); + + if (prevP.length) { + problemPs.push(prevP.get(0)); + } + else { + report.error('Paragraph contains line breaks but does not contain text.', p); + } + } + }); + + _.uniq(problemPs, false).forEach(function(p) { + var text = $.trim($(p).text()); + report.error('Paragraph is followed by more than one blank line: '+ text, p); + }); +}; + diff --git a/guidelines/wikipedia/src/strikeout.js b/guidelines/wikipedia/src/strikeout.js new file mode 100644 index 0000000..e1e3856 --- /dev/null +++ b/guidelines/wikipedia/src/strikeout.js @@ -0,0 +1,14 @@ +exports.name = "Don't use strikeout."; +exports.description = "By default, most screen readers do not indicate presentational text attributes (bold, italic, underline) or even semantic text attributes (emphasis, importance, text deletion), so struck-out text is read normally along with any other text."; + +exports.rule = function (report) { + var err = function(idx, elt) { + report.error("Strikeout tags should not be used.", elt); + }; + + $5('#mw-content-text del').each(err); + $5('#mw-content-text strike').each(err); + $5('#mw-content-text span').filter(function(i, s) { + return (/line-through/).test($(s).css('text-decoration')); + }).each(err); +}; diff --git a/guidelines/wikipedia/strikeout.js b/guidelines/wikipedia/strikeout.js deleted file mode 100644 index e1e3856..0000000 --- a/guidelines/wikipedia/strikeout.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.name = "Don't use strikeout."; -exports.description = "By default, most screen readers do not indicate presentational text attributes (bold, italic, underline) or even semantic text attributes (emphasis, importance, text deletion), so struck-out text is read normally along with any other text."; - -exports.rule = function (report) { - var err = function(idx, elt) { - report.error("Strikeout tags should not be used.", elt); - }; - - $5('#mw-content-text del').each(err); - $5('#mw-content-text strike').each(err); - $5('#mw-content-text span').filter(function(i, s) { - return (/line-through/).test($(s).css('text-decoration')); - }).each(err); -}; diff --git a/guidelines/wikipedia/wikipedia.json b/guidelines/wikipedia/wikipedia.json index e6030ac..166bec6 100644 --- a/guidelines/wikipedia/wikipedia.json +++ b/guidelines/wikipedia/wikipedia.json @@ -2,20 +2,20 @@ , "description": "Guidelines published by wikipedia for authors creating or editing wiki pages." , "license": "BSD3" , "rules": - [ "headingOrder.js" - , "bullets.js" - , "strikeout.js" - , "color.js" - , "spaceBetweenParagraphs.js" - , "paragraphLength.js" - , "imageSize.js" - , "horizontalRule.js" - , "pseudoHeadings.js" - , "pseudoIndent.js" - , "floatSandwiches.js" - , "spaceBetweenListItems.js" - , "imageAlt.js" - , "imageCaption.js" - , "inlineStyle.js" + [ "src/headingOrder.js" + , "src/bullets.js" + , "src/strikeout.js" + , "src/color.js" + , "src/spaceBetweenParagraphs.js" + , "src/paragraphLength.js" + , "src/imageSize.js" + , "src/horizontalRule.js" + , "src/pseudoHeadings.js" + , "src/pseudoIndent.js" + , "src/floatSandwiches.js" + , "src/spaceBetweenListItems.js" + , "src/imageAlt.js" + , "src/imageCaption.js" + , "src/inlineStyle.js" ] } -- cgit v1.2.3