The Web Design Group

... Making the Web accessible to all.

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> HTML Pencil: an online HTML editor with real-time preview
RainLover
post Jul 4 2014, 09:25 AM
Post #1


Advanced Member
****

Group: Members
Posts: 216
Joined: 16-November 09
Member No.: 10,346



HTML Pencil is an online HTML editor created for modern browsers.

Please review the source code and provide feedback:

CODE
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="description" content="An online HTML editor with real-time preview">
    <title>HTML Pencil</title>
    <link rel="icon" href="favicon.ico" type="image/x-icon">
    <base target="_blank">
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            height: 100%;
        }
        body {
            display: -webkit-flex;
            /* WebKit prefixes are added to support Safari. */
            display: flex;
            -webkit-flex-direction: column;
            flex-direction: column;
        }
        header,
        .shown {
            display: -webkit-flex;
            display: flex;
            -webkit-align-items: center;
            align-items: center;
            padding: 5px;
        }
        header {
            background: linear-gradient(#FFF, #CCC);
        }
        #fileSaver,
        [type="button"],
        #fileChooser,
        label,
        span {
            font: bold 11px arial;
            color: #333;
        }
        #selector,
        #resizer,
        #viewsToggle,
        [title$="Twitter"] {
            margin-right: 5px;
            margin-left: 5px;
        }
        #fileSaver {
            margin-right: 5px;
        }
        #fileChooser,
        [title$="Facebook"] {
            margin-right: auto;
        }
        #resizer {
            margin-top: 0;
            margin-bottom: 0;
            padding: 0;
        }
        /* to remove the extra margins and padding in some browsers, e.g. IE11 */
        span {
            width: 35px;
        }
        #footerToggle {
            margin-right: 0;
            margin-left: 5px;
            border: 0;
            padding: 0;
            background: transparent;
        }
        main {
            display: -webkit-flex;
            display: flex;
            -webkit-flex: 1;
            flex: 1;
        }
        .horizontal {
            -webkit-flex-direction: column;
            flex-direction: column;
        }
        main * {
            margin: 0;
            -webkit-flex: 50;
            flex: 50;
            background: #FFF;
            min-height: 100%;
            /* to ensure that the flex items are stretched to use available space; IE11, for example, doesn't stretch the iframe. */
        }
        .horizontal * {
            min-width: 100%;
            min-height: 0;
            /* to get back to the initial value */
        }
        textarea {
            box-sizing: border-box;
            border: 0;
            outline: 0;
            padding: 5px;
            resize: none;
            overflow: auto;
            /* to remove the default scrollbar in IE11 */
        }
        .minSize {
            padding: 0;
        }
        iframe {
            border: solid #CCC;
            border-width: 0 0 0 5px;
            padding: 0;
        }
        .horizontal iframe {
            border-width: 5px 0 0;
        }
        .shown {
            background: linear-gradient(#CCC, #FFF);
        }
        img {
            display: block;
            width: 20px;
            height: 20px;
        }
        address,
        address a {
            color: #333;
        }
    </style>
</head>

<body>
    <header>
        <a download="myFile.html" title="Save as..." id="fileSaver">Save as...</a>
        <input type="button" value="Reset" id="resetter">
        <input type="button" value="Select" id="selector">
        <input type="file" accept="text/html" id="fileChooser">
        <label for="resizer">Text field size</label>
        <input type="range" id="resizer">
        <span id="indicator">50%</span>
        <!-- The semantic element to use instead of span is output. But it's not supported in IE11. -->
        <label for="viewsToggle">Horizontal view</label>
        <input type="checkbox" id="viewsToggle">
        <input type="button" value="▲" title="Show footer" id="footerToggle">
    </header>
    <main id="main">
        <textarea spellcheck="false" id="editor"><!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>HTML Document Template</title>
  </head>
  <body>
    <p>Hello, world!</p>
  </body>
</html></textarea>
        <iframe id="viewer"></iframe>
    </main>
    <footer hidden id="footer">
        <a href="https://plus.google.com/share?url=http%3A%2F%2Fhtmlpencil.appspot.com%2F" title="Share on Google+">
            <img src="images/google+.png" alt="Google+">
        </a>
        <a href="https://twitter.com/share?text=HTML%20Pencil&amp;url=http%3A%2F%2Fhtmlpencil.appspot.com%2F" title="Share on Twitter">
            <img src="images/twitter.png" alt="Twitter">
        </a>
        <a href="https://www.facebook.com/sharer.php?u=http%3A%2F%2Fhtmlpencil.appspot.com%2F" title="Share on Facebook">
            <img src="images/facebook.png" alt="Facebook">
        </a>
        <address><a href="feedback.html" title="Feedback">Feedback</a> / Created by <a href="https://plus.google.com/+MortezaMirmojarabian?rel=author" title="Google+ profile" rel="author">Mori</a></address>
    </footer>
    <script>
        var editor = document.getElementById('editor'),
            viewer = document.getElementById('viewer'),
            fileChooser = document.getElementById('fileChooser'),
            resizer = document.getElementById('resizer');

        function preview() {
            try {
                var viewerDoc = viewer.contentDocument;
                viewerDoc.open();
                viewerDoc.write(editor.value);
                viewerDoc.close();
            } catch (e) { // in case of iframe redirection to a different origin
                viewer.src = 'about:blank';
                setTimeout(preview, 4); // minimum delay
            }
        }
        preview();
        editor.oninput = preview;

        function createURL() {
            var blob = new Blob([editor.value], {
                type: 'text/html'
            });
            document.getElementById('fileSaver').href = window.URL.createObjectURL(blob);
        }
        createURL();
        editor.onchange = createURL;
        fileChooser.onclick = function () { // to empty the fileList so you can rechoose the same file
            this.value = '';
        };
        fileChooser.onchange = function () {
            var file = this.files[0],
                reader = new FileReader();
            if (file) { // to ensure that there's a file to read so IE11 doesn't run this function on clicking fileChooser before you choose a file
                reader.readAsText(file);
                reader.onload = function () {
                    editor.value = this.result;
                    preview();
                    createURL();
                };
            }
        };
        document.getElementById('viewsToggle').onchange = function () {
            document.getElementById('main').classList.toggle('horizontal');
        };
        resizer.oninput = resizer.onchange = function () { // The onchange property is added to support IE11.
            var resizerVal = this.value;
            editor.style.webkitFlex = resizerVal;
            editor.style.flex = resizerVal;
            viewer.style.webkitFlex = 100 - resizerVal;
            viewer.style.flex = 100 - resizerVal;
            document.getElementById('indicator').textContent = resizerVal + '%';
            if (resizerVal == 0) {
                editor.className = 'minSize';
            } else {
                editor.className = '';
            }
        };
        document.getElementById('selector').onclick = function () {
            editor.select();
        };
        document.getElementById('resetter').onclick = function () {
            if (!editor.value || editor.value != editor.defaultValue && confirm('Are you sure?')) {
                editor.value = editor.defaultValue;
                preview();
                createURL();
            }
        };
        document.getElementById('footerToggle').onclick = function () {
            var footerClasses = document.getElementById('footer').classList;
            footerClasses.toggle('shown');
            if (footerClasses.length) {
                this.value = '▼';
                this.title = 'Hide footer';
            } else {
                this.value = '▲';
                this.title = 'Show footer';
            }
        };
    </script>
</body>

</html>



Acknowledgement

Many thanks to Christian J who's always been a great help!
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Jul 4 2014, 03:04 PM
Post #2


.
********

Group: WDG Moderators
Posts: 9,656
Joined: 10-August 06
Member No.: 7



QUOTE(RainLover @ Jul 4 2014, 04:25 PM) *

Please review the source code and provide feedback:

Older browsers don't support all the features, so some browser feature detection might be useful? At least specify supported browsers and -versions somewhere. Does the file upload and save feature work on mobile phones (considering their more or less hidden file systems)?

Some instructions might be helpful. I think I understand what the script can do from your previous forum threads, otherwise it might have been a mystery.

QUOTE
Acknowledgement

Many thanks to Christian J who's always been a great help!

You're welcome... blush.gif
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
RainLover
post Jul 5 2014, 02:40 AM
Post #3


Advanced Member
****

Group: Members
Posts: 216
Joined: 16-November 09
Member No.: 10,346



Thanks for the feedback! smile.gif

QUOTE(Christian J @ Jul 4 2014, 03:04 PM) *

Does the file upload and save feature work on mobile phones (considering their more or less hidden file systems)?

I really have no idea as I don't have a smart phone. I just tried it in the latest version of all major browsers.
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Jul 6 2014, 07:54 AM
Post #4


.
********

Group: WDG Moderators
Posts: 9,656
Joined: 10-August 06
Member No.: 7



One thing I'm not sure about is the use of HTML code inside a TEXTAREA. Obviously such HTML code is shown as plain text (without rendering), but is it allowed there in the first place?

The HTML specs are vague (as usual), but the W3C validator flags an error when I try it using an HTML4 Doctype (for the main document), while HTML5 seems to accept it.

I also tried uploading an HTML file that contained a TEXTAREA, and apparently javascript could handle that without the nested TEXTAREA closing the outer one prematurely.
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
RainLover
post Jul 6 2014, 10:45 PM
Post #5


Advanced Member
****

Group: Members
Posts: 216
Joined: 16-November 09
Member No.: 10,346



QUOTE(Christian J @ Jul 6 2014, 07:54 AM) *

One thing I'm not sure about is the use of HTML code inside a TEXTAREA. Obviously such HTML code is shown as plain text (without rendering), but is it allowed there in the first place?

It's valid in HTML 5: MDN.

QUOTE
I also tried uploading an HTML file that contained a TEXTAREA, and apparently javascript could handle that without the nested TEXTAREA closing the outer one prematurely.

I read this sentence a few times and am still not sure what you mean. Would you mind paraphrasing it? What was the HTML file content exactly? What was the expected behavior? What actually happened? Thanks!

This post has been edited by RainLover: Jul 6 2014, 10:47 PM
User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post
Christian J
post Jul 7 2014, 04:45 AM
Post #6


.
********

Group: WDG Moderators
Posts: 9,656
Joined: 10-August 06
Member No.: 7



QUOTE(RainLover @ Jul 7 2014, 05:45 AM) *

It's valid in HTML 5: MDN.

Good!

QUOTE
What was the HTML file content exactly?

Something like this

CODE
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>HTML Document Template</title>
  </head>
  <body>
    <textarea>nested</textarea>
  </body>
</html>


QUOTE
What was the expected behavior? What actually happened?

I was afraid that the file's </textarea> end tag might close the TEXTAREA used by the script, but fortunately that didn't happen. smile.gif


User is offlinePM
Go to the top of the page
Toggle Multi-post QuotingQuote Post

Reply to this topicStart new topic
2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members:

 



- Lo-Fi Version Time is now: 24th April 2024 - 07:33 PM