joseph / Monocle

A silky, tactile browser-based ebook JavaScript library.
http://monocle.inventivelabs.com.au
MIT License
743 stars 200 forks source link

TOC navigation breaks when single xhtml with internal links #133

Closed gavrilis closed 11 years ago

gavrilis commented 11 years ago

Hi all,

I'm facing a problem with navigating across chapters using the TOC popover (I've tried chrome, firefox, safari). I can see the TOC correctly but nothing happens when I click on them. The problem seems to be affected by the fact that all chapters are defined as internal links within the same xhtml file.

I have only 1 xhtml file with all chapters defined as internal links: var bookData = { getComponents: function () { return [ 'OEBPS/Text/Section0001.xhtml#heading_id_5', 'OEBPS/Text/Section0001.xhtml#heading_id_6', 'OEBPS/Text/Section0001.xhtml#heading_id_7', ...

When I use separate files for each chapter, it seems to be working fine.

Any help will be appreciated. Dimitris.

aronwoost commented 11 years ago

Can you confirm that the Section0001.xhtml is correctly served with mime-type application/xhtml?

gavrilis commented 11 years ago

Firefox reports a type of: application/xhtml+xml

The index.html page header is: <?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

aronwoost commented 11 years ago

Ok.

I not sure if getComponents can be used for jumping to book positions. You might want to check the moveTo() method.

Like this:

reader.moveTo({ componentId: "Section0001.xhtml", anchor: "heading_id_5" });
joseph commented 11 years ago

Aron's right: you're confusing components for chapters. Your book has one component, and many chapters. Check the wiki on bookData objects for more details.

On 03/09/2012, at 7:48 PM, Aron Woost notifications@github.com wrote:

Ok.

I not sure if getComponents can be used for jumping to book positions. You might want to check the moveTo() method.

Like this:

reader.moveTo({ componentId: "Section0001.xhtml", anchor: "heading_id_5" }); — Reply to this email directly or view it on GitHub.

gavrilis commented 11 years ago

I think it is ok. Below you may see how my components and contents are defined. I have 1 xhtml which contains 19 items (chapters) that I want to navigate through the TOC.

getComponents: function () {
  return [
    'OEBPS/Text/Section0001.xhtml',
    'OEBPS/Text/Section0002.xhtml',
    'OEBPS/Text/Section0003.xhtml',
    'OEBPS/Text/Section0001.xhtml#heading_id_5',
    'OEBPS/Text/Section0001.xhtml#heading_id_6',
    'OEBPS/Text/Section0001.xhtml#heading_id_7',
    'OEBPS/Text/Section0001.xhtml#heading_id_8',
    'OEBPS/Text/Section0001.xhtml#heading_id_9',
    'OEBPS/Text/Section0001.xhtml#heading_id_10',
    'OEBPS/Text/Section0001.xhtml#heading_id_11',
    'OEBPS/Text/Section0001.xhtml#heading_id_12',
    'OEBPS/Text/Section0001.xhtml#heading_id_13',
    'OEBPS/Text/Section0001.xhtml#heading_id_14',
    'OEBPS/Text/Section0001.xhtml#heading_id_15',
    'OEBPS/Text/Section0001.xhtml#heading_id_16',
    'OEBPS/Text/Section0001.xhtml#heading_id_17',
    'OEBPS/Text/Section0001.xhtml#heading_id_18',
    'OEBPS/Text/Section0001.xhtml#heading_id_19'
  ];
},
getContents: function () {
  return [
    {
      title: "Μηνολόγιο",
      src: "OEBPS/Text/Section0001.xhtml"
    },
    {
      title: "Ιούνης",
      src: "OEBPS/Text/Section0002.xhtml"
    },
    {
      title: "Ιούλης",
      src: "OEBPS/Text/Section0003.xhtml"
    },
    {
      title: "Αυγουστής",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_5"
    },
    {
      title: "Σεπτέμβρης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_6"
    },
    {
      title: "Οκτώβρης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_7"
    },
    {
      title: "Νοέμβρης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_8"
    },
    {
      title: "Δεκέμβρης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_9"
    },
    {
      title: "Γενάρης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_10"
    },
    {
      title: "Φλεβάρης αρτιμελής (περίπου)",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_11"
    },
    {
      title: "Φλεβάρης χωλός",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_12"
    },
    {
      title: "Μάρτης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_13"
    },
    {
      title: "Απρίλης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_14"
    },
    {
      title: "Μάης",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_15"
    },
    {
      title: "Χρόνοι Δίσεχτοι",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_16"
    },
    {
      title: "Νηολόγιο",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_17"
    },
    {
      title: "Ποινολόγιο",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_18"
    },
    {
      title: "Όνειρο μέσα σε όνειρο",
      src: "OEBPS/Text/Section0001.xhtml#heading_id_19"
    }
  ]
},
gavrilis commented 11 years ago

So, do you think my configuration is ok ? It still doesn't work.

rubemz commented 11 years ago

Regarding the getComponents function it should return an array of all the component ids that are to be accessed in linear reading order.

So, I'd change it to:

getComponents: function () { return [ 'OEBPS/Text/Section0001.xhtml', 'OEBPS/Text/Section0002.xhtml', 'OEBPS/Text/Section0003.xhtml' ]; }

Since this is the reading order, as far as I could understand. Also, I don't think you need to specify anchors inside a section(.xhtml) as a component.

gavrilis commented 11 years ago

What I've done is map the epub's toc.ncx to getComponents() and getContents(). The toc.ncx is as follows:

<navMap>
    <navPoint id="navPoint-1" playOrder="1">
        <navLabel>
            <text>Μηνολόγιο</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_2"/>
    </navPoint>
    <navPoint id="navPoint-2" playOrder="2">
        <navLabel>
            <text>Ιούνης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_3"/>
    </navPoint>
    <navPoint id="navPoint-3" playOrder="3">
        <navLabel>
            <text>Ιούλης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_4"/>
    </navPoint>
    <navPoint id="navPoint-4" playOrder="4">
        <navLabel>
            <text>Αυγουστής</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_5"/>
    </navPoint>
    <navPoint id="navPoint-5" playOrder="5">
        <navLabel>
            <text>Σεπτέμβρης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_6"/>
    </navPoint>
    <navPoint id="navPoint-6" playOrder="6">
        <navLabel>
            <text>Οκτώβρης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_7"/>
    </navPoint>
    <navPoint id="navPoint-7" playOrder="7">
        <navLabel>
            <text>Νοέμβρης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_8"/>
    </navPoint>
    <navPoint id="navPoint-8" playOrder="8">
        <navLabel>
            <text>Δεκέμβρης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_9"/>
    </navPoint>
    <navPoint id="navPoint-9" playOrder="9">
        <navLabel>
            <text>Γενάρης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_10"/>
    </navPoint>
    <navPoint id="navPoint-10" playOrder="10">
        <navLabel>
            <text>Φλεβάρης αρτιμελής (περίπου)</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_11"/>
    </navPoint>
    <navPoint id="navPoint-11" playOrder="11">
        <navLabel>
            <text>Φλεβάρης χωλός</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_12"/>
    </navPoint>
    <navPoint id="navPoint-12" playOrder="12">
        <navLabel>
            <text>Μάρτης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_13"/>
    </navPoint>
    <navPoint id="navPoint-13" playOrder="13">
        <navLabel>
            <text>Απρίλης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_14"/>
    </navPoint>
    <navPoint id="navPoint-14" playOrder="14">
        <navLabel>
            <text>Μάης</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_15"/>
    </navPoint>
    <navPoint id="navPoint-15" playOrder="15">
        <navLabel>
            <text>Χρόνοι Δίσεχτοι</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_16"/>
    </navPoint>
    <navPoint id="navPoint-16" playOrder="16">
        <navLabel>
            <text>Νηολόγιο</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_17"/>
    </navPoint>
    <navPoint id="navPoint-17" playOrder="17">
        <navLabel>
            <text>Ποινολόγιο</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_18"/>
    </navPoint>
    <navPoint id="navPoint-18" playOrder="18">
        <navLabel>
            <text>Όνειρο μέσα σε όνειρο</text>
        </navLabel>
        <content src="Text/Section0001.xhtml#heading_id_19"/>
    </navPoint>
</navMap>
rubemz commented 11 years ago

Ok. But, based on the wiki:

getComponents: returns an array of all the component ids that are to be accessed in linear reading order (ie, like the spine in an EPUB OPF file — you don't have to list every component, just the ones that are read in order).

So, you should map the spine of the book to the getComponents. What you have put above seems the content of the ncx file (Navigation Control file for XML) - this one you may map to getContents, like you have done.

Take a look inside the spine inside the *.opf file and map it to getComponents. It should look like this:

<spine toc="ncx">
    <itemref idref="titlepage" />
    <itemref idref="historico-obra.xhtml" />
    <itemref idref="ficha-catalografica.xhtml" />
    <itemref idref="Section0001.xhtml" />
</spine>
rubemz commented 11 years ago

Anyway, not sure if this is the root cause of your issue. But, this seems one fix that you can do to your book data object :)

gavrilis commented 11 years ago

Well I tried mapping

to getComponents()

and then all chapters to getContents()

but it just doesnt' work.

rubemz commented 11 years ago

Could you somehow share your code or implementation? So that we could take a look on it.

joseph commented 11 years ago

Yep, it'd help if you can put it up somewhere.

The example at test/showcase/02-dickens/index.html includes a chapter using a hash fragment appended to the component href. If you can confirm that you can get to "Chapter II - The Ghost..." via the TOC in that demo, you could compare its implementation to your own.

gavrilis commented 11 years ago

Yes I actually created the epub -> monocle mapping based on this example. Unfortunately it just doesn't work. Please take a look at this example: http://xtek.gr/epub_test/13/

rubemz commented 11 years ago

Thanks for sharing.

The fix is replace this method (getComponents) on book.js

   getComponents: function () {
     return [
      'OEBPS/Text/Section0001.xhtml#heading_id_2',
      'OEBPS/Text/Section0001.xhtml#heading_id_3',
      'OEBPS/Text/Section0001.xhtml#heading_id_4',
      'OEBPS/Text/Section0001.xhtml#heading_id_5',
      'OEBPS/Text/Section0001.xhtml#heading_id_6',
      'OEBPS/Text/Section0001.xhtml#heading_id_7',
      'OEBPS/Text/Section0001.xhtml#heading_id_8',
      'OEBPS/Text/Section0001.xhtml#heading_id_9',
      'OEBPS/Text/Section0001.xhtml#heading_id_10',
      'OEBPS/Text/Section0001.xhtml#heading_id_11',
      'OEBPS/Text/Section0001.xhtml#heading_id_12',
      'OEBPS/Text/Section0001.xhtml#heading_id_13',
      'OEBPS/Text/Section0001.xhtml#heading_id_14',
      'OEBPS/Text/Section0001.xhtml#heading_id_15',
      'OEBPS/Text/Section0001.xhtml#heading_id_16',
      'OEBPS/Text/Section0001.xhtml#heading_id_17',
      'OEBPS/Text/Section0001.xhtml#heading_id_18',
      'OEBPS/Text/Section0001.xhtml#heading_id_19',
    ];

by this:


    getComponents: function () {
       return [
         'OEBPS/Text/Section0001.xhtml',
       ];  
     },  

It worked for me after this change. As I mentioned, the getComponents() should return each component listed in the epub spine, not an entry for every section inside a component.

gavrilis commented 11 years ago

Thank you so much. This seemed to be the problem. It works fine now !!!

joseph commented 11 years ago

Thanks @rubemz for solving this, and thanks @gavrilis for reporting back.

rubemz commented 11 years ago

@gavrilis @joseph You are welcome :D