summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources
diff options
context:
space:
mode:
authormirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 00:32:11 +0000
committermirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-26 00:32:11 +0000
commit61a523f378291307081d46277cca5dd087fb30ac (patch)
tree76a60b79fafd0f01c2e94b5740db63e88cd9ef99 /chrome/browser/resources
parent5bbf2884b6ff9466d95e3c6f177ebb7a39b70268 (diff)
downloadchromium_src-61a523f378291307081d46277cca5dd087fb30ac.zip
chromium_src-61a523f378291307081d46277cca5dd087fb30ac.tar.gz
chromium_src-61a523f378291307081d46277cca5dd087fb30ac.tar.bz2
Add single line of tips to NNTP.
BUG= http://crbug.com/19162 TEST= Start browser with NNTP, note line of tips at bottom. Review URL: http://codereview.chromium.org/173087 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24384 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources')
-rw-r--r--chrome/browser/resources/new_new_tab.css7
-rw-r--r--chrome/browser/resources/new_new_tab.html5
-rw-r--r--chrome/browser/resources/new_new_tab.js98
-rw-r--r--chrome/browser/resources/new_tab_theme.css7
4 files changed, 116 insertions, 1 deletions
diff --git a/chrome/browser/resources/new_new_tab.css b/chrome/browser/resources/new_new_tab.css
index c2ce487..a2af6fb0 100644
--- a/chrome/browser/resources/new_new_tab.css
+++ b/chrome/browser/resources/new_new_tab.css
@@ -682,6 +682,13 @@ html[dir='rtl'] #t4 {
top: 183px;
}
+/* tip line */
+#tip-line {
+ margin-top: 40px;
+ margin-bottom: 10px;
+ text-align: center;
+}
+
/* small */
@media (max-width: 920px) {
diff --git a/chrome/browser/resources/new_new_tab.html b/chrome/browser/resources/new_new_tab.html
index 9415d16..5266a88 100644
--- a/chrome/browser/resources/new_new_tab.html
+++ b/chrome/browser/resources/new_new_tab.html
@@ -35,11 +35,13 @@ function registerCallback(name) {
chrome.send('getShownSections');
chrome.send('getMostVisited');
chrome.send('getRecentlyClosedTabs');
+chrome.send('getTips');
registerCallback('onShownSections');
registerCallback('mostVisitedPages');
registerCallback('recentlyClosedTabs');
registerCallback('syncMessageChanged');
+registerCallback('tips');
logEvent('log start');
@@ -223,6 +225,9 @@ document.write('<link id="themecss" rel="stylesheet" ' +
<span><a href="">&nbsp;</a></span>
</div>
+ <div id="tip-line">
+ </div>
+
<div id="attribution" class="attribution">
<span i18n-content="attributionintro"></span><br />
<img id="attribution-img" />
diff --git a/chrome/browser/resources/new_new_tab.js b/chrome/browser/resources/new_new_tab.js
index 78f7912..e9618a9 100644
--- a/chrome/browser/resources/new_new_tab.js
+++ b/chrome/browser/resources/new_new_tab.js
@@ -94,6 +94,31 @@ function mostVisitedPages(data, firstRun) {
}
}
+var tipCache = {};
+
+function tips(data) {
+ logEvent('received tips');
+ tipCache = data;
+ renderTip();
+}
+
+function createTip(data) {
+ var parsedTips;
+ try {
+ parsedTips = parseHtmlSubset(data[0].tip_html_text);
+ } catch (parseErr) {
+ console.log('Error parsing tips: ' + parseErr.message);
+ }
+ return parsedTips;
+}
+
+function renderTip() {
+ var tipElement = $('tip-line');
+ // There should always be only one tip.
+ tipElement.textContent = '';
+ tipElement.appendChild(createTip(tipCache));
+}
+
function recentlyClosedTabs(data) {
logEvent('received recently closed tabs');
// We need to store the recent items so we can update the layout on a resize.
@@ -1539,3 +1564,76 @@ var dnd = {
};
dnd.init();
+
+/**
+ * Whitelist of tag names allowed in parseHtmlSubset.
+ * @type {[string]}
+ * /
+var allowedTags = ['A', 'B', 'STRONG'];
+
+/**
+ * Parse a very small subset of HTML.
+ * @param {string} s The string to parse.
+ * @throws {Error} In case of non supported markup.
+ * @return {DocumentFragment} A document fragment containing the DOM tree.
+ */
+var allowedAttributes = {
+ 'href': function(node, value) {
+ // Only allow a[href] starting with http:// and https://
+ return node.tagName == 'A' && (value.indexOf('http://') == 0 ||
+ value.indexOf('https://') == 0);
+ }
+}
+
+/**
+ * Parse a very small subset of HTML. This ensures that insecure HTML /
+ * javascript cannot be injected into the new tab page.
+ * @param {string} s The string to parse.
+ * @throws {Error} In case of non supported markup.
+ * @return {DocumentFragment} A document fragment containing the DOM tree.
+ */
+function parseHtmlSubset(s) {
+ function walk(n, f) {
+ f(n);
+ for (var i = 0; i < n.childNodes.length; i++) {
+ walk(n.childNodes[i], f);
+ }
+ }
+
+ function assertElement(node) {
+ if (allowedTags.indexOf(node.tagName) == -1)
+ throw Error(node.tagName + ' is not supported');
+ }
+
+ function assertAttribute(attrNode, node) {
+ var n = attrNode.nodeName;
+ var v = attrNode.nodeValue;
+ if (!allowedAttributes.hasOwnProperty(n) || !allowedAttributes[n](node, v))
+ throw Error(node.tagName + '[' + n + '="' + v + '"] is not supported');
+ }
+
+ var r = document.createRange();
+ r.selectNode(document.body);
+ // This does not execute any scripts.
+ var df = r.createContextualFragment(s);
+ walk(df, function(node) {
+ switch (node.nodeType) {
+ case Node.ELEMENT_NODE:
+ assertElement(node);
+ var attrs = node.attributes;
+ for (var i = 0; i < attrs.length; i++) {
+ assertAttribute(attrs[i], node);
+ }
+ break;
+
+ case Node.COMMENT_NODE:
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ case Node.TEXT_NODE:
+ break;
+
+ default:
+ throw Error('Node type ' + node.nodeType + ' is not supported');
+ }
+ });
+ return df;
+}
diff --git a/chrome/browser/resources/new_tab_theme.css b/chrome/browser/resources/new_tab_theme.css
index b59ef62c..e4547cd 100644
--- a/chrome/browser/resources/new_tab_theme.css
+++ b/chrome/browser/resources/new_tab_theme.css
@@ -56,7 +56,8 @@ body {
}
#recently-closed span,
#recently-closed a,
-#recently-closed a:link {
+#recently-closed a:link,
+#tip-line a {
color: $$4; /* COLOR_NTP_SECTION_LINK */
text-decoration:underline;
}
@@ -66,3 +67,7 @@ body {
color: $9;
text-align:right;
}
+
+#tip-line {
+ color: $$8;
+}