Commit 2d91c033 authored by cduvall@chromium.org's avatar cduvall@chromium.org

Extensions Docs Server: Fix samples page and ExampleZipper

The path for the default images in the samples page was wrong because of recent
branch/channel switches, and ExampleZipper was getting cached unicode data
instead of binary data.

BUG=144672

Review URL: https://chromiumcodereview.appspot.com/10878056

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153604 0039d316-1c4b-4281-b951-d872f2087c98
parent e544c099
......@@ -12,12 +12,11 @@ import compiled_file_system as compiled_fs
class ExampleZipper(object):
"""This class creates a zip file given a samples directory.
"""
def __init__(self, file_system, cache_factory, base_path, match_path):
def __init__(self, file_system, cache_factory, base_path):
self._base_path = base_path
self._zip_cache = cache_factory.Create(self._MakeZipFile,
compiled_fs.ZIP)
self._file_system = file_system
self._match_path = match_path
def _MakeZipFile(self, files):
zip_path = os.path.commonprefix(files).rsplit('/', 1)[-2]
......
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import unittest
from compiled_file_system import CompiledFileSystem
from example_zipper import ExampleZipper
from in_memory_object_store import InMemoryObjectStore
from local_file_system import LocalFileSystem
from memcache_file_system import MemcacheFileSystem
class ExampleZipperTest(unittest.TestCase):
def setUp(self):
object_store = InMemoryObjectStore('')
self._file_system = MemcacheFileSystem(LocalFileSystem('test_data'),
object_store)
self._example_zipper = ExampleZipper(
self._file_system,
CompiledFileSystem.Factory(self._file_system, object_store),
'example_zipper')
def testCreateZip(self):
# Cache manifest.json as unicode and make sure ExampleZipper doesn't error.
self._file_system.ReadSingle('example_zipper/basic/manifest.json')
self.assertTrue(len(self._example_zipper.Create('basic')) > 0)
if __name__ == '__main__':
unittest.main()
......@@ -93,7 +93,7 @@ def _GetInstanceForBranch(channel_name, local_path):
cache_factory,
[INTRO_PATH, ARTICLE_PATH])
samples_data_source_factory = SamplesDataSource.Factory(
branch,
channel_name,
file_system,
GITHUB_FILE_SYSTEM,
cache_factory,
......@@ -113,8 +113,7 @@ def _GetInstanceForBranch(channel_name, local_path):
PRIVATE_TEMPLATE_PATH)
example_zipper = ExampleZipper(file_system,
cache_factory,
DOCS_PATH,
EXAMPLES_PATH)
DOCS_PATH)
SERVER_INSTANCES[branch] = ServerInstance(
template_data_source_factory,
example_zipper,
......
......@@ -7,11 +7,17 @@ from future import Future
import object_store
class _AsyncUncachedFuture(object):
def __init__(self, uncached, current_result, file_system, object_store):
def __init__(self,
uncached,
current_result,
file_system,
object_store,
namespace):
self._uncached = uncached
self._current_result = current_result
self._file_system = file_system
self._object_store = object_store
self._namespace = namespace
def Get(self):
mapping = {}
......@@ -20,7 +26,7 @@ class _AsyncUncachedFuture(object):
version = self._file_system.Stat(item).version
mapping[item] = (new_items[item], version)
self._current_result[item] = new_items[item]
self._object_store.SetMulti(mapping, object_store.FILE_SYSTEM_READ, time=0)
self._object_store.SetMulti(mapping, self._namespace, time=0)
return self._current_result
class MemcacheFileSystem(FileSystem):
......@@ -67,9 +73,10 @@ class MemcacheFileSystem(FileSystem):
"""
result = {}
uncached = []
results = self._object_store.GetMulti(paths,
object_store.FILE_SYSTEM_READ,
time=0).Get()
namespace = object_store.FILE_SYSTEM_READ
if binary:
namespace = '%s.binary' % namespace
results = self._object_store.GetMulti(paths, namespace, time=0).Get()
result_values = [x[1] for x in sorted(results.iteritems())]
stats = self._object_store.GetMulti(paths,
object_store.FILE_SYSTEM_STAT).Get()
......@@ -85,7 +92,6 @@ class MemcacheFileSystem(FileSystem):
if stat is None:
stat = self.Stat(path).version
if stat != version:
self._object_store.Delete(path, object_store.FILE_SYSTEM_READ)
uncached.append(path)
continue
result[path] = data
......@@ -96,4 +102,5 @@ class MemcacheFileSystem(FileSystem):
self._file_system.Read(uncached, binary=binary),
result,
self,
self._object_store))
self._object_store,
namespace))
......@@ -22,7 +22,7 @@ class SamplesDataSource(object):
Requests.
"""
def __init__(self,
branch,
channel,
file_system,
github_file_system,
cache_factory,
......@@ -30,7 +30,7 @@ class SamplesDataSource(object):
samples_path):
self._file_system = file_system
self._github_file_system = github_file_system
self._static_path = ((('/' + branch) if branch != 'local' else '') +
self._static_path = ((('/' + channel) if channel != 'local' else '') +
'/static')
self._extensions_cache = cache_factory.Create(self._MakeSamplesList,
compiled_fs.EXTENSIONS)
......
{
"name": "My Bookmarks",
"version": "1.0",
"description": "A browser action with a popup dump of all bookmarks, including search, add, edit and delete.",
"permissions": [
"bookmarks", "tabs"
],
"browser_action": {
"default_title": "My Bookmarks.",
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"manifest_version": 2,
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}
<html>
<head>
<link type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css" rel="stylesheet">
<style>
div, td, th { color: black; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
<script src="popup.js"></script>
<script>
</script>
</head>
<body style="width: 400px">
<div>Search Bookmarks: <input id="search"></div>
<div id="bookmarks"></div>
<div id="editdialog"></div>
<div id="deletedialog"></div>
<div id="adddialog"></div>
</body>
</html>
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Search the bookmarks when entering the search keyword.
$(function() {
$('#search').change(function() {
$('#bookmarks').empty();
dumpBookmarks($('#search').val());
});
});
// Traverse the bookmark tree, and print the folder and nodes.
function dumpBookmarks(query) {
var bookmarkTreeNodes = chrome.bookmarks.getTree(
function(bookmarkTreeNodes) {
$('#bookmarks').append(dumpTreeNodes(bookmarkTreeNodes, query));
});
}
function dumpTreeNodes(bookmarkNodes, query) {
var list = $('<ul>');
var i;
for (i = 0; i < bookmarkNodes.length; i++) {
list.append(dumpNode(bookmarkNodes[i], query));
}
return list;
}
function dumpNode(bookmarkNode, query) {
if (bookmarkNode.title) {
if (query && !bookmarkNode.children) {
if (String(bookmarkNode.title).indexOf(query) == -1) {
return $('<span></span>');
}
}
var anchor = $('<a>');
anchor.attr('href', bookmarkNode.url);
anchor.text(bookmarkNode.title);
/*
* When clicking on a bookmark in the extension, a new tab is fired with
* the bookmark url.
*/
anchor.click(function() {
chrome.tabs.create({url: bookmarkNode.url});
});
var span = $('<span>');
var options = bookmarkNode.children ?
$('<span>[<a href="#" id="addlink">Add</a>]</span>') :
$('<span>[<a id="editlink" href="#">Edit</a> <a id="deletelink" ' +
'href="#">Delete</a>]</span>');
var edit = bookmarkNode.children ? $('<table><tr><td>Name</td><td>' +
'<input id="title"></td></tr><tr><td>URL</td><td><input id="url">' +
'</td></tr></table>') : $('<input>');
// Show add and edit links when hover over.
span.hover(function() {
span.append(options);
$('#deletelink').click(function() {
$('#deletedialog').empty().dialog({
autoOpen: false,
title: 'Confirm Deletion',
resizable: false,
height: 140,
modal: true,
overlay: {
backgroundColor: '#000',
opacity: 0.5
},
buttons: {
'Yes, Delete It!': function() {
chrome.bookmarks.remove(String(bookmarkNode.id));
span.parent().remove();
$(this).dialog('destroy');
},
Cancel: function() {
$(this).dialog('destroy');
}
}
}).dialog('open');
});
$('#addlink').click(function() {
$('#adddialog').empty().append(edit).dialog({autoOpen: false,
closeOnEscape: true, title: 'Add New Bookmark', modal: true,
buttons: {
'Add' : function() {
chrome.bookmarks.create({parentId: bookmarkNode.id,
title: $('#title').val(), url: $('#url').val()});
$('#bookmarks').empty();
$(this).dialog('destroy');
window.dumpBookmarks();
},
'Cancel': function() {
$(this).dialog('destroy');
}
}}).dialog('open');
});
$('#editlink').click(function() {
edit.val(anchor.text());
$('#editdialog').empty().append(edit).dialog({autoOpen: false,
closeOnEscape: true, title: 'Edit Title', modal: true,
show: 'slide', buttons: {
'Save': function() {
chrome.bookmarks.update(String(bookmarkNode.id), {
title: edit.val()
});
anchor.text(edit.val());
options.show();
$(this).dialog('destroy');
},
'Cancel': function() {
$(this).dialog('destroy');
}
}}).dialog('open');
});
options.fadeIn();
},
// unhover
function() {
options.remove();
}).append(anchor);
}
var li = $(bookmarkNode.title ? '<li>' : '<div>').append(span);
if (bookmarkNode.children && bookmarkNode.children.length > 0) {
li.append(dumpTreeNodes(bookmarkNode.children, query));
}
return li;
}
document.addEventListener('DOMContentLoaded', function () {
dumpBookmarks();
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment