Skip to content
6 changes: 6 additions & 0 deletions Web.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
</configuration>
6 changes: 6 additions & 0 deletions homework/Web.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
</configuration>
104 changes: 69 additions & 35 deletions homework/content.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,71 @@
'use strict';

(function() {
var _wrapper = document.querySelector('#note-content-wrapper');

function start() {
window.addEventListener('note-open', function(event) {
var note = event.detail;
resetWrapper();
drawNote(note);
});
}

function resetWrapper() {
_wrapper.innerHTML = '';
}

function drawNote(note) {
var title = note.title;
var h = document.createElement('h2');
h.textContent = title;
var passages = note.passages;
var buff = document.createDocumentFragment();
passages.forEach(function(passage) {
var p = document.createElement('p');
p.classList.add('note-passage');
p.textContent = passage;
buff.appendChild(p);
});
_wrapper.appendChild(h);
_wrapper.appendChild(buff);
}

document.addEventListener('DOMContentLoaded', function(event) {
start();
});
})();
(function (exports) {
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's good to see you tried to JSDoc the code.

* Declare wrapper.
*
* @constructor
* @this {TodoContentManager}
*/
var TodoContentManager = function () {
this._wrapper = null;
}
TodoContentManager.prototype = {
/**
* Initiate wrapper.
* Add a event listener to listen to note-open event
*
* @this {TodoContentManager}
*/
start() {
this._wrapper = document.querySelector('#note-content-wrapper');
window.addEventListener('note-open', this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. Bind this as the listener is better than an anonymous function.

},
/**
* Handle event
*
* @param{object} event - custom event :'note-open'
* , fire when note is opened.
* @this{TodoContentManager}
*/
handleEvent(event) {
switch (event.type) {
case 'note-open':
var note = event.detail;
this.resetWrapper();
this.drawNote(note);
break;
}
},
/**
* Reset the wrapper.
*
* @this {TodoContentManager}
*/
resetWrapper() {
this._wrapper.innerHTML = '';
},
/**
* Draw and add the note on wrapper.
*
* @param{object} note- note to be drawed
* @this{TodoContentManager}
*/
drawNote(note) {
var title = note.title;
var h = document.createElement('h2');
h.textContent = title;
var passages = note.passages;
var buff = document.createDocumentFragment();
passages.forEach(function (passage) {
var p = document.createElement('p');
p.classList.add('note-passage');
p.textContent = passage;
buff.appendChild(p);
});
this._wrapper.appendChild(h);
this._wrapper.appendChild(buff);
}
};
exports.TodoContentManager = TodoContentManager;
})(window);
21 changes: 12 additions & 9 deletions homework/index.html
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> Homework - Note List </title>
<script defer src="list.js"></script>
<script defer src="content.js"></script>
<link rel="stylesheet" type="text/css" href="main.css" />
<meta charset="UTF-8">
<title> Homework - Note List </title>
<script defer src="main.js"></script>
<script defer src="list.js"></script>
<script defer src="content.js"></script>
<script defer src="test.js"></script>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<h1> Homework - Note List </h1>
<div id="note-list-wrapper"></div>
<div id="note-content-wrapper"></div>
<h1> Homework - Note List </h1>
<div id="note-list-wrapper">
</div>
<div id="note-content-wrapper"></div>
</body>
</html>
213 changes: 138 additions & 75 deletions homework/list.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,142 @@
'use strict';

(function() {

var _listNoteContent = [];
var _wrapper = document.querySelector('#note-list-wrapper');

function start() {
fetchList(function(data) {
updateList(data);
drawList();
preloadFirstNote();
});
window.addEventListener('click', function(event) {
onNoteOpen(event);
});
}

function onNoteOpen(event) {
if (event.target.classList.contains('note-title')) {
var id = event.target.dataset.noteId;
var content = _listNoteContent[id];
window.dispatchEvent(new CustomEvent('note-open',
{ detail: content }));
(function (exports) {
/**
* Declare _listNoteContent.
* Declare wrapper.
*
* @constructor
* @this {TodoListManager}
*/
var TodoListManager = function () {
// Local data storage; should sync up with the server.
this._listNoteContent = [];
// Will be an element as the list wrapper.
this._wrapper = null;
};
}

function preloadFirstNote() {
if (_listNoteContent.length !== 0) {
var content = _listNoteContent[0];
window.dispatchEvent(new CustomEvent('note-open',
{ detail: content }));
}
}

function updateList(list) {
_listNoteContent = list;
}

function drawList() {
var list = _listNoteContent;
var ul = document.createElement('ul');
ul.id = 'note-title-list';
var buff = document.createDocumentFragment();
list.forEach(function(note, i) {
var li = document.createElement('li');
li.dataset.noteId = i;
li.classList.add('note-title');
li.textContent = note.title;
// Note: buff is captured, so we now have a
// little closure naturally.
buff.appendChild(li);
});
ul.appendChild(buff);
_wrapper.appendChild(ul);
}

function fetchList(afterFetch) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/demo-list-notes.json', true);
xhr.responseType = 'json';
xhr.onreadystatechange = function(e) {
// Watch out: we have a mysterious unknown 'this'.
if (this.readyState === 4 && this.status === 200) {
var listData = this.response;
// The flow ends here.
afterFetch(listData);
} else if (this.status !== 200 ){
// Ignore error in this case.
}
TodoListManager.prototype = {
/**
* Initial wrapper
* Add a eventlistener to listen click event
* Call fetchList to fetech data,
* after fetch , draw the list
*
* @this {TodoListManager}
*/
start() {
this._wrapper = document.querySelector('#note-list-wrapper');
window.addEventListener('click', this);
this.fetchList().then((function (data) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to use Arrow function instead of call bind API. It's more expressive, see:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this

this.updateList(data);
this.drawList();
this.preloadFirstNote();
}).bind(this))
},
/**
* Dispatch a custom event when mouse click at the note-title.
* Also determine the content to be showed.
*
* @param {Object} event- mouse click event.
* @this {TodoListManager}
*/
onNoteOpen(event) {
if (event.target.classList.contains('note-title')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a function body is wrapped by an if...else with only one branch, moving the condition into the caller rather than caller is recommended.

var id = event.target.dataset.noteId;
var content = this._listNoteContent[id];
window.dispatchEvent(new CustomEvent('note-open',
{ detail: content }));
};
},
/**
* Handle click event.
* If users click on note-title, call onNoteOpen to handle.
*
* @param {Object} event - mouse click event
* @this {TodoListManager}
*/
handleEvent(event) {
switch (event.type) {
case 'click':
this.onNoteOpen(event);
break;
}
},
/**
* Show the Note for start stage.
*
* @this {TodoListManager}
*/
preloadFirstNote() {
if (this._listNoteContent.length !== 0) {
var content = this._listNoteContent[0];
window.dispatchEvent(new CustomEvent('note-open',
{ detail: content }));
}
},
/**
* Update List.
*
* @param {array} - list to be updated to _listNoteContent
* @this {TodoListManager}
*/
updateList(list) {
this._listNoteContent = list;
},
/**
* Draw the list.
*
* @this {TodoListManager}
*/
drawList() {
var list = this._listNoteContent;
var ul = document.createElement('ul');
ul.id = 'note-title-list';
var buff = document.createDocumentFragment();
list.forEach(function (note, i) {
var li = document.createElement('li');
li.dataset.noteId = i;
li.classList.add('note-title');
li.textContent = note.title;
// Note: buff is captured, so we now have a
// little closure naturally.
buff.appendChild(li);
});
ul.appendChild(buff);
this._wrapper.appendChild(ul);
},
/**
* Try fetch Data(note-list) from .json,where is localhost.
* If there is any problem fetch the file direct from same http server as .html file
* (Because I got some problem to get the file from my system)
* If success,then continue the following flow
* Else it will reject
*
* @return {Promise}
* @this {TodoListManager}
*/
fetchList() {
return new Promise((function (yes, no) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if you work along this may not be a problem. But to keep the documented names of arguments make your code more readable for others. Anyway, you have successfully "Promisified" the method, good work.

var xhr = new XMLHttpRequest();
try {
xhr.open('GET', 'http://127.0.0.1:8000/demo-list-notes.json', true);
} catch (exception) {
console.log(exception);
xhr.open('GET', 'demo-list-notes.json', true);
}
xhr.responseType = 'json';
xhr.onreadystatechange = function (e) {
// Watch out: we have a mysterious unknown 'this'.
if (this.readyState === 4 && this.status === 200) {
var listData = this.response;
// The flow ends here.
yes(listData);
} else if (this.status !== 200) {
// Ignore error in this case.
}
};
xhr.send();
}).bind(this));
}
};
xhr.send();
}

document.addEventListener('DOMContentLoaded', function(event) {
start();
});

})();
exports.TodoListManager = TodoListManager;
})(window);
10 changes: 10 additions & 0 deletions homework/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

// Kick off
document.addEventListener('DOMContentLoaded', function (event) {
var todoListManager = new TodoListManager();
var todoContentManager = new TodoContentManager();
var test = new Test();
todoListManager.start();
todoContentManager.start();
});
14 changes: 14 additions & 0 deletions homework/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use strict';
'use strict';

(function (exports) {
var Test = function () {

};
Test.prototype = {
test(a, b) {
return a + b;
}
};
exports.Test = Test;
})(window);
Loading