├── .bowerrc ├── locales ├── zh_CN │ └── ns.viewerMHTML.json ├── ja │ └── ns.viewerMHTML.json ├── ar │ └── ns.viewerMHTML.json ├── ca │ └── ns.viewerMHTML.json ├── el │ └── ns.viewerMHTML.json ├── ko │ └── ns.viewerMHTML.json ├── sv │ └── ns.viewerMHTML.json ├── uk │ └── ns.viewerMHTML.json ├── nl_NL │ └── ns.viewerMHTML.json ├── zh_TW │ └── ns.viewerMHTML.json ├── id_ID │ └── ns.viewerMHTML.json ├── pt_BR │ └── ns.viewerMHTML.json ├── sk_SK │ └── ns.viewerMHTML.json ├── it │ └── ns.viewerMHTML.json ├── cs │ └── ns.viewerMHTML.json ├── pt_PT │ └── ns.viewerMHTML.json ├── es │ └── ns.viewerMHTML.json ├── pl │ └── ns.viewerMHTML.json ├── fr │ └── ns.viewerMHTML.json ├── ru │ └── ns.viewerMHTML.json ├── bg │ └── ns.viewerMHTML.json ├── hu │ └── ns.viewerMHTML.json ├── de_DE │ └── ns.viewerMHTML.json ├── tr │ └── ns.viewerMHTML.json └── en_US │ └── ns.viewerMHTML.json ├── bower.json ├── extension.css ├── mailparser └── LICENSE[MIT].txt ├── LICENSE.txt ├── css ├── github.css ├── clearness-dark.css ├── solarized-dark.css ├── clearness.css ├── haroopad.css ├── metro-vibes.css └── markdown.css ├── README.md ├── extension.js ├── libs └── jquery.highlight.js ├── index.html └── main.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "libs", 3 | "color": true 4 | } -------------------------------------------------------------------------------- /locales/zh_CN/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "缩小", 3 | "zoomIn": "放大", 4 | "zoomReset": "重置缩放", 5 | "changeTheme": "更换主题", 6 | "resetTheme": "重置主题", 7 | "print": "打印", 8 | "about": "关于", 9 | "aboutTitle": "关于ViewerMHTML扩展", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/ja/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "ズームアウト", 3 | "zoomIn": "ズームイン", 4 | "zoomReset": "ズーム解除", 5 | "changeTheme": "テーマ変更", 6 | "resetTheme": "テーマのリセット", 7 | "print": "プリント", 8 | "about": "詳細", 9 | "aboutTitle": "ViewerMHTML拡張について", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/ar/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/ca/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/el/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/ko/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/sv/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/uk/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/nl_NL/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/zh_TW/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Change Theme", 6 | "resetTheme": "Reset Theme", 7 | "print": "Print", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/id_ID/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Perkecil", 3 | "zoomIn": "Perbesar", 4 | "zoomReset": "Reset Pembesaran", 5 | "changeTheme": "Ganti Tema", 6 | "resetTheme": "Reset Tema", 7 | "print": "Cetak", 8 | "about": "Tentang", 9 | "aboutTitle": "Tentang ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/pt_BR/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Out", 3 | "zoomIn": "Zoom In", 4 | "zoomReset": "Zoom Reset", 5 | "changeTheme": "Alterar Aparência", 6 | "resetTheme": "Repor Aparência", 7 | "print": "Imprimir", 8 | "about": "Sobre", 9 | "aboutTitle": "Sobre a extensão ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/sk_SK/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Vzdialiť", 3 | "zoomIn": "Priblížiť", 4 | "zoomReset": "Obnoviť priblíženie", 5 | "changeTheme": "Zmeniť motív", 6 | "resetTheme": "Reset Theme", 7 | "print": "Tlačiť", 8 | "about": "About", 9 | "aboutTitle": "About ViewerMHTML extension", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/it/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom Indietro", 3 | "zoomIn": "Zoom Avanti", 4 | "zoomReset": "Ripristina lo Zoom", 5 | "changeTheme": "Cambia Tema", 6 | "resetTheme": "Ripristina Tema", 7 | "print": "Stampa", 8 | "about": "About", 9 | "aboutTitle": "About estensione ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/cs/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Odálit", 3 | "zoomIn": "Přiblížit", 4 | "zoomReset": "Resetovat Přiblížení/odálení", 5 | "changeTheme": "Změnit téma", 6 | "resetTheme": "Resetovat téma", 7 | "print": "Tisknout", 8 | "about": "O ViewerMHTML", 9 | "aboutTitle": "O rozšíření ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/pt_PT/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Afastar", 3 | "zoomIn": "Aproximar", 4 | "zoomReset": "Repor Vista", 5 | "changeTheme": "Alterar Aparência", 6 | "resetTheme": "Repor Aparência", 7 | "print": "Imprimir", 8 | "about": "Acerca de", 9 | "aboutTitle": "Acerca da extensão ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/es/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Reducir", 3 | "zoomIn": "Aumentar", 4 | "zoomReset": "Restablecer aumento", 5 | "changeTheme": "Cambiar tema", 6 | "resetTheme": "Restablecer tema", 7 | "print": "Imprimir", 8 | "about": "Acerca de", 9 | "aboutTitle": "Acerca de la extensión ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/pl/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Pomniejsz", 3 | "zoomIn": "Powiększ", 4 | "zoomReset": "Rozmiar oryginalny", 5 | "changeTheme": "Zmień motyw", 6 | "resetTheme": "Resetuj motyw", 7 | "print": "Drukuj", 8 | "about": "O programie", 9 | "aboutTitle": "Informacje o rozszerzeniu ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/fr/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Zoom arrière", 3 | "zoomIn": "Zoom avant", 4 | "zoomReset": "Taille normale", 5 | "changeTheme": "Changer le thème", 6 | "resetTheme": "Réinitialiser le thème", 7 | "print": "Imprimer", 8 | "about": "A propos", 9 | "aboutTitle": "A propos de l'extension ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/ru/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Уменьшить масштаб", 3 | "zoomIn": "Увеличить масштаб", 4 | "zoomReset": "Сбросить масштаб", 5 | "changeTheme": "Сменить оформление", 6 | "resetTheme": "Сбросить оформление", 7 | "print": "Печать", 8 | "about": "О расширении", 9 | "aboutTitle": "О расширении ViewerMHTML", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/bg/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Отдалечаване", 3 | "zoomIn": "Приближаване", 4 | "zoomReset": "Възстановяване на приближаването", 5 | "changeTheme": "Смяна на темата", 6 | "resetTheme": "Възстановяване на темата", 7 | "print": "Принтирай", 8 | "about": "Относно", 9 | "aboutTitle": "За ViewerMHTML плъгина", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/hu/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Kicsinyítés", 3 | "zoomIn": "Nagyítás", 4 | "zoomReset": "Nézet nagyításának visszaállítása", 5 | "changeTheme": "Téma váltás", 6 | "resetTheme": "Kinézet visszaállítása", 7 | "print": "Nyomtatás", 8 | "about": "A programról", 9 | "aboutTitle": "A ViewerMHTML kiegészítőről", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/de_DE/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Ansicht verkleinern", 3 | "zoomIn": "Ansicht vergrössern", 4 | "zoomReset": "Ansicht zurücksetzen", 5 | "changeTheme": "Farbenthema wechseln", 6 | "resetTheme": "Farbenthema zurücksetzen", 7 | "print": "Drucken", 8 | "about": "Über", 9 | "aboutTitle": "Über ViewerMHTML Erweiterung", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /locales/tr/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "zoomOut": "Uzaklaştır", 3 | "zoomIn": "Yakınlaştır", 4 | "zoomReset": "Yakınlaştırma Ayarını Sıfırla", 5 | "changeTheme": "Temayı Değiştir", 6 | "resetTheme": "Temayı Başlangıçtaki Durumuna Getir", 7 | "print": "Yazdır", 8 | "about": "Hakkında", 9 | "aboutTitle": "ViewerMHTML uzantısı hakkında", 10 | "-": "-" 11 | } -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MHTML Reader", 3 | "id": "viewerMHTML", 4 | "description": "A TagSpaces extension allowing you to open MHTML and EML files.", 5 | "type": "viewer", 6 | "version": "1.0.0", 7 | "dependencies": {}, 8 | "devDependencies": {}, 9 | "authors": [ 10 | "TagSpaces Authors - http://tagspaces.org", 11 | "Ilian Sapundshiev - http://ilian.me" 12 | ], 13 | "keywords": [ 14 | "viewer", 15 | "eml", 16 | "mhtml", 17 | "mht" 18 | ], 19 | "license": "MIT", 20 | "main": [ 21 | "extension.js" 22 | ], 23 | "ignore": [ 24 | "Gruntfile.js" 25 | ], 26 | "private": true 27 | } 28 | -------------------------------------------------------------------------------- /extension.css: -------------------------------------------------------------------------------- 1 | @import '../../assets/extensions.css'; 2 | @import '../../libs/extCommon/common.css'; 3 | 4 | html, body { 5 | overflow: auto; 6 | } 7 | 8 | #mhtmlViewer { 9 | font-size: 14px; 10 | } 11 | 12 | #readabilityFont { 13 | margin-left:19px; 14 | margin-top:11px; 15 | } 16 | 17 | #sanSerifLabel{ 18 | font-family: Helvetica, Arial, sans-serif 19 | } 20 | 21 | #serifLabel{ 22 | font-family: Georgia, Times New Roman, serif; 23 | } 24 | 25 | #readabilityFontSize { 26 | margin-left:19px; 27 | margin-top:11px; 28 | } 29 | 30 | .btn-black { 31 | background-color: #282a36; 32 | color: #ffffff; 33 | } 34 | 35 | .btn-sepia { 36 | background-color: #f4ecd8; 37 | color: #5b4636; 38 | } -------------------------------------------------------------------------------- /locales/en_US/ns.viewerMHTML.json: -------------------------------------------------------------------------------- 1 | { 2 | "findInDocument": "Find in document", 3 | "startSearch": "Start Search", 4 | "cancelSearch": "Cancel Search", 5 | "zoomOut": "Zoom Out", 6 | "zoomIn": "Zoom In", 7 | "zoomReset": "Zoom Reset", 8 | "changeTheme": "Change Theme", 9 | "resetTheme": "Reset Theme", 10 | "openSourceURL": "Open source URL", 11 | "openInNewWindow": "Open in new window", 12 | "print": "Print", 13 | "about": "About", 14 | "aboutTitle": "About ViewerMHTML extension", 15 | "readabilityOn": "Open reader mode", 16 | "readabilityOff": "Close reader mode", 17 | "toSansSerifFont": "Apply sans serif font", 18 | "toSerifFont": "Apply serif font", 19 | "increasingFontSize": "Increase Font Size", 20 | "decreasingFontSize": "Decrease Font Size", 21 | "changeBackgroundColor": "Change Background Color", 22 | "-": "-" 23 | } -------------------------------------------------------------------------------- /mailparser/LICENSE[MIT].txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Andris Reinman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 11 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 12 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 13 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 14 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 15 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 16 | SOFTWARE. -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Ilian Sapundshiev 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /css/github.css: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------- 2 | LESS Elements 0.9 3 | --------------------------------------------------- 4 | A set of useful LESS mixins 5 | More info at: http://lesselements.com 6 | ---------------------------------------------------*/ 7 | /** 8 | * https://github.com/rhiokim/markdown-css 9 | * solarized-light style 10 | * made by rhio.kim 11 | * powered by http://ethanschoonover.com/solarized 12 | */ 13 | .github { 14 | padding: 20px; 15 | color: #000000; 16 | font-size: 15px; 17 | font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', Verdana, Tahoma, sans-serif; 18 | background: #ffffff; 19 | -webkit-font-smoothing: antialiased; 20 | } 21 | .github a { 22 | color: #3269a0; 23 | } 24 | .github a:hover { 25 | color: #4183c4; 26 | } 27 | .github h2 { 28 | border-bottom: 1px solid #e6e6e6; 29 | line-height: 1.7em; 30 | } 31 | .github h6 { 32 | color: #777; 33 | } 34 | .github hr { 35 | border: 1px solid #e6e6e6; 36 | } 37 | .github pre > code { 38 | font-size: .9em; 39 | font-family: Consolas, Inconsolata, Courier, monospace; 40 | } 41 | .github blockquote { 42 | border-left: 4px solid #e6e6e6; 43 | padding: 0 15px; 44 | font-style: italic; 45 | } 46 | .github table { 47 | background-color: #fafafa; 48 | } 49 | .github table tr th, 50 | .github table tr td { 51 | border: 1px solid #e6e6e6; 52 | } 53 | .github table tr:nth-child(2n) { 54 | background-color: #f2f2f2; 55 | } 56 | /** 57 | * after less 58 | */ 59 | -------------------------------------------------------------------------------- /css/clearness-dark.css: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------- 2 | LESS Elements 0.9 3 | --------------------------------------------------- 4 | A set of useful LESS mixins 5 | More info at: http://lesselements.com 6 | ---------------------------------------------------*/ 7 | /** 8 | * https://github.com/rhiokim/markdown-css 9 | * solarized-light style 10 | * made by rhio.kim 11 | * powered by http://ethanschoonover.com/solarized 12 | */ 13 | .clearness-dark { 14 | padding: 20px; 15 | color: #ffffff; 16 | font-size: 15px; 17 | font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', Verdana, Tahoma, sans-serif; 18 | background: #282a36; 19 | -webkit-font-smoothing: antialiased; 20 | } 21 | .clearness-dark a { 22 | color: #e03300; 23 | } 24 | .clearness-dark a:hover { 25 | color: #ff4a14; 26 | } 27 | .clearness-dark h2 { 28 | border-bottom: 1px solid #21232d; 29 | line-height: 1.7em; 30 | } 31 | .clearness-dark h6 { 32 | color: #a4a296; 33 | } 34 | .clearness-dark hr { 35 | border: 1px solid #21232d; 36 | } 37 | .clearness-dark pre > code { 38 | font-size: .9em; 39 | font-family: Consolas, Inconsolata, Courier, monospace; 40 | } 41 | .clearness-dark blockquote { 42 | border-left: 4px solid #121319; 43 | padding: 0 15px; 44 | font-style: italic; 45 | } 46 | .clearness-dark table { 47 | background-color: #303241; 48 | } 49 | .clearness-dark table tr th, 50 | .clearness-dark table tr td { 51 | border: 1px solid #4b4e65; 52 | } 53 | .clearness-dark table tr:nth-child(2n) { 54 | background-color: #373a4b; 55 | } 56 | /** 57 | * after less 58 | */ -------------------------------------------------------------------------------- /css/solarized-dark.css: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------- 2 | LESS Elements 0.9 3 | --------------------------------------------------- 4 | A set of useful LESS mixins 5 | More info at: http://lesselements.com 6 | ---------------------------------------------------*/ 7 | /** 8 | * https://github.com/rhiokim/markdown-css 9 | * solarized-dark style 10 | * made by rhio.kim 11 | * powered by http://ethanschoonover.com/solarized 12 | */.solarized-dark { 13 | padding: 20px; 14 | color: #839496; 15 | font-size: 15px; 16 | font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', Verdana, Tahoma, sans-serif; 17 | background: #002b36; 18 | -webkit-font-smoothing: antialiased; 19 | } 20 | .solarized-dark a { 21 | color: #1e6ea7; 22 | } 23 | .solarized-dark a:hover { 24 | color: #268bd2; 25 | } 26 | .solarized-dark h1, 27 | .solarized-dark h2, 28 | .solarized-dark h3, 29 | .solarized-dark h4, 30 | .solarized-dark h5 { 31 | color: #b58900; 32 | } 33 | .solarized-dark h2 { 34 | border-bottom: 1px solid #005469; 35 | line-height: 1.7em; 36 | } 37 | .solarized-dark h6 { 38 | color: #694f00; 39 | } 40 | .solarized-dark hr { 41 | border: 1px solid #001f27; 42 | } 43 | .solarized-dark pre > code { 44 | font-size: .9em; 45 | font-family: Consolas, Inconsolata, Courier, monospace; 46 | } 47 | .solarized-dark blockquote { 48 | border-left: 4px solid #000203; 49 | padding: 0 15px; 50 | font-style: italic; 51 | } 52 | .solarized-dark table { 53 | background-color: #003441; 54 | } 55 | .solarized-dark table tr th, 56 | .solarized-dark table tr td { 57 | border: 1px solid #005065; 58 | } 59 | .solarized-dark table tr:nth-child(2n) { 60 | background-color: #003b4b; 61 | } 62 | /** 63 | * after less 64 | */ -------------------------------------------------------------------------------- /css/clearness.css: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------- 2 | LESS Elements 0.9 3 | --------------------------------------------------- 4 | A set of useful LESS mixins 5 | More info at: http://lesselements.com 6 | ---------------------------------------------------*/ 7 | /** 8 | * https://github.com/rhiokim/markdown-css 9 | * solarized-light style 10 | * made by rhio.kim 11 | * powered by http://ethanschoonover.com/solarized 12 | */ 13 | .clearness { 14 | padding: 20px; 15 | color: #737373; 16 | font-size: 15px; 17 | font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', Verdana, Tahoma, sans-serif; 18 | background: #ffffff; 19 | -webkit-font-smoothing: antialiased; 20 | } 21 | .clearness a { 22 | color: #1e6ea7; 23 | } 24 | .clearness a:hover { 25 | color: #268bd2; 26 | } 27 | .clearness h1, 28 | .clearness h2, 29 | .clearness h3, 30 | .clearness h4, 31 | .clearness h5 { 32 | color: #404040; 33 | } 34 | .clearness h2 { 35 | border-bottom: 1px solid #cccccc; 36 | line-height: 1.7em; 37 | } 38 | .clearness h6 { 39 | color: #666666; 40 | } 41 | .clearness hr { 42 | border: 1px solid #e6e6e6; 43 | } 44 | .clearness pre > code { 45 | font-size: .9em; 46 | font-family: Consolas, Inconsolata, Courier, monospace; 47 | } 48 | .clearness blockquote { 49 | padding: 0 15px; 50 | font-style: italic; 51 | } 52 | .clearness blockquote:before { 53 | content: "\201C"; 54 | font-size: 40px; 55 | margin-left: -20px; 56 | color: #aaa; 57 | } 58 | .clearness table { 59 | background-color: #ffffff; 60 | border-collapse: separate; 61 | border-spacing: 2px; 62 | } 63 | .clearness table tr th, 64 | .clearness table tr td { 65 | border: 0px; 66 | padding: .2em 1em; 67 | } 68 | .clearness table tr th { 69 | border-bottom: 1px solid #bfbfbf; 70 | } 71 | .clearness table tr td { 72 | border-bottom: 1px solid #d9d9d9; 73 | } 74 | .clearness table tr:nth-child(2n) { 75 | background-color: #ffffff; 76 | } 77 | /** 78 | * after less 79 | */ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MHTML Viewer for TagSpaces 2 | 3 | A TagSpaces extension allowing you to open MHTML and EML files. 4 | 5 | ## Features 6 | 7 | * Viewing of MHTML/MHT files - MHTML is [file format](https://tools.ietf.org/html/rfc2557) for saving web pages with all the images and styling information in one single file. Saving in MHTML format is natively supported by [Chrome™](http://docs.tagspaces.org/tutorials/webclipping.html#enabling-the-saving-of-webpages-as-mhtml), Internet Explorer™ and Firefox™ (with the help of the [MAFF addon](https://addons.mozilla.org/en-US/firefox/addon/mozilla-archive-format/)) browsers. 8 | * Viewing of EML files - EML is file format for saving emails. It is the default export email format of the Thunderbird email client. The *show original* email functionality in Gmail™ also exports the email in this format. 9 | * Readabilty mode - for easy reading of the text content, with support for *serif* and *sans serif* font, different font size and background colors. 10 | * Showing the creation date of the file 11 | * Opening the source url of a MHTML file 12 | * Finding text in the current file 13 | * File printing 14 | 15 | ![Animation of the viewerMHTML extension](https://github.com/tagspaces/documentation/raw/master/media/extensions/mhtml-viewer-readabilty-mode.gif) 16 | 17 | ## Used libraries 18 | This extension thankfully relays on the following great project(s): 19 | 20 | * [mailparser](https://github.com/andris9/mailparser) 21 | * [readability](https://github.com/mozilla/readability) 22 | 23 | ## Installation 24 | 25 | This extensions is packaged with any new version of TagSpaces 26 | 27 | ## Source code 28 | 29 | The source code of this extension is freely available on [github.com/tagspaces/viewerMHTML](https://github.com/tagspaces/viewerMHTML/) 30 | 31 | ## Development 32 | 33 | If you want to extend this extensions, please follow our general [extension development guide](https://docs.tagspaces.org/dev/extension-development-guide) 34 | 35 | ## License 36 | 37 | [MIT](https://github.com/tagspaces/viewerMHTML/blob/master/LICENSE.txt) 38 | 39 | -------------------------------------------------------------------------------- /css/haroopad.css: -------------------------------------------------------------------------------- 1 | /* 2 | @import url(http://fonts.googleapis.com/css?family=Tauri); 3 | @import url(http://fonts.googleapis.com/css?family=Roboto+Condensed:300italic,400italic,700italic,400,300,700); 4 | */ 5 | 6 | /*--------------------------------------------------- 7 | LESS Elements 0.9 8 | --------------------------------------------------- 9 | A set of useful LESS mixins 10 | More info at: http://lesselements.com 11 | ---------------------------------------------------*/ 12 | /** 13 | * https://github.com/rhiokim/markdown-css 14 | * solarized-light style 15 | * made by rhio.kim 16 | * powered by http://ethanschoonover.com/solarized 17 | */ 18 | .haroopad { 19 | padding: 20px; 20 | color: #222222; 21 | font-size: 15px; 22 | font-family: 'Roboto Condensed', 'Tauri', "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', Verdana, Tahoma, sans-serif; 23 | background: #ffffff; 24 | -webkit-font-smoothing: antialiased; 25 | } 26 | .haroopad a { 27 | color: #3269a0; 28 | } 29 | .haroopad a:hover { 30 | color: #4183c4; 31 | } 32 | .haroopad h2 { 33 | border-bottom: 1px solid #e6e6e6; 34 | line-height: 1.7em; 35 | } 36 | .haroopad h6 { 37 | color: #777; 38 | } 39 | .haroopad hr { 40 | border: 1px solid #e6e6e6; 41 | } 42 | .haroopad p > code { 43 | font-family: Consolas, Inconsolata, Courier, monospace; 44 | color: #BD006A; 45 | } 46 | .haroopad pre > code { 47 | font-size: 1em; 48 | font-family: Consolas, Inconsolata, Courier, monospace; 49 | letter-spacing: -1px; 50 | font-weight: bold; 51 | } 52 | .haroopad blockquote { 53 | border-left: 4px solid #e6e6e6; 54 | padding: 0 15px; 55 | font-style: italic; 56 | } 57 | .haroopad table { 58 | background-color: #fafafa; 59 | } 60 | .haroopad table tr th, 61 | .haroopad table tr td { 62 | border: 1px solid #e6e6e6; 63 | } 64 | .haroopad table tr:nth-child(2n) { 65 | background-color: #f2f2f2; 66 | } 67 | /** 68 | * after less 69 | */ 70 | /* 71 | .haroopad { 72 | 73 | img { 74 | .bordered(@border-color, @border-color, @border-color, @border-color); 75 | .rounded(3px); 76 | .box-shadow(0 0 7px darken(@border-color, 18%)); 77 | 78 | &:hover { 79 | -webkit-animation-duration: 1s; 80 | -webkit-animation-delay: .2s; 81 | .pulse; 82 | } 83 | } 84 | 85 | h1 { 86 | -webkit-animation-duration: .5s; 87 | -webkit-animation-delay: .2s; 88 | .tada; 89 | } 90 | 91 | &>ul { 92 | &>li { 93 | -webkit-animation-duration: .5s; 94 | -webkit-animation-delay: .2s; 95 | .fadeInLeft; 96 | } 97 | } 98 | 99 | } 100 | */ -------------------------------------------------------------------------------- /extension.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2016 The TagSpaces Authors. 2 | * Use of this source code is governed by the MIT license which can be found in the LICENSE.txt file. */ 3 | 4 | define(function(require, exports, module) { 5 | "use strict"; 6 | 7 | var extensionID = "viewerMHTML"; // ID should be equal to the directory name where the ext. is located 8 | var extensionSupportedFileTypes = ["mht", "mhtml"]; 9 | 10 | console.log("Loading " + extensionID); 11 | 12 | var TSCORE = require("tscore"); 13 | var currentFilePath; 14 | var $containerElement; 15 | var contentIFrame; 16 | var extensionDirectory = TSCORE.Config.getExtensionPath() + "/" + extensionID; 17 | var filePathURI; 18 | 19 | function init(filePath, containerElementID) { 20 | console.log("Initalization MHTML Viewer..."); 21 | $containerElement = $('#' + containerElementID); 22 | currentFilePath = filePath; 23 | 24 | if (isCordova || isWeb) { 25 | filePathURI = filePath; 26 | } else { 27 | filePathURI = "file:///" + filePath; 28 | } 29 | 30 | $containerElement.empty(); 31 | $containerElement.css("background-color", "white"); 32 | 33 | var extUITmpl = Handlebars.compile( 34 | '' 35 | ); 36 | 37 | var extUI = extUITmpl({ 38 | id: extensionID, 39 | lang: TSCORE.currentLanguage, 40 | extDir: extensionDirectory 41 | }); 42 | $containerElement.append(extUI); 43 | 44 | contentIFrame = document.getElementById("iframeViewer").contentWindow; 45 | 46 | TSCORE.IO.loadTextFilePromise(filePath).then(function(content) { 47 | exports.setContent(content); 48 | }, 49 | function(error) { 50 | TSCORE.hideLoadingAnimation(); 51 | TSCORE.showAlertDialog("Loading " + filePath + " failed."); 52 | console.error("Loading file " + filePath + " failed " + error); 53 | }); 54 | } 55 | 56 | function setFileType() { 57 | console.log("setFileType not supported on this extension"); 58 | } 59 | 60 | function viewerMode(isViewerMode) { 61 | // set readonly 62 | } 63 | 64 | function setContent(content) { 65 | if (typeof contentIFrame.setContent === "function") { 66 | contentIFrame.setContent(content, filePathURI); 67 | } else { 68 | window.setTimeout(function() { 69 | contentIFrame.setContent(content, filePathURI); 70 | }, 500); 71 | } 72 | } 73 | 74 | function getContent() { 75 | 76 | } 77 | 78 | exports.init = init; 79 | exports.getContent = getContent; 80 | exports.setContent = setContent; 81 | exports.viewerMode = viewerMode; 82 | exports.setFileType = setFileType; 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /css/metro-vibes.css: -------------------------------------------------------------------------------- 1 | /*@import url(http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800);*/ 2 | /*--------------------------------------------------- 3 | LESS Elements 0.9 4 | --------------------------------------------------- 5 | A set of useful LESS mixins 6 | More info at: http://lesselements.com 7 | ---------------------------------------------------*/ 8 | /** 9 | * https://github.com/rhiokim/markdown-css 10 | * made by rhio.kim 11 | */ 12 | .metro-vibes { 13 | padding: 20px; 14 | color: #8e8071; 15 | font-size: 15px; 16 | font-family: 'Open Sans', AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', sans-serif; 17 | background: #ffffff; 18 | -webkit-font-smoothing: antialiased; 19 | } 20 | .metro-vibes a { 21 | color: #3269a0; 22 | } 23 | .metro-vibes a:hover { 24 | color: #4183c4; 25 | } 26 | .metro-vibes h1, 27 | .metro-vibes h2, 28 | .metro-vibes h3, 29 | .metro-vibes h4, 30 | .metro-vibes h5 { 31 | font-weight: 400; 32 | color: #5c5146; 33 | letter-spacing: -1px; 34 | } 35 | .metro-vibes h2 { 36 | border-bottom: 1px solid #e6e6e6; 37 | line-height: 1.7em; 38 | } 39 | .metro-vibes h6 { 40 | color: #777; 41 | } 42 | .metro-vibes hr { 43 | border: 1px solid #e6e6e6; 44 | } 45 | .metro-vibes p { 46 | line-height: 19px; 47 | } 48 | .metro-vibes p > code { 49 | font-family: 'Open Sans', AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', sans-serif; 50 | color: #e86741; 51 | font-size: .9em; 52 | } 53 | .metro-vibes pre > code { 54 | font-size: 1em; 55 | font-family: 'Open Sans', AppleSDGothicNeo-Medium, 'Segoe UI', 'Malgun Gothic', sans-serif; 56 | letter-spacing: -1px; 57 | font-weight: normal; 58 | } 59 | .metro-vibes blockquote { 60 | border-left: 4px solid #e6e6e6; 61 | padding: 0 15px; 62 | font-style: italic; 63 | color: #e86741; 64 | } 65 | .metro-vibes table { 66 | background-color: #fafafa; 67 | } 68 | .metro-vibes table tr th, 69 | .metro-vibes table tr td { 70 | border: 1px solid #e6e6e6; 71 | } 72 | .metro-vibes table tr:nth-child(2n) { 73 | background-color: #f2f2f2; 74 | } 75 | /** 76 | * after less 77 | */ 78 | /* 79 | .haroopad { 80 | 81 | img { 82 | .bordered(@border-color, @border-color, @border-color, @border-color); 83 | .rounded(3px); 84 | .box-shadow(0 0 7px darken(@border-color, 18%)); 85 | 86 | &:hover { 87 | -webkit-animation-duration: 1s; 88 | -webkit-animation-delay: .2s; 89 | .pulse; 90 | } 91 | } 92 | 93 | h1 { 94 | -webkit-animation-duration: .5s; 95 | -webkit-animation-delay: .2s; 96 | .tada; 97 | } 98 | 99 | &>ul { 100 | &>li { 101 | -webkit-animation-duration: .5s; 102 | -webkit-animation-delay: .2s; 103 | .fadeInLeft; 104 | } 105 | } 106 | 107 | } 108 | */ -------------------------------------------------------------------------------- /css/markdown.css: -------------------------------------------------------------------------------- 1 | /** 2 | * standard markdown style 3 | */ 4 | .markdown { 5 | padding: 20px; 6 | } 7 | .markdown a { 8 | text-decoration: none; 9 | vertical-align: baseline; 10 | } 11 | .markdown a:hover { 12 | text-decoration: underline; 13 | } 14 | .markdown h1 { 15 | font-size: 2.2em; 16 | font-weight: bold; 17 | margin: 1.5em 0 1em 0; 18 | } 19 | .markdown h2 { 20 | font-size: 1.8em; 21 | font-weight: bold; 22 | margin: 1.275em 0 0.85em 0; 23 | } 24 | .markdown h3 { 25 | font-size: 1.6em; 26 | font-weight: bold; 27 | margin: 1.125em 0 0.75em 0; 28 | } 29 | .markdown h4 { 30 | font-size: 1.4em; 31 | font-weight: bold; 32 | margin: 0.99em 0 0.66em 0; 33 | } 34 | .markdown h5 { 35 | font-size: 1.2em; 36 | font-weight: bold; 37 | margin: 0.855em 0 0.57em 0; 38 | } 39 | .markdown h6 { 40 | font-size: 1em; 41 | font-weight: bold; 42 | margin: 0.75em 0 0.5em 0; 43 | } 44 | .markdown h1:first-child, 45 | .markdown h2:first-child, 46 | .markdown h3:first-child, 47 | .markdown h4:first-child, 48 | .markdown h5:first-child, 49 | .markdown h6:first-child { 50 | margin-top: 0; 51 | } 52 | .markdown h1 + p, 53 | .markdown h2 + p, 54 | .markdown h3 + p, 55 | .markdown h4 + p, 56 | .markdown h5 + p, 57 | .markdown h6 + p { 58 | margin-top: 0; 59 | } 60 | .markdown hr { 61 | border: 1px solid #cccccc; 62 | } 63 | .markdown p { 64 | margin: 1em 0; 65 | word-wrap: break-word; 66 | } 67 | .markdown ol { 68 | list-style-type: decimal; 69 | } 70 | .markdown li { 71 | display: list-item; 72 | line-height: 1.4em; 73 | } 74 | .markdown blockquote { 75 | margin: 1em 20px; 76 | } 77 | .markdown blockquote > :first-child { 78 | margin-top: 0; 79 | } 80 | .markdown blockquote > :last-child { 81 | margin-bottom: 0; 82 | } 83 | .markdown blockquote cite:before { 84 | content: '\2014 \00A0'; 85 | } 86 | .markdown .code { 87 | border-radius: 3px; 88 | word-break: break-all; 89 | word-wrap: break-word; 90 | } 91 | .markdown pre { 92 | border-radius: 3px; 93 | word-break: break-all; 94 | word-wrap: break-word; 95 | overflow: auto; 96 | } 97 | .markdown pre code { 98 | display: block; 99 | } 100 | .markdown pre > code { 101 | border: 1px solid #cccccc; 102 | white-space: pre; 103 | padding: .5em; 104 | margin: 0; 105 | } 106 | .markdown code { 107 | border-radius: 3px; 108 | word-break: break-all; 109 | word-wrap: break-word; 110 | border: 1px solid #cccccc; 111 | padding: 0 5px; 112 | margin: 0 2px; 113 | } 114 | .markdown img { 115 | max-width: 100%; 116 | } 117 | .markdown table { 118 | padding: 0; 119 | border-collapse: collapse; 120 | border-spacing: 0; 121 | } 122 | .markdown table tr th, 123 | .markdown table tr td { 124 | border: 1px solid #cccccc; 125 | margin: 0; 126 | padding: 6px 13px; 127 | } 128 | .markdown table tr th { 129 | font-weight: bold; 130 | } 131 | .markdown table tr th > :first-child { 132 | margin-top: 0; 133 | } 134 | .markdown table tr th > :last-child { 135 | margin-bottom: 0; 136 | } 137 | .markdown table tr td > :first-child { 138 | margin-top: 0; 139 | } 140 | .markdown table tr td > :last-child { 141 | margin-bottom: 0; 142 | } 143 | .markdown { 144 | /* custom rule for haroopad */ 145 | 146 | } 147 | .markdown em.underline { 148 | font-style: normal; 149 | text-decoration: underline; 150 | } 151 | .markdown strong.highlight { 152 | color: black; 153 | padding: 0 5px; 154 | background-color: #fdffb6; 155 | -webkit-box-shadow: #fdffb6 0 0 5px; 156 | -moz-box-shadow: #fdffb6 0 0 5px; 157 | box-shadow: #fdffb6 0 0 5px; 158 | } -------------------------------------------------------------------------------- /libs/jquery.highlight.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Highlight plugin 3 | * 4 | * Based on highlight v3 by Johann Burkard 5 | * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html 6 | * 7 | * Code a little bit refactored and cleaned (in my humble opinion). 8 | * Most important changes: 9 | * - has an option to highlight only entire words (wordsOnly - false by default), 10 | * - has an option to be case sensitive (caseSensitive - false by default) 11 | * - highlight element tag and class names can be specified in options 12 | * 13 | * Usage: 14 | * // wrap every occurrance of text 'lorem' in content 15 | * // with (default options) 16 | * $('#content').highlight('lorem'); 17 | * 18 | * // search for and highlight more terms at once 19 | * // so you can save some time on traversing DOM 20 | * $('#content').highlight(['lorem', 'ipsum']); 21 | * $('#content').highlight('lorem ipsum'); 22 | * 23 | * // search only for entire word 'lorem' 24 | * $('#content').highlight('lorem', { wordsOnly: true }); 25 | * 26 | * // don't ignore case during search of term 'lorem' 27 | * $('#content').highlight('lorem', { caseSensitive: true }); 28 | * 29 | * // wrap every occurrance of term 'ipsum' in content 30 | * // with 31 | * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); 32 | * 33 | * // remove default highlight 34 | * $('#content').unhighlight(); 35 | * 36 | * // remove custom highlight 37 | * $('#content').unhighlight({ element: 'em', className: 'important' }); 38 | * 39 | * 40 | * Copyright (c) 2009 Bartek Szopka 41 | * 42 | * Licensed under MIT license. 43 | * 44 | */ 45 | 46 | jQuery.extend({ 47 | highlight: function (node, re, nodeName, className) { 48 | if (node.nodeType === 3) { 49 | var match = node.data.match(re); 50 | if (match) { 51 | var highlight = document.createElement(nodeName || 'span'); 52 | highlight.className = className || 'highlight'; 53 | var wordNode = node.splitText(match.index); 54 | wordNode.splitText(match[0].length); 55 | var wordClone = wordNode.cloneNode(true); 56 | highlight.appendChild(wordClone); 57 | wordNode.parentNode.replaceChild(highlight, wordNode); 58 | return 1; //skip added node in parent 59 | } 60 | } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children 61 | !/(script|style)/i.test(node.tagName) && // ignore script and style nodes 62 | !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted 63 | for (var i = 0; i < node.childNodes.length; i++) { 64 | i += jQuery.highlight(node.childNodes[i], re, nodeName, className); 65 | } 66 | } 67 | return 0; 68 | } 69 | }); 70 | 71 | jQuery.fn.unhighlight = function (options) { 72 | var settings = { className: 'highlight', element: 'span' }; 73 | jQuery.extend(settings, options); 74 | 75 | return this.find(settings.element + "." + settings.className).each(function () { 76 | var parent = this.parentNode; 77 | parent.replaceChild(this.firstChild, this); 78 | parent.normalize(); 79 | }).end(); 80 | }; 81 | 82 | jQuery.fn.highlight = function (words, options) { 83 | var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; 84 | jQuery.extend(settings, options); 85 | 86 | if (words.constructor === String) { 87 | words = [words]; 88 | } 89 | words = jQuery.grep(words, function(word, i){ 90 | return word != ''; 91 | }); 92 | words = jQuery.map(words, function(word, i) { 93 | return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 94 | }); 95 | if (words.length == 0) { return this; }; 96 | 97 | var flag = settings.caseSensitive ? "" : "i"; 98 | var pattern = "(" + words.join("|") + ")"; 99 | if (settings.wordsOnly) { 100 | pattern = "\\b" + pattern + "\\b"; 101 | } 102 | var re = new RegExp(pattern, flag); 103 | 104 | return this.each(function () { 105 | jQuery.highlight(this, re, settings.element, settings.className); 106 | }); 107 | }; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 40 |
41 |

Preview of the document

42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 54 | 119 |
120 | 135 | 136 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2016 The TagSpaces Authors. 2 | * Use of this source code is governed by the MIT license which can be found in the LICENSE.txt file. */ 3 | 4 | /* global define MailParser, DOMPurify, Readability */ 5 | /* globals marked, MailParser, Mousetrap */ 6 | 7 | "use strict"; 8 | 9 | var readabilityContent; 10 | var cleanedHTML; 11 | var mhtmlViewer; 12 | var fontSize = 14; 13 | 14 | function setContent(content, filePathURI) { 15 | //console.log("MHTML Content: "+content); 16 | var mhtparser = new mailparser.MailParser(); 17 | mhtparser.on("end", function(mail_object) { 18 | //console.log("mail_object:", mail_object); 19 | 20 | var contLocation = /^content-location:(.*$)/im.exec(content); 21 | mail_object.contentLocation = (contLocation && contLocation.length > 0) ? contLocation[1] : "not found"; 22 | cleanedHTML = DOMPurify.sanitize(mail_object.html); 23 | 24 | updateHTMLContent($("#mhtmlViewer"), cleanedHTML); 25 | 26 | $("#fileMeta").append("saved on " + mail_object.headers.date); 27 | 28 | // View readability mode 29 | 30 | try { 31 | var documentClone = document.cloneNode(true); 32 | var article = new Readability(document.baseURI, documentClone).parse(); 33 | readabilityContent = article.content; 34 | } catch (e) { 35 | console.log("Error handling" + e); 36 | var msg = { 37 | command: "showAlertDialog", 38 | title: 'Readability Mode', 39 | message: 'This content can not be loaded.' 40 | }; 41 | window.parent.postMessage(JSON.stringify(msg), "*"); 42 | } 43 | 44 | 45 | if(readabilityContent) { 46 | updateHTMLContent($("#mhtmlViewer"), readabilityContent); 47 | } 48 | 49 | mhtmlViewer = document.getElementById("mhtmlViewer"); 50 | mhtmlViewer.style.fontSize = fontSize;//"large"; 51 | mhtmlViewer.style.fontFamily = "Helvetica, Arial, sans-serif"; 52 | mhtmlViewer.style.background = "#ffffff"; 53 | mhtmlViewer.style.color = ""; 54 | 55 | init(filePathURI, mail_object); 56 | }); 57 | 58 | mhtparser.write(content); 59 | mhtparser.end(); 60 | } 61 | 62 | function handleLinks($element) { 63 | $element.find("a[href]").each(function() { 64 | var currentSrc = $(this).attr("href"); 65 | $(this).off(); 66 | $(this).on('click', function(e) { 67 | e.preventDefault(); 68 | var msg = {command: "openLinkExternally", link: currentSrc}; 69 | window.parent.postMessage(JSON.stringify(msg), "*"); 70 | }); 71 | }); 72 | } 73 | 74 | function updateHTMLContent($targetElement, content) { 75 | $targetElement.html(content); 76 | handleLinks($targetElement); 77 | } 78 | 79 | function init(filePathURI, objectlocation) { 80 | var isCordova; 81 | var isWin; 82 | var isWeb; 83 | 84 | var $htmlContent; 85 | 86 | function getParameterByName(name) { 87 | name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); 88 | var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), 89 | results = regex.exec(window.location.search); 90 | return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); 91 | } 92 | 93 | var locale = getParameterByName("locale"); 94 | 95 | var extSettings; 96 | loadExtSettings(); 97 | 98 | isCordova = parent.isCordova; 99 | isWin = parent.isWin; 100 | isWeb = parent.isWeb; 101 | 102 | $htmlContent = $("#mhtmlViewer"); 103 | 104 | var styles = ['', 'solarized-dark', 'github', 'metro-vibes', 'clearness', 'clearness-dark']; 105 | var currentStyleIndex = 0; 106 | if (extSettings && extSettings.styleIndex) { 107 | currentStyleIndex = extSettings.styleIndex; 108 | } 109 | 110 | var zoomSteps = ['zoomSmallest', 'zoomSmaller', 'zoomSmall', 'zoomDefault', 'zoomLarge', 'zoomLarger', 'zoomLargest']; 111 | var currentZoomState = 3; 112 | if (extSettings && extSettings.zoomState) { 113 | currentZoomState = extSettings.zoomState; 114 | } 115 | 116 | $htmlContent.removeClass(); 117 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 118 | 119 | // Menu: hide readability items 120 | $("#toSansSerifFont").show(); 121 | $("#toSerifFont").show(); 122 | $("#increasingFontSize").show(); 123 | $("#decreasingFontSize").show(); 124 | $("#readabilityOn").hide(); 125 | $("#changeStyleButton").hide(); 126 | $("#resetStyleButton").hide(); 127 | 128 | //hide zoom operation menu items because they don't influence on the style 129 | $("#zoomInButton").hide(); 130 | $("#zoomOutButton").hide(); 131 | $("#zoomResetButton").hide(); 132 | 133 | $("#zoomInButton").on('click', function() { 134 | //console.log("#zoomInButton click"); 135 | currentZoomState++; 136 | if (currentZoomState >= zoomSteps.length) { 137 | currentZoomState = 6; 138 | } 139 | $htmlContent.removeClass(); 140 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 141 | saveExtSettings(); 142 | }); 143 | 144 | $("#zoomOutButton").on('click', function() { 145 | //console.log("#zoomOutButton click"); 146 | currentZoomState--; 147 | if (currentZoomState < 0) { 148 | currentZoomState = 0; 149 | } 150 | $htmlContent.removeClass(); 151 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 152 | saveExtSettings(); 153 | }); 154 | 155 | $("#zoomResetButton").on('click', function() { 156 | currentZoomState = 3; 157 | $htmlContent.removeClass(); 158 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 159 | saveExtSettings(); 160 | }); 161 | 162 | $("#openInNewWindowButton").on('click', function() { 163 | window.parent.open(filePathURI, '_blank'); // , 'nodeIntegration=0' 164 | }); 165 | 166 | $("#openURLButton").on('click', function() { 167 | var msg = {command: "openLinkExternally", link: objectlocation.contentLocation.trim()}; 168 | window.parent.postMessage(JSON.stringify(msg), "*"); 169 | }); 170 | 171 | $("#toSansSerifFont").on('click', function(e) { 172 | e.stopPropagation(); 173 | $htmlContent[0].style.fontFamily = "Helvetica, Arial, sans-serif"; 174 | }); 175 | 176 | $("#toSerifFont").on('click', function(e) { 177 | e.stopPropagation(); 178 | $htmlContent[0].style.fontFamily = "Georgia, Times New Roman, serif"; 179 | }); 180 | 181 | $("#increasingFontSize").on('click', function(e) { 182 | e.stopPropagation(); 183 | increaseFont(); 184 | }); 185 | 186 | $("#decreasingFontSize").on('click', function(e) { 187 | e.stopPropagation(); 188 | decreaseFont(); 189 | }); 190 | 191 | $("#whiteBackgroundColor").on('click', function(e) { 192 | e.stopPropagation(); 193 | $htmlContent[0].style.background = "#ffffff"; 194 | $htmlContent[0].style.color = ""; 195 | }); 196 | 197 | $("#blackBackgroundColor").on('click', function(e) { 198 | e.stopPropagation(); 199 | $htmlContent[0].style.background = "#282a36"; 200 | $htmlContent[0].style.color = "#ffffff"; 201 | }); 202 | 203 | $("#sepiaBackgroundColor").on('click', function(e) { 204 | e.stopPropagation(); 205 | $htmlContent[0].style.color = "#5b4636"; 206 | $htmlContent[0].style.background = "#f4ecd8"; 207 | }); 208 | 209 | $("#changeStyleButton").on('click', function() { 210 | currentStyleIndex = currentStyleIndex + 1; 211 | if (currentStyleIndex >= styles.length) { 212 | currentStyleIndex = 0; 213 | } 214 | $htmlContent.removeClass(); 215 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 216 | saveExtSettings(); 217 | }); 218 | 219 | $("#resetStyleButton").on('click', function() { 220 | currentStyleIndex = 0; 221 | //currentZoomState = 5; 222 | $htmlContent.removeClass(); 223 | $htmlContent.addClass('markdown ' + styles[currentStyleIndex] + " " + zoomSteps[currentZoomState]); 224 | saveExtSettings(); 225 | }); 226 | 227 | $("#readabilityOn").on('click', function() { 228 | if(readabilityContent) { 229 | updateHTMLContent($("#mhtmlViewer"), readabilityContent); 230 | } 231 | //if ($("#mhtmlViewer").data('clicked', true)) { 232 | $("#toSerifFont").show(); 233 | $("#toSansSerifFont").show(); 234 | $("#increasingFontSize").show(); 235 | $("#decreasingFontSize").show(); 236 | $("#readabilityOff").show(); 237 | $("#whiteBackgroundColor").show(); 238 | $("#blackBackgroundColor").show(); 239 | $("#sepiaBackgroundColor").show(); 240 | $("#themeStyle").show(); 241 | $("#readabilityFont").show(); 242 | $("#readabilityFontSize").show(); 243 | $("#readabilityOn").hide(); 244 | $("#changeStyleButton").hide(); 245 | $("#resetStyleButton").hide(); 246 | //} 247 | }); 248 | 249 | $("#readabilityOff").on('click', function() { 250 | updateHTMLContent($("#mhtmlViewer"), cleanedHTML); 251 | mhtmlViewer.style.fontSize = ''; 252 | mhtmlViewer.style.fontFamily = ""; 253 | mhtmlViewer.style.color = ""; 254 | mhtmlViewer.style.background = ""; 255 | $("#readabilityOff").hide(); 256 | $("#toSerifFont").hide(); 257 | $("#toSansSerifFont").hide(); 258 | $("#increasingFontSize").hide(); 259 | $("#decreasingFontSize").hide(); 260 | $("#whiteBackgroundColor").hide(); 261 | $("#blackBackgroundColor").hide(); 262 | $("#sepiaBackgroundColor").hide(); 263 | $("#themeStyle").hide(); 264 | $("#readabilityFont").hide(); 265 | $("#readabilityFontSize").hide(); 266 | $("#readabilityOn").show(); 267 | $("#changeStyleButton").show(); 268 | $("#resetStyleButton").show(); 269 | }); 270 | 271 | function increaseFont() { 272 | var style = window.getComputedStyle($htmlContent[0], null).getPropertyValue('font-size'); 273 | var fontSize = parseFloat(style); 274 | $htmlContent[0].style.fontSize = (fontSize + 1) + 'px'; 275 | } 276 | 277 | function decreaseFont() { 278 | var style = window.getComputedStyle($htmlContent[0], null).getPropertyValue('font-size'); 279 | var fontSize = parseFloat(style); 280 | $htmlContent[0].style.fontSize = (fontSize - 1) + 'px'; 281 | } 282 | 283 | Mousetrap.bind(['command++', 'ctrl++'], function(e) { 284 | increaseFont(); 285 | return false; 286 | }); 287 | 288 | Mousetrap.bind(['command+-', 'ctrl+-'], function(e) { 289 | decreaseFont(); 290 | return false; 291 | }); 292 | 293 | // Init internationalization 294 | $.i18n.init({ 295 | ns: {namespaces: ['ns.viewerMHTML']}, 296 | debug: true, 297 | lng: locale, 298 | fallbackLng: 'en_US' 299 | }, function() { 300 | $('[data-i18n]').i18n(); 301 | }); 302 | 303 | function saveExtSettings() { 304 | var settings = { 305 | "styleIndex": currentStyleIndex, 306 | "zoomState": currentZoomState 307 | }; 308 | localStorage.setItem('viewerMHTMLSettings', JSON.stringify(settings)); 309 | } 310 | 311 | function loadExtSettings() { 312 | extSettings = JSON.parse(localStorage.getItem("viewerMHTMLSettings")); 313 | } 314 | } --------------------------------------------------------------------------------