Commit 5c90fba3 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Correctly handle unicode in anchors.

URL-encode all unicode characters.

Fixes #397
parent 3ff90c44
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
require 'cgi'

module JsDuck

  # Transforms in-page links so they won't break docs app #!-navigation.
@@ -9,7 +11,7 @@ module JsDuck

    def self.transform(html, guide_name)
      html.gsub(/(<a\s+(?:[^<>]*\s+)?href=['"]#)([^!\/].*?)(['"])/i) do |m|
        "#{$1}!/guide/#{guide_name}-section-#{$2}#{$3}"
        $1 + "!/guide/" + transform_id($2, guide_name) + $3

      end.gsub(/(<a\s+(?:[^<>]*\s+)?name=['"])(.*?)(['"])/i) do |m|
        $1 + transform_id($2, guide_name) + $3
@@ -23,6 +25,11 @@ module JsDuck
      if id =~ /^#{guide_name}-section-/
        id
      else
        # Escape the ID if it's not already escaped.  This check is
        # needed to avoid re-escaping anchor-links created with
        # Markdown - these get auto-escaped by RDiscount.
        id = (id =~ /%[0-9A-F]{2}/) ? id : CGI::escape(id)

        "#{guide_name}-section-#{id}"
      end
    end
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ module JsDuck
    end

    def self.title_to_id(title)
      title.downcase.gsub(/[^\w]+/, "-")
      CGI::escape(title.downcase.gsub(/ /, "-"))
    end

  end
+16 −0
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
require "jsduck/guide_anchors"

describe JsDuck::GuideAnchors do
@@ -21,6 +22,11 @@ describe JsDuck::GuideAnchors do
      "Some\nlong\ntext\nhere...\n\n <a href='#!/guide/myguide-section-blah'>label</a>"
  end

  it "URL-encodes unicode anchors links" do
    transform("<a href='#fäg'>label</a>").should ==
      "<a href='#!/guide/myguide-section-f%C3%A4g'>label</a>"
  end

  it "doesn't transform normal links" do
    transform("<a href='http://example.com'>label</a>").should ==
      "<a href='http://example.com'>label</a>"
@@ -41,6 +47,11 @@ describe JsDuck::GuideAnchors do
      "<a name='myguide-section-blah'>target</a>"
  end

  it "URL-encodes unicode in anchors" do
    transform("<a name='fäg'>target</a>").should ==
      "<a name='myguide-section-f%C3%A4g'>target</a>"
  end

  it "doesn't transform anchors already in target format" do
    transform("<a name='myguide-section-blah'>target</a>").should ==
      "<a name='myguide-section-blah'>target</a>"
@@ -51,6 +62,11 @@ describe JsDuck::GuideAnchors do
      "<h1 id='myguide-section-blah'>target</h1>"
  end

  it "URL-encodes unicode in ID-s" do
    transform("<h1 id='fäg'>target</h1>").should ==
      "<h1 id='myguide-section-f%C3%A4g'>target</h1>"
  end

  it "doesn't transform ID-s already in target format" do
    transform("<h1 id='myguide-section-blah'>target</h1>").should ==
      "<h1 id='myguide-section-blah'>target</h1>"
+14 −0
Original line number Diff line number Diff line
# -*- coding: utf-8 -*-
require "jsduck/guide_toc"

describe JsDuck::GuideToc do
@@ -30,6 +31,12 @@ describe JsDuck::GuideToc do
    EOHTML
  end

  it "URL-encodes unicode in heading ID-s" do
    inject(<<-EOHTML).should =~ /<h2 id='myguide-section-my-f%C3%A4pter'>My Fäpter/
      <h2>My Fäpter</h2>
    EOHTML
  end

  it "links to headings from TOC" do
    inject(<<-EOHTML).should =~ /<a href='#!\/guide\/myguide-section-my-chapter'>/
      <h2>My Chapter</h2>
@@ -37,6 +44,13 @@ describe JsDuck::GuideToc do
    EOHTML
  end

  it "links to unicode headings from TOC" do
    inject(<<-EOHTML).should =~ /<a href='#!\/guide\/myguide-section-my-f%C3%A4pter'>/
      <h2>My Fäpter</h2>
      <h2>Another Fäpter</h2>
    EOHTML
  end

  it "adds ID-s to H2 headings even when no TOC" do
    inject(<<-EOHTML).should =~ /<h2 id='myguide-section-my-chapter'>My Chapter/
      <h2>My Chapter</h2>