diff options
author | Rory MacQueen <rorymacqueen@gmail.com> | 2014-05-27 16:13:23 -0700 |
---|---|---|
committer | Rory MacQueen <rorymacqueen@gmail.com> | 2014-05-27 16:13:23 -0700 |
commit | c2d1a64a514c70185808dafcf628a8a7cd780791 (patch) | |
tree | f83c397c60a49bbd4bf4faddd23fd4a25b80bbd0 | |
parent | 0f2082a16cc628eeecbd4837cef65e2cc31fac0e (diff) |
Remove Endless Wikipedia library from SDK
[endlessm/eos-sdk#693]
53 files changed, 0 insertions, 2984 deletions
@@ -7,8 +7,6 @@ Endless-0.gir Endless-0.typelib endless/eosresource.c endless/eosresource-private.h -data/eos-wikipedia-domain.gresource -wikipedia/config.js tools/eos-run-test tools/eos-application-manifest/eos-application-manifest tools/eos-json-extractor/eos-json-extractor diff --git a/Makefile.am b/Makefile.am index c635f63..11743c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,6 @@ DISTCLEANFILES += @EOS_SDK_API_NAME@.pc # SDK sublibraries gjsmodulesdir = $(datadir)/gjs-1.0 -include $(top_srcdir)/wikipedia/Makefile.am.inc include $(top_srcdir)/webhelper/Makefile.am.inc # # # INTROSPECTION FILES # # # @@ -127,21 +126,6 @@ endif include $(top_srcdir)/docs/reference/webhelper/Makefile.am.inc -# # # SECONDARY GRESOURCES # # # - -wikipedia_resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/data --generate-dependencies $(srcdir)/data/eos-wikipedia-domain.gresource.xml) -data/eos-wikipedia-domain.gresource: data/eos-wikipedia-domain.gresource.xml $(wikipedia_resource_files) - $(AM_V_GEN) $(MKDIR_P) $(builddir)/data && \ - $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/data $< - -wikipediadatadir = $(datadir)/eos-wikipedia-domain -wikipediadata_DATA = data/eos-wikipedia-domain.gresource -EXTRA_DIST += \ - $(wikipedia_resource_files) \ - data/eos-wikipedia-domain.gresource.xml \ - $(NULL) -CLEANFILES += data/eos-wikipedia-domain.gresource - # # # GJS OVERRIDES # # # include $(top_srcdir)/overrides/Makefile.am.inc diff --git a/configure.ac b/configure.ac index 4f5ad3f..243fb2a 100644 --- a/configure.ac +++ b/configure.ac @@ -204,13 +204,6 @@ PKG_CHECK_MODULES([EOS_SDK], [ $EOS_REQUIRED_MODULES $EOS_REQUIRED_MODULES_PRIVATE]) -# Check installed GIRs for wikipedia module -EOS_CHECK_GJS_GIR([Gdk], [3.0]) -EOS_CHECK_GJS_GIR([GdkPixbuf], [2.0]) -EOS_CHECK_GJS_GIR([Gio], [2.0]) -EOS_CHECK_GJS_GIR([GObject], [2.0]) -EOS_CHECK_GJS_GIR([Gtk], [3.0]) -EOS_CHECK_GJS_GIR([Json], [1.0]) AC_CACHE_SAVE diff --git a/data/assets/content_background.jpg b/data/assets/content_background.jpg Binary files differdeleted file mode 100644 index e53a87a..0000000 --- a/data/assets/content_background.jpg +++ /dev/null diff --git a/data/assets/content_title_separator.png b/data/assets/content_title_separator.png Binary files differdeleted file mode 100644 index db7d7db..0000000 --- a/data/assets/content_title_separator.png +++ /dev/null diff --git a/data/assets/image_strip_back_button.png b/data/assets/image_strip_back_button.png Binary files differdeleted file mode 100644 index 1d4787c..0000000 --- a/data/assets/image_strip_back_button.png +++ /dev/null diff --git a/data/assets/introduction_title_separator.png b/data/assets/introduction_title_separator.png Binary files differdeleted file mode 100644 index 7c202f7..0000000 --- a/data/assets/introduction_title_separator.png +++ /dev/null diff --git a/data/assets/panel_shadow.png b/data/assets/panel_shadow.png Binary files differdeleted file mode 100644 index b5a2c57..0000000 --- a/data/assets/panel_shadow.png +++ /dev/null diff --git a/data/assets/submenu_background.jpg b/data/assets/submenu_background.jpg Binary files differdeleted file mode 100644 index ccdac1d..0000000 --- a/data/assets/submenu_background.jpg +++ /dev/null diff --git a/data/assets/submenu_bg_hover.png b/data/assets/submenu_bg_hover.png Binary files differdeleted file mode 100644 index b9ed24a..0000000 --- a/data/assets/submenu_bg_hover.png +++ /dev/null diff --git a/data/assets/submenu_bg_normal.jpg b/data/assets/submenu_bg_normal.jpg Binary files differdeleted file mode 100644 index b84c375..0000000 --- a/data/assets/submenu_bg_normal.jpg +++ /dev/null diff --git a/data/assets/submenu_bg_pressed.png b/data/assets/submenu_bg_pressed.png Binary files differdeleted file mode 100644 index d5693d5..0000000 --- a/data/assets/submenu_bg_pressed.png +++ /dev/null diff --git a/data/assets/submenu_hover_arrow.png b/data/assets/submenu_hover_arrow.png Binary files differdeleted file mode 100644 index a286591..0000000 --- a/data/assets/submenu_hover_arrow.png +++ /dev/null diff --git a/data/assets/submenu_separator_shadow_a.png b/data/assets/submenu_separator_shadow_a.png Binary files differdeleted file mode 100644 index d4ac1ba..0000000 --- a/data/assets/submenu_separator_shadow_a.png +++ /dev/null diff --git a/data/assets/submenu_separator_shadow_b.png b/data/assets/submenu_separator_shadow_b.png Binary files differdeleted file mode 100644 index ba79241..0000000 --- a/data/assets/submenu_separator_shadow_b.png +++ /dev/null diff --git a/data/assets/topbar_back_icon_normal.png b/data/assets/topbar_back_icon_normal.png Binary files differdeleted file mode 100644 index 84c6861..0000000 --- a/data/assets/topbar_back_icon_normal.png +++ /dev/null diff --git a/data/assets/wikipedia-category-back-symbolic.svg b/data/assets/wikipedia-category-back-symbolic.svg deleted file mode 100644 index f844163..0000000 --- a/data/assets/wikipedia-category-back-symbolic.svg +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" - width="68px" height="68px" viewBox="-0.5 0.5 68 68" enable-background="new -0.5 0.5 68 68" xml:space="preserve"> -<path style="fill:#bebebe" d="M33.5,68.5c18.776,0,34-15.224,34-34c0-18.775-15.224-34-34-34c-18.775,0-34,15.225-34,34 - C-0.5,53.276,14.725,68.5,33.5,68.5z M37.456,16.652l5.151,5.15L29.73,34.682l12.876,12.88l-5.151,5.152L19.424,34.682 - L37.456,16.652z"/> -</svg> diff --git a/data/assets/wikipedia-category-forward-symbolic.svg b/data/assets/wikipedia-category-forward-symbolic.svg deleted file mode 100644 index 2fe909d..0000000 --- a/data/assets/wikipedia-category-forward-symbolic.svg +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" - width="42px" height="42px" viewBox="-0.5 0.5 42 42" enable-background="new -0.5 0.5 42 42" xml:space="preserve"> -<path style="fill:#bebebe" d="M20.5,0.5c-11.598,0-21,9.402-21,21s9.402,21,21,21s21-9.402,21-21S32.098,0.5,20.5,0.5z M17.999,32.499L15,29.5l7.998-8 - L15,13.5l2.999-2.999l11,10.999L17.999,32.499z"/> -</svg> diff --git a/data/css/eos-wikipedia-domain.css b/data/css/eos-wikipedia-domain.css deleted file mode 100644 index 0e834a2..0000000 --- a/data/css/eos-wikipedia-domain.css +++ /dev/null @@ -1,160 +0,0 @@ -* { - font-family: Lato; -} - -EosWindow { - background-color: black; -} - -.title { - font-family: "Lato Light"; - color: #ffffff; - text-shadow: 0px 1px 0px alpha(#23326e, 0.15); -} - -.title.main-element.category.front-page { - font-size: 9.17em; -} - -.title.category.front-page { - font-size: 3.75em; -} - -Gjs_ArticleList{ - background-image: url('resource:///com/endlessm/wikipedia-domain/assets/submenu_background.jpg'); -} - -Gjs_ArticleList .button { - padding-left: 25px; - padding-right: 25px; - padding-top: 15px; - padding-bottom: 15px; - font-size: 1.45em; - color: #464646; - background-image: url('resource:///com/endlessm/wikipedia-domain/assets/submenu_bg_normal.jpg'); - background-size: cover; -} - -Gjs_ArticleList .button:hover { - background-image: url('resource:///com/endlessm/wikipedia-domain/assets/submenu_bg_hover.png'); -} - -Gjs_ArticleList .button:active { - background-image: url('resource:///com/endlessm/wikipedia-domain/assets/submenu_bg_pressed.png'); -} - -Gjs_ArticleList .scrollbar.slider { - border-radius: 6px; - background-color: alpha(#464646, 0.5); -} - -.articles-page { - color: black; - background-color: #babdb6; -} - -.category-page .category-horizontal-separator { - border-image: url('resource:///com/endlessm/wikipedia-domain/assets/introduction_title_separator.png') 0 0 18 0 stretch; - border-width: 0px 0px 18px 0px; - border-style: solid; -} - -.category-page .category-vertical-separator { - border-image: url('resource:///com/endlessm/wikipedia-domain/assets/panel_shadow.png') 200 8 200 0 stretch; - border-width: 200px 8px 200px 0px; - border-style: solid; -} - -.category-page #category-info { - background-color: alpha(#464646, 0.8); -} - -.category-page #category-description { - color:rgba(255, 255, 255, 1.0); - background-color: rgba(0, 0, 0, 0); - font-size: 1.5em; -} - -.category-page #category-description-align { - padding: 0em 3.2em 0em 3.7em; -} - -.category-page #category-scrolled-window .scrollbar.slider { - border-radius: 6px; - background-color: alpha(white, 0.3); -} - -.category-page #category-title { - font-family: "Lato Light"; - font-size: 4.17em; - /* Set the font size in this widget, so the padding below (in ems) is actually - * relative to this font size */ - padding: .5em .75em .2em .75em; - color: rgba(255, 255, 255, 0.9); -} - -Gjs_CategoryButton.clickable { - transition: background-color 150ms ease-in-out; -} - -Gjs_CategoryButton.clickable:hover { - background-color: alpha(#212121, 0.5); -} - -#side_bar_button:hover { - background-color: rgba(0, 0, 0, 0.2); -} - -.category-page .back .image { - padding: 15px; - color: black; - opacity: 0.6; - icon-shadow: inset 0 1px 1px alpha(black, 0.5), 0 1px alpha(white, 0.2); -} - -.category-page .back .image:hover { - color: white; -} - -.category-page .back .image:active { - color: #d7d7d7; -} - -.category-page .back .image:hover, -.category-page .back .image:active { - opacity: 0.95; - icon-shadow: inset 0 1px 1px alpha(black, 0.5), - 0 1px alpha(white, 0.2), - 0 0 15px alpha(black, 0.15); -} - -.category-page .back .label { - font-weight: bold; - color: alpha(white, 0.0); -} - -.category-page .back .label:hover, -.category-page .back .label:active { - text-shadow: 0px 1px 0px alpha(#000000, 0.5), 0px 0px 12px alpha(#000000, 0.3); - color: alpha(white, 1.0); -} - -.category-page .back { - /* button image should be 60px from the right. image needs 15 px padding for - * background glow, so we pad by 45 here */ - padding-left: 45px; - padding-right: 45px; -} - -Gjs_BackButton { - -GtkButton-image-spacing: 7; - padding-top: 2px; - padding-bottom: 2px; - padding-left: 10px; - padding-right: 10px; -} - -.tooltip { - border-radius: 5px; - background-color: alpha(#212526, 0.90); -} diff --git a/data/eos-wikipedia-domain.gresource.xml b/data/eos-wikipedia-domain.gresource.xml deleted file mode 100644 index bccc5c0..0000000 --- a/data/eos-wikipedia-domain.gresource.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<gresources> - <gresource prefix="/com/endlessm/wikipedia-domain"> - <file compressed="true">css/eos-wikipedia-domain.css</file> - <file>assets/introduction_title_separator.png</file> - <file>assets/submenu_bg_hover.png</file> - <file>assets/submenu_bg_pressed.png</file> - <file>assets/submenu_bg_normal.jpg</file> - <file>assets/submenu_separator_shadow_a.png</file> - <file>assets/submenu_separator_shadow_b.png</file> - <file>assets/submenu_hover_arrow.png</file> - <file>assets/submenu_background.jpg</file> - <file>assets/image_strip_back_button.png</file> - <file>assets/panel_shadow.png</file> - <file compressed="true">assets/wikipedia-category-back-symbolic.svg</file> - <file compressed="true">assets/wikipedia-category-forward-symbolic.svg</file> - <file>assets/topbar_back_icon_normal.png</file> - </gresource> -</gresources> diff --git a/po/POTFILES.in b/po/POTFILES.in index 302ac4a..667e27c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1 @@ # List of source files which contain translatable strings. -wikipedia/widgets/BackButton.js -wikipedia/widgets/category_back_button.js @@ -19,11 +19,3 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: wikipedia/widgets/BackButton.js:21 -msgid "BACK" -msgstr "REGRESA" - -#: wikipedia/widgets/category_back_button.js:34 -msgid "OTHER CATEGORIES" -msgstr "OTRAS CATEGORÍAS" diff --git a/po/pt_BR.po b/po/pt_BR.po index e75a08a..67f8459 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -20,11 +20,3 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Language: pt\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#: wikipedia/widgets/BackButton.js:21 -msgid "BACK" -msgstr "Voltar" - -#: wikipedia/widgets/category_back_button.js:34 -msgid "OTHER CATEGORIES" -msgstr "OUTRAS CATEGORIAS" diff --git a/test/Makefile.am.inc b/test/Makefile.am.inc index 5a95942..921700b 100644 --- a/test/Makefile.am.inc +++ b/test/Makefile.am.inc @@ -15,9 +15,6 @@ javascript_tests = \ test/webhelper/testTranslate.js \ test/webhelper/testWebActions.js \ test/webhelper/testUpdateFontSize.js \ - test/wikipedia/models/testCategoryModel.js \ - test/wikipedia/models/testArticleModel.js \ - test/wikipedia/models/testDomainWikiModel.js \ $(NULL) EXTRA_DIST += $(javascript_tests) diff --git a/test/wikipedia/models/testArticleModel.js b/test/wikipedia/models/testArticleModel.js deleted file mode 100644 index f916369..0000000 --- a/test/wikipedia/models/testArticleModel.js +++ /dev/null @@ -1,110 +0,0 @@ -const ArticleModel = imports.wikipedia.models.article_model; - -describe("Wikipedia article model", function() { - let mockJsonData = { - title: 'Article Title', - url: 'file:///', - source: 'Mock data', - categories: [ - 'Category One', - 'Category Two' - ] - }; - - describe("from JSON", function() { - let model; - - beforeEach(function() { - model = ArticleModel.newFromJson(mockJsonData); - }); - - it("has an article title", function() { - expect(model.title).toEqual(mockJsonData.title); - }); - - it("has a uri", function() { - expect(model.uri).toEqual(mockJsonData.url); - }); - - it("has a list of categories", function() { - expect(model.getCategories()).toEqual(mockJsonData.categories); - }); - }); - - describe("from properties", function() { - let model; - beforeEach(function() { - model = new ArticleModel.ArticleModel({ - title: 'Article Title', - uri: 'file://' - }); - }); - - it("is an instance of an ArticleModel", function() { - expect(model instanceof ArticleModel.ArticleModel).toBeTruthy(); - }); - - it("has a title", function() { - expect(model.title).toEqual('Article Title'); - }); - - it("has a URI", function() { - expect(model.uri).toEqual('file://'); - }); - - it("has no categories", function() { - expect(model.getCategories().length).toEqual(0); - }); - }); - - describe("setCategories method", function() { - let model; - - beforeEach(function() { - model = new ArticleModel.ArticleModel(); - }); - - it("adds categories", function() { - let expectedCategories = ['One', 'Two', 'Three']; - model.setCategories(expectedCategories); - expect(model.getCategories()).toEqual(expectedCategories); - }); - - it("replaces existing categories", function() { - model.setCategories(['One', 'Two']); - let expectedCategories = ['One', 'Two', 'Three']; - model.setCategories(expectedCategories); - expect(model.getCategories()).toEqual(expectedCategories); - }); - }); - - it("appends new categories on addCategory", function() { - let model = new ArticleModel.ArticleModel(); - - model.addCategory('One'); - model.addCategory('Two'); - model.addCategory('Three'); - expect(model.getCategories()).toEqual(['One', 'Two', 'Three']); - }); - describe("hasCategory method", function() { - let model; - let expectedCategories = ['One', 'Two', 'Three']; - - beforeEach(function() { - model = new ArticleModel.ArticleModel; - model.setCategories(expectedCategories); - }); - - expectedCategories.forEach(function(category) { - (function(categoryName) { - it("returns true for category named " + categoryName, function() { - expect(model.hasCategory(categoryName)).toBeTruthy(); - }); - }); - }); - - it("returns false for an unexpected category", function() { - expect(model.hasCategory('unexpected')).toBeFalsy(); - }); - }); -}); diff --git a/test/wikipedia/models/testCategoryModel.js b/test/wikipedia/models/testCategoryModel.js deleted file mode 100644 index 4ffc1a0..0000000 --- a/test/wikipedia/models/testCategoryModel.js +++ /dev/null @@ -1,180 +0,0 @@ -const CategoryModel = imports.wikipedia.models.category_model; - -describe("Category Model", function() { - let mockJsonData = { - category_name: 'Category Name', - content_text: 'Lorem Ipsum', - image_file: 'file:///image.jpg', - image_thumb_uri: 'file:///thumb.jpg', - is_main_category: false, - subcategories: [ 'Category Two' ] - }; - describe("from JSON", function() { - - let model; - beforeEach(function() { - model = CategoryModel.newFromJson(mockJsonData); - }); - - it("is a CategoryModel", function() { - expect(model instanceof CategoryModel.CategoryModel).toBeTruthy(); - }); - - it("has an id", function() { - expect(model.id).toEqual(mockJsonData.category_name); - }); - - it("has no subcategories", function() { - expect(model.getSubcategories().length).toEqual(0); - }); - }); - - describe("from properties", function() { - let model; - - beforeEach(function() { - model = new CategoryModel.CategoryModel({ - id: 'id', - title: 'title', - description: 'description', - image_uri: 'image-uri', - image_thumbnail_uri: 'image-thumbnail-uri', - is_main_category: true, - has_articles: true - }); - }); - - it("has an id", function() { - expect(model.id).toEqual('id'); - }); - - it("has a title", function() { - expect(model.title).toEqual('title'); - }); - - it("has a description", function() { - expect(model.description).toEqual('description'); - }); - - it("has an image uri", function() { - expect(model.image_uri).toEqual('image-uri'); - }); - - it("has an image thumbnail uri", function() { - expect(model.image_thumbnail_uri).toEqual('image-thumbnail-uri'); - }); - - it("is a main category", function() { - expect(model.is_main_category).toBeTruthy(); - }); - - it("has articles", function() { - expect(model.has_articles).toBeTruthy(); - }); - - // FIXME: This seems to be a fairly useless test. Does it actually - // test anything? - it("does not have articles once the flag is unset", function() { - model.has_articles = false; - expect(model.has_articles).toBeFalsy(); - }); - }); - - it("starts with no subcategories", function() { - let model = new CategoryModel.CategoryModel(); - - expect(model.getSubcategories().length).toEqual(0); - }); - - describe("in a tree-like structure", function() { - let parent; - - beforeEach(function() { - jasmine.addMatchers({ - toContainCategoriesWithNames: function() { - return { - compare: function(actual, names) { - let result = { - pass: (function() { - let outer_pass = true; - names.forEach(function (id) { - let categories = actual.getSubcategories(); - if (!categories.some(function(category) { - return category.id == id; - })) { - outer_pass = false; - } - }); - return outer_pass; - })(), - - message: (function() { - let msg = "Expected categories with the following names\n"; - names.forEach(function(name) { - msg += " " + name + "\n"; - }); - msg += "Object actually has the following categories\n"; - actual.getSubcategories().forEach(function(category) { - msg += " " + category.id + "\n"; - }); - return msg; - })() - } - - return result; - } - } - }, - toHaveOnlyTheFollowingCategoriesInOrder: function() { - return { - compare: function(actual, names) { - let result = { - pass: (function() { - let categories = actual.getSubcategories(); - if (categories.length != names.length) - return false; - - for (let i = 0; i < categories.length; i++) { - if (categories[i].id != names[i]) - return false; - } - - return true; - })(), - - message: (function() { - let msg = "Expected exactly the following category names\n"; - names.forEach(function(name) { - msg += " " + name + "\n"; - }); - - msg += "Actually had the following category names\n"; - actual.getSubcategories().forEach(function(category) { - msg += " " + category.id + "\n"; - }); - - return msg; - })() - } - - return result; - } - } - } - }); - - parent = new CategoryModel.CategoryModel({ id: 'Category One' }); - parent.addSubcategory(new CategoryModel.CategoryModel({ id: 'Category Two' })); - parent.addSubcategory(new CategoryModel.CategoryModel({ id: 'Category Three' })); - }); - - it("has subcategories", function() { - expect(parent).toContainCategoriesWithNames(['Category Two', 'Category Three']); - }); - - it("silently does not add duplicates", function() { - parent.addSubcategory(new CategoryModel.CategoryModel({ id: 'Category Two' })); - expect(parent).toHaveOnlyTheFollowingCategoriesInOrder(['Category Two', 'Category Three']); - }); - }); -}); diff --git a/test/wikipedia/models/testDomainWikiModel.js b/test/wikipedia/models/testDomainWikiModel.js deleted file mode 100644 index f30d1bd..0000000 --- a/test/wikipedia/models/testDomainWikiModel.js +++ /dev/null @@ -1,208 +0,0 @@ -const DomainWikiModel = imports.wikipedia.models.domain_wiki_model; - -describe('Domain Wiki Model', function () { - const mockJsonData = { - categories: [ - { - category_name: 'Main Category', - content_text: 'Lorem Ipsum', - image_file: 'file:///image.jpg', - image_thumb_uri: 'file:///image_thumb.jpg', - is_main_category: true, - subcategories: [ - 'Category One', - 'Category Two' - ] - }, - { - category_name: 'Category One', - content_text: 'Lorem Ipsum', - image_file: 'file:///image.jpg', - image_thumb_uri: 'file:///image_thumb.jpg', - is_main_category: false, - subcategories: [] - }, - { - category_name: 'Category Two', - content_text: 'Lorem Ipsum', - image_file: 'file:///image.jpg', - image_thumb_uri: 'file:///image_thumb.jpg', - is_main_category: false, - subcategories: [ - 'Category Three' - ] - }, - { - category_name: 'Category Three', - content_text: 'Lorem Ipsum', - image_file: 'file:///image.jpg', - image_thumb_uri: 'file:///image_thumb.jpg', - is_main_category: false, - subcategories: [] - } - ], - articles: [ - { - title: 'Article One', - url: 'file:///article1.html', - source: 'Mock data', - categories: [ - 'Category One' - ] - }, - { - title: 'Article Two', - url: 'file:///article2.html', - source: 'Mock data', - categories: [ - 'Category One', - 'Category Two' - ] - }, - { - title: 'Article Three', - url: 'file:///article3.html', - source: 'Mock data', - categories: [ - 'Category Two' - ] - } - ] - }; - beforeEach(function () { - let model = new DomainWikiModel.DomainWikiModel(); - - jasmine.addMatchers({ - toHaveObjectsContainingProperties: function () { - return { - compare: function (actual, propertyMap) { - let result = { - pass: (function () { - for (let property in propertyMap) { - let allValuesListedHaveAMatchForObject = actual.some(function (object) { - if (object[property] == 'undefined') { - return false; - } - - let propertyValueMatchedForObject = - propertyMap[property].some(function (value) { - return object[property] == value; - }); - - return propertyValueMatchedForObject; - }); - - if (!allValuesListedHaveAMatchForObject) - return false; - } - - return true; - })(), - - message: (function () { - let msg = 'Expected objects to have the following values for the following properties \n'; - for (let property in propertyMap) { - msg += ' - Property: ' + property + '\n'; - for (let value in propertyMap[property]) { - msg += ' * Value: ' + propertyMap[property][value].toString() + '\n'; - } - } - - msg += 'Object actually has the following toplevel properties\n'; - - for (let i = 0; i < actual.length; i++) { - let object = actual[i]; - msg += ' Object in position ' + i + '\n'; - for (let property in object) { - msg += ' - ' + property + ' : ' + object[property] + '\n'; - } - } - - return msg; - })() - }; - - return result; - } - }; - } - }); - }); - - describe('when loaded from some mock JSON data', function () { - let model; - beforeEach(function () { - model = new DomainWikiModel.DomainWikiModel(); - model.loadFromJson(mockJsonData); - }); - - it('returns all articles when getting articles', function () { - let articles = model.getArticles(); - expect(articles).toHaveObjectsContainingProperties({ - title: [ 'Article One', 'Article Two', 'Article Three' ] - }); - }); - - it('can get articles for a category', function () { - let articles = model.getArticlesForCategory('Category One'); - expect(articles).toHaveObjectsContainingProperties({ - title: [ 'Article One', 'Article Two' ] - }); - }); - - it('has no articles on a category that does not have articles', function () { - let articles = model.getArticlesForCategory('Main Category'); - expect(articles.length).toEqual(0); - }); - - it('has no articles for a category that does not exist', function () { - let articles = model.getArticlesForCategory('Nonexistent'); - expect(articles.length).toEqual(0); - }); - - it('can check whether or not a category has articles', function () { - expect(model._getCategoryHasArticles('Category Two')).toBeTruthy(); - }); - - it('can check whether or not a category does not have articles', function () { - expect(model._getCategoryHasArticles('Category Three')).toBeFalsy(); - }); - - it('verifies that a category that does not exist has no articles', function () { - expect(model._getCategoryHasArticles('Nonexistent')).toBeFalsy(); - }); - - describe('category fetch', function () { - let category; - - beforeEach(function () { - category = model.getCategory('Category One'); - }); - - it('actually returns a category', function () { - expect(category.__name__).toEqual('CategoryModel'); - }); - - it('returns the right category', function () { - expect(category.title).toEqual('Category One'); - }); - }); - - it("returns an undefined value if we try to get a category that doesn't exist", function () { - expect(model.getCategory('Nonexistent')).toBeUndefined(); - }); - - it("returns 'Main Category' when getting the main category", function () { - let category = model.getMainCategory(); - - expect(category).toEqual(new jasmine.ObjectContaining({ - 'title' : 'Main Category' - })); - }); - }); - - it('returns null when the Main Category is unset', function () { - let model = new DomainWikiModel.DomainWikiModel(); - expect(model.getMainCategory()).toBeNull(); - }); -}); diff --git a/wikipedia/ArticleList.js b/wikipedia/ArticleList.js deleted file mode 100644 index 80c309a..0000000 --- a/wikipedia/ArticleList.js +++ /dev/null @@ -1,69 +0,0 @@ -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const ListTextButton = imports.wikipedia.widgets.ListTextButton; - -const ARTICLE_LIST_SIZE_REQUEST = 320; -const HOVER_ARROW_URI = "/com/endlessm/wikipedia-domain/assets/submenu_hover_arrow.png"; - -const ArticleList = new Lang.Class({ - Name: 'ArticleList', - Extends: Gtk.ScrolledWindow, - - Signals: { - 'article-chosen': { - param_types: [GObject.TYPE_STRING, GObject.TYPE_STRING] - } - }, - - _init: function(props) { - props = props || {}; - props.hscrollbar_policy = Gtk.PolicyType.NEVER; - props.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC, - this.parent(props); - this._grid = new Gtk.Grid({ - orientation: Gtk.Orientation.VERTICAL, - vexpand: true - }); - - // width is set per designs, height is set arbitrarily for now but - // doesn't matter because it's just a min size - this.set_size_request(ARTICLE_LIST_SIZE_REQUEST, -1); - this.add(this._grid); - }, - - /** - * Method: setArticles - * Set articles to display in this widget - * - * Parameters: - * articles - An array of <ArticleModels> - */ - setArticles: function(articles) { - // Remove all existing article links - this._grid.get_children().forEach(function(element, index, obj) { - this._grid.remove(element); - }, this); - - // Create new ones - articles.forEach(function (article) { - let button = new ListTextButton.ListTextButton(HOVER_ARROW_URI, - article.title, { hexpand: true }); - button.connect('clicked', Lang.bind(this, function() { - this.emit('article-chosen', article.title, article.uri); - })); - - this._grid.add(button); - }, this); - }, - - /** - * Method: scrollToTop - * Scrolls the article list all the way up. - */ - scrollToTop: function () { - this.get_vadjustment().set_value(0); - } -}); diff --git a/wikipedia/EndlessWikipedia.js b/wikipedia/EndlessWikipedia.js deleted file mode 100644 index c6e003b..0000000 --- a/wikipedia/EndlessWikipedia.js +++ /dev/null @@ -1,22 +0,0 @@ -const Endless = imports.gi.Endless; - -// Pull modules into this namespace, sort of like __init__.py and __all__ -this.WikipediaApplication = imports.wikipedia.WikipediaApplication.WikipediaApplication; -this.PrebuiltWikipediaApplication = imports.wikipedia.PrebuiltWikipediaApplication.PrebuiltWikipediaApplication; -this.PrebuiltFrontPage = imports.wikipedia.PrebuiltFrontPage.PrebuiltFrontPage; -this.PrebuiltCategoryPage = imports.wikipedia.PrebuiltCategoryPage.PrebuiltCategoryPage; -this.PrebuiltArticlesPage = imports.wikipedia.PrebuiltArticlesPage.PrebuiltArticlesPage; -this.ArticleList = imports.wikipedia.ArticleList.ArticleList; -this.WikipediaWebView = imports.wikipedia.WikipediaWebView.WikipediaWebView; - -const STYLE_CLASS_TITLE = 'title'; -const STYLE_CLASS_MAIN = 'main-element'; -const STYLE_CLASS_PREBUILT = 'prebuilt'; -const STYLE_CLASS_CATEGORY = 'category'; -const STYLE_CLASS_CATEGORY_CLICKABLE = 'clickable'; -const STYLE_CLASS_ARTICLE = 'article'; -const STYLE_CLASS_FRONT_PAGE = 'front-page'; -const STYLE_CLASS_CATEGORY_PAGE = 'category-page'; -const STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR = 'category-vertical-separator'; -const STYLE_CLASS_CATEGORY_HORIZONTAL_SEPARATOR = 'category-horizontal-separator'; -const STYLE_CLASS_ARTICLES_PAGE = 'articles-page'; diff --git a/wikipedia/Makefile.am.inc b/wikipedia/Makefile.am.inc deleted file mode 100644 index e4d1ad5..0000000 --- a/wikipedia/Makefile.am.inc +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2013 Endless Mobile, Inc. - -# # # CONFIGURE SCRIPT # # # - -# Create a config.js file with the installed directory locations. Use the -# following sed script to replace $datadir inside the script, as suggested by -# the Autoconf manual; because $datadir and friends only work inside Makefiles. -wikipedia_edit = sed \ - -e 's|@datadir[@]|$(datadir)|g' \ - $(NULL) -wikipedia/config.js: wikipedia/config.js.in Makefile - $(AM_V_GEN)mkdir -p wikipedia && \ - rm -f $@ $@.tmp && \ - $(wikipedia_edit) $< >$@.tmp && \ - chmod +x $@.tmp && \ - chmod a-w $@.tmp && \ - mv $@.tmp $@ -CLEANFILES += wikipedia/config.js -EXTRA_DIST += wikipedia/config.js.in - -# # # INSTALL RULES # # # - -js_sources = \ - wikipedia/ArticleList.js \ - wikipedia/widgets/BackButton.js \ - wikipedia/widgets/category_back_button.js \ - wikipedia/widgets/composite_button.js \ - wikipedia/widgets/FixedSizeTextView.js \ - wikipedia/EndlessWikipedia.js \ - wikipedia/PrebuiltArticlesPage.js \ - wikipedia/PrebuiltCategoryPage.js \ - wikipedia/PrebuiltFrontPage.js \ - wikipedia/PrebuiltWikipediaApplication.js \ - wikipedia/widgets/ListTextButton.js \ - wikipedia/config.js \ - wikipedia/utils.js \ - wikipedia/WikipediaApplication.js \ - wikipedia/models/article_model.js \ - wikipedia/models/category_model.js \ - wikipedia/models/domain_wiki_model.js \ - wikipedia/models/utils/json_utils.js \ - wikipedia/models/utils/locale_utils.js \ - wikipedia/presenters/domain_wiki_presenter.js \ - wikipedia/widgets/category_button.js \ - wikipedia/widgets/category_layout_manager.js \ - wikipedia/widgets/category_selector_view.js \ - wikipedia/views/domain_wiki_view.js \ - wikipedia/WikipediaWebView.js \ - $(NULL) - -wikipediadir = $(gjsmodulesdir) -nobase_dist_wikipedia_DATA = \ - $(js_sources) \ - $(NULL) diff --git a/wikipedia/PrebuiltArticlesPage.js b/wikipedia/PrebuiltArticlesPage.js deleted file mode 100644 index c982e99..0000000 --- a/wikipedia/PrebuiltArticlesPage.js +++ /dev/null @@ -1,76 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const PrebuiltArticlesPage = new Lang.Class({ - Name: 'PrebuiltArticlesPage', - Extends: Gtk.Frame, - Properties: { - 'article-title': GObject.ParamSpec.string('article-title', - 'Article title', - 'Human-readable title for the article to be displayed', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - 'article-uri': GObject.ParamSpec.string('article-uri', - 'Article URI', - 'Wikipedia URI for the article to be displayed', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - '') - }, - - _init: function(props) { - this._article_title = null; - this._article_uri = null; - - // Empty array is placeholder until we get baby page rank - this._wiki_view = new EndlessWikipedia.WikipediaWebView({ - expand: true, - hide_links: true - }); - - this.parent(props); - - this.add(this._wiki_view); - - // Add style contexts for CSS - let context = this.get_style_context(); - context.add_class(EndlessWikipedia.STYLE_CLASS_ARTICLES_PAGE); - }, - - setShowableLinks: function(linked_articles) { - this._wiki_view.setShowableLinks(linked_articles); - }, - - set_app_name: function (app_name) { - this._wiki_view.app_name = app_name; - }, - - set_personality: function (personality) { - this._wiki_view.system_personality = personality; - }, - - get article_title() { - return this._article_title; - }, - - set article_title(value) { - this._article_title = value; - }, - - get article_uri() { - return this._article_uri; - }, - - set article_uri(value) { - this._article_uri = value; - if(value !== null && value !== "") { - let url_parts = this._article_uri.split("/"); - let suffix = decodeURI(url_parts[url_parts.length-1]); - this._wiki_view.loadArticleById(suffix); - } - } -});
\ No newline at end of file diff --git a/wikipedia/PrebuiltCategoryPage.js b/wikipedia/PrebuiltCategoryPage.js deleted file mode 100644 index bc5fe28..0000000 --- a/wikipedia/PrebuiltCategoryPage.js +++ /dev/null @@ -1,163 +0,0 @@ -const Endless = imports.gi.Endless; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const CategoryBackButton = imports.wikipedia.widgets.category_back_button; -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const FixedSizeTextView = imports.wikipedia.widgets.FixedSizeTextView; - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const PrebuiltCategoryPage = new Lang.Class({ - Name: 'PrebuiltCategoryPage', - Extends: Gtk.Frame, - Properties: { - 'title': GObject.ParamSpec.string('title', - 'Name of category', - 'Name of the category to be displayed at the top of the category page', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - 'description': GObject.ParamSpec.string('description', - 'Description', - 'Description of the category (excerpt from Wiki text)', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - // resource URI for the category's accompanying image - 'image-uri': GObject.ParamSpec.string('image-uri', - 'Image URI', - 'Resource URI for the image file accompanying the category', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - '') - }, - - Signals: { - 'go-back-home':{} - }, - - _get_info_box: function(){ - this._title_label = new Gtk.Label({ - name: 'category-title', - expand: false, - halign: Gtk.Align.START, - xalign: 0.0, // deprecated Gtk.Misc property; necessary because - wrap: true, // "wrap" doesn't respect "halign" - width_chars: 15, - max_width_chars: 18 - }); - - let description_separator = new Gtk.Frame(); - description_separator.get_style_context().add_class( - EndlessWikipedia.STYLE_CLASS_CATEGORY_HORIZONTAL_SEPARATOR); - - this._description_text_view = new FixedSizeTextView.FixedSizeTextView({ - name: 'category-description', - sensitive: false, - editable: false, - cursor_visible: false, - pixels_inside_wrap: 10, - wrap_mode: Gtk.WrapMode.WORD - }); - - let description_scrolled_window = new Gtk.ScrolledWindow({ - name: 'category-scrolled-window', - halign: Gtk.Align.FILL, - vexpand: true, - hscrollbar_policy: Gtk.PolicyType.NEVER, - vscrollbar_policy: Gtk.PolicyType.AUTOMATIC - }); - description_scrolled_window.add(this._description_text_view); - - // Would rather have a more lightweight widget here like alignment, - // but alignment doesn't seem to respect padding and margin - let description_alignment = new Gtk.Frame({ - name: 'category-description-align' - }); - description_alignment.add(description_scrolled_window); - - let vertical_separator = new Gtk.Frame(); - vertical_separator.get_style_context().add_class( - EndlessWikipedia.STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR); - - let grid = new Gtk.Grid(); - grid.attach(this._title_label, 0, 0, 1, 1); - grid.attach(description_separator, 0, 1, 1, 1); - grid.attach(description_alignment, 0, 2, 1, 1); - grid.attach(vertical_separator, 1, 0, 1, 3); - - let frame = new Gtk.Frame({ - name: 'category-info', - vexpand: true - }); - frame.add(grid); - return frame; - }, - - _init: function(props) { - this._title = null; - this._description = null; - this._category_provider = new Gtk.CssProvider(); - this.parent(props); - - let info_box = this._get_info_box(); - - let back_button = new CategoryBackButton.CategoryBackButton({ - name: 'category-back-button', - expand: true, - halign: Gtk.Align.START, - valign: Gtk.Align.FILL - }); - back_button.connect('clicked', Lang.bind(this, function() { - this.emit('go-back-home'); - })); - - let vertical_separator = new Gtk.Frame(); - vertical_separator.get_style_context().add_class( - EndlessWikipedia.STYLE_CLASS_CATEGORY_VERTICAL_SEPARATOR); - - let grid = new Gtk.Grid({ - orientation: Gtk.Orientation.HORIZONTAL - }); - grid.add(back_button); - grid.add(vertical_separator); - grid.add(info_box); - this.add(grid); - - // Add style contexts for CSS - let context = this.get_style_context(); - context.add_class(EndlessWikipedia.STYLE_CLASS_CATEGORY_PAGE); - }, - - get title() { - return this._title; - }, - - set title(value) { - this._title = value; - if(this._title_label) - this._title_label.label = value.toUpperCase(); - }, - - get description() { - return this._description; - }, - - set description(value) { - this._description = value; - if(this._description_text_view) - this._description_text_view.buffer.set_text(value, -1); - }, - - get image_uri(){ - return this._image_uri; - }, - - set image_uri(value){ - if (value) { - let frame_css = "#category_frame{background-image: url('" + value + "');background-repeat:no-repeat;background-size:cover;}"; - this._category_provider.load_from_data(frame_css); - let context = this.get_style_context(); - context.add_provider(this._category_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - } - } -}); diff --git a/wikipedia/PrebuiltFrontPage.js b/wikipedia/PrebuiltFrontPage.js deleted file mode 100644 index 828cbf3..0000000 --- a/wikipedia/PrebuiltFrontPage.js +++ /dev/null @@ -1,61 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const CategorySelectorView = imports.wikipedia.widgets.category_selector_view; - -const TITLE_CATEGORY_COLUMN_SPACING = 10; // pixels - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const PrebuiltFrontPage = new Lang.Class({ - Name: 'PrebuiltFrontPage', - Extends: Gtk.Grid, - Signals: { - 'category-chosen': { - param_types: [GObject.TYPE_STRING] - } - }, - - _init: function(props) { - - this._category_selector = new CategorySelectorView.CategorySelectorView(); - - props = props || {}; - props.orientation = Gtk.Orientation.HORIZONTAL; - props.column_spacing = TITLE_CATEGORY_COLUMN_SPACING; - this.parent(props); - - this.add(this._category_selector); - this._category_selector.connect('category-chosen', - Lang.bind(this, this._onCategoryChosen)); - }, - - get title() { - return this._title; - }, - - set title(value) { - this._title = value; - this._title_label.title = value; - }, - - get image_uri() { - return this._image_uri; - }, - - set image_uri(value) { - this._image_uri = value; - this._title_label.image_uri = value; - }, - - setCategories: function(categories) { - this._category_selector.setCategories(categories); - }, - - // Proxy signal - _onCategoryChosen: function(widget, categoryId) { - this.emit('category-chosen', categoryId); - } -});
\ No newline at end of file diff --git a/wikipedia/PrebuiltWikipediaApplication.js b/wikipedia/PrebuiltWikipediaApplication.js deleted file mode 100644 index dcfcfd4..0000000 --- a/wikipedia/PrebuiltWikipediaApplication.js +++ /dev/null @@ -1,28 +0,0 @@ -const Endless = imports.gi.Endless; -const Format = imports.format; -const Lang = imports.lang; -const Gtk = imports.gi.Gtk; - -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const DomainWikiView = imports.wikipedia.views.domain_wiki_view; -const DomainWikiModel = imports.wikipedia.models.domain_wiki_model; -const DomainWikiPresenter = imports.wikipedia.presenters.domain_wiki_presenter; - -String.prototype.format = Format.format; - -const PrebuiltWikipediaApplication = new Lang.Class({ - Name: 'PrebuiltWikipediaApplication', - Extends: EndlessWikipedia.WikipediaApplication, - - _init: function(props) { - this.parent(props); - }, - - vfunc_startup: function() { - this.parent(); - this._domain_wiki_view = new DomainWikiView.DomainWikiView(this); - let app_filename = this.application_uri; - let linked_articles_filename = this.linked_articles_uri; - this._domain_wiki_presenter = new DomainWikiPresenter.DomainWikiPresenter(this._domain_wiki_model, this._domain_wiki_view, app_filename, linked_articles_filename); - } -}); diff --git a/wikipedia/WikipediaApplication.js b/wikipedia/WikipediaApplication.js deleted file mode 100644 index e932ada..0000000 --- a/wikipedia/WikipediaApplication.js +++ /dev/null @@ -1,66 +0,0 @@ -const Endless = imports.gi.Endless; -const Gdk = imports.gi.Gdk; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; -const GObject = imports.gi.GObject; -const Gio = imports.gi.Gio; - -const Config = imports.wikipedia.config; -const DomainWikiModel = imports.wikipedia.models.domain_wiki_model; - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const WikipediaApplication = new Lang.Class({ - Name: 'WikipediaApplication', - Extends: Endless.Application, - Properties: { - // resource:// URI for the categories JSON file - 'application-uri': GObject.ParamSpec.string('application-uri', - 'Category file URI', - 'URI for the data file describing the categories and articles', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ''), - - // Name of the Wikipedia-based application, e.g. 'Brazil', 'Math' - 'application-name': GObject.ParamSpec.string('application-name', - 'Application name', - 'Name of the Wikipedia-based application', - GObject.ParamFlags.READABLE, - ''), - - // Name of the Wikipedia-based application, e.g. 'Brazil', 'Math' - 'application-base-path': GObject.ParamSpec.string('application-base-path', - 'Application Base Path', - 'Path to base directory where execution began', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ''), - - // resource:// URI for the linked articles JSON file - 'linked-articles-uri': GObject.ParamSpec.string('linked-articles-uri', - 'Linked articles file URI', - 'URI for the data file describing which articles can have their links shown', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - '') - }, - - _init: function(props) { - this.parent(props); - }, - - // VIRTUAL FUNCTIONS - - vfunc_startup: function() { - // Load GResource bundle - let resource = Gio.Resource.load(Config.WIKIPEDIA_DATADIR + 'eos-wikipedia-domain.gresource'); - resource._register(); - - this.parent(); - this._domain_wiki_model = new DomainWikiModel.DomainWikiModel(); - - let provider = new Gtk.CssProvider(); - let css_file = Gio.File.new_for_uri('resource:///com/endlessm/wikipedia-domain/css/eos-wikipedia-domain.css') - provider.load_from_file(css_file); - Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - } - -}); diff --git a/wikipedia/WikipediaWebView.js b/wikipedia/WikipediaWebView.js deleted file mode 100644 index 03173b9..0000000 --- a/wikipedia/WikipediaWebView.js +++ /dev/null @@ -1,136 +0,0 @@ -const Gdk = imports.gi.Gdk; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const GObject = imports.gi.GObject; -const Lang = imports.lang; -const WebKit = imports.gi.WebKit2; -const Utils = imports.wikipedia.utils; - -const API_ENDPOINT = "http://127.0.0.1:3000"; -const API_VERSION = "v1"; -const getPageByIdURI = "getArticleById?"; -const getPageByTitleURI = "getArticleByTitle?"; -const getPageByQueryURI = "getTopArticleByQuery?"; -const getTitlesByQueryURI = "getArticleTitlesByQuery?"; - - -const WikipediaWebView = new Lang.Class({ - Name: 'EndlessWikipediaWebView', - Extends: WebKit.WebView, - Properties: { - 'hide-links': GObject.ParamSpec.boolean('hide-links', - 'Hide article links', - 'A boolean to determine whether links should be shown', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - false), - 'system-personality': GObject.ParamSpec.string('system-personality', - 'System Personality string', - 'Specifies the system personality to be used in this wiki webview', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ""), - 'app-name': GObject.ParamSpec.string('app-name', - 'Application name', - 'Specifies the application that is using this wiki webview', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ""), - }, - - _init: function(params) { - this.parent(params); - // For debugging - //let settings = this.get_settings(); - //settings.set_enable_developer_extras(true); - //this.set_settings(settings); - this.connect('context-menu', Lang.bind(this, function() {return true;})); - - this.connect('decide-policy', - Lang.bind(this, this._onNavigation)); - this.connect('load-changed', - Lang.bind(this, this._onLoadChange)); - }, - - setShowableLinks: function(linked_articles){ - this._links_to_show = linked_articles; - }, - - _getFullURL: function(method, params){ - // We always include personality and - // app name on all requests. - let base_url = [API_ENDPOINT, API_VERSION, method].join("/"); - params["personality"] = this.system_personality; - params["appname"] = this.app_name; - let full_url = base_url; - for(let key in params){ - full_url += key + "=" + params[key] + "&"; - } - // Remove the final '&' - full_url = full_url.slice(0, -1); - return full_url; - }, - - loadArticleById: function (id) { - let params = { - id: id, - hideLinks: this.hide_links - }; - let url = this._getFullURL(getPageByIdURI, params); - this.load_uri(url); - }, - - loadArticleBySearchQuery: function (query, source) { - let params = { - query: query, - hideLinks: this.hide_links, - source: source - }; - let url = this._getFullURL(getPageByQueryURI, params); - this.load_uri(url); - }, - - loadTitlesBySearchQuery: function (query) { - let params = { query: query }; - let url = this._getFullURL(getTitlesByQueryURI, params); - this.load_uri(url); - }, - - scriptFinished: function(){ - // NO OP - }, - - setAllowedLinks: function(){ - // If you want to show all links, then - // no point in showing some subset of them as well - if(!this.hide_links || this._links_to_show.length === 0){ - return; - } - let str = JSON.stringify(this._links_to_show); - let script = "window.links_to_show = " + str; - this.run_javascript(script, null, this.scriptFinished, null); - }, - - _onNavigation: function(webview, decision, decision_type) { - if (decision_type == WebKit.PolicyDecisionType.NAVIGATION_ACTION) { - let uri = decision.request.uri; - if (uri.startsWith(API_ENDPOINT + "/wiki/")) { - let parts = uri.split("/"); - let suffix = parts[parts.length - 1]; - let id = decodeURI(suffix); - this.loadArticleById(id); - decision.ignore(); - return true; // handled - } else if (GLib.uri_parse_scheme(uri).startsWith('browser-')) { - // Open everything that starts with 'browser-' in the system - // browser - let realURI = uri.slice('browser-'.length); - Gtk.show_uri(null, realURI, Gdk.CURRENT_TIME); - decision.ignore(); - return true; // handled - } - } - return false; // not handled, default behavior - }, - - _onLoadChange: function(webview, load_event, data){ - this.setAllowedLinks(); - } -}); diff --git a/wikipedia/config.js.in b/wikipedia/config.js.in deleted file mode 100644 index 9ea8aab..0000000 --- a/wikipedia/config.js.in +++ /dev/null @@ -1,2 +0,0 @@ -this.DATADIR = '@datadir@'; -this.WIKIPEDIA_DATADIR = this.DATADIR + '/eos-wikipedia-domain/'; diff --git a/wikipedia/models/article_model.js b/wikipedia/models/article_model.js deleted file mode 100644 index c74da17..0000000 --- a/wikipedia/models/article_model.js +++ /dev/null @@ -1,104 +0,0 @@ -const Endless = imports.gi.Endless; -const GObject = imports.gi.GObject; -const Lang = imports.lang; - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const ArticleModel = new Lang.Class({ - Name: "ArticleModel", - Extends: GObject.Object, - Properties: { - 'title': GObject.ParamSpec.string('title', 'Article Title', 'Human Readable Article Title', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ""), - 'source': GObject.ParamSpec.string('source', 'Source', - 'Source website or database that the article is from', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ''), - 'uri': GObject.ParamSpec.string('uri', 'Article URI', 'Title URI as stored in wikipedia database', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - "") - }, - - _init: function(params) { - this._categoryList = []; - this.parent(params); - }, - - /** - * Method: setCategories - * Give this article a list of categories or tags - * - * Parameters: - * categoryList - an array of strings signifying category IDs - * - * Makes this article's categories the list signified by _categoryList_, - * wiping out any categories that were previously set. - */ - setCategories: function (categoryList) { - this._categoryList = categoryList; - }, - - /** - * Method: addCategory - * Attach a category or tag to this article - * - * Parameters: - * categoryId - a string signifying a category ID - * - * Tags this article with _categoryID_. - * Does nothing if this article is already tagged with that ID. - */ - addCategory: function (categoryId) { - if (!this.hasCategory(categoryId)) - this._categoryList.push(categoryId); - }, - - /** - * Method: getCategories - * List of this article's categories or tags - * - * Returns: - * An array of strings signifying category IDs. - */ - getCategories: function () { - return this._categoryList; - }, - - /** - * Method: hasCategory - * Whether this article is tagged with a particular ID - * - * Parameters: - * categoryId - a string signifying a category ID - * - * Returns: - * true if this article is tagged with _categoryId_, false if not. - */ - hasCategory: function (categoryId) { - return this._categoryList.indexOf(categoryId) != -1; - } - -}); - -/** - * Function: newFromJson - * Construct a new <ArticleModel> from data exported by the CMS - * - * Parameters: - * json - a category object created by parsing the JSON file - * - * Returns: - * A newly created <ArticleModel>. - * - * See <DomainWikiModel.loadFromJson> for the structure of the JSON object. - */ -function newFromJson(json) { - let retval = new ArticleModel({ - title: json['title'], - source: json['source'], - uri: json['url'] - }); - retval.setCategories(json['categories']); - return retval; -} diff --git a/wikipedia/models/category_model.js b/wikipedia/models/category_model.js deleted file mode 100644 index a17c9ac..0000000 --- a/wikipedia/models/category_model.js +++ /dev/null @@ -1,114 +0,0 @@ -const Endless = imports.gi.Endless; -const GObject = imports.gi.GObject; -const Lang = imports.lang; - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const CategoryModel = new Lang.Class({ - Name: "CategoryModel", - Extends: GObject.Object, - Properties: { - /** - * Property: id - * String for referring to this category internally - * - * Can generally be equal to <CategoryModel.title>, though that is not - * required. - */ - 'id': GObject.ParamSpec.string('id', 'ID string', - 'String for referring to this category internally', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ''), - 'description': GObject.ParamSpec.string('description', 'Category Description', 'This is the text that the user reads on the category page.', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ""), - 'title': GObject.ParamSpec.string('title', 'Category Name', 'This is the name that is displayed on the front page and as the title on the category page.', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ""), - 'image-uri': GObject.ParamSpec.string('image-uri', 'Category Image URI', 'Path to image for this category in the GResource', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ""), - 'image-thumbnail-uri': GObject.ParamSpec.string('image-thumbnail-uri', 'Category Thumbnail Image URI', 'Path to thumbnail image for this category in the GResource', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - ""), - 'is-main-category': GObject.ParamSpec.boolean('is-main-category', 'Is Main Category boolean', 'Flag denoting whether this category is the main category for this app', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - false), - /** - * Property: has_articles - * Whether this category contains articles - * - * This property is not computed in any way, but is set by the library - * model when loading from a JSON file. - * This value is used to determine whether a category should be - * clickable, for example. - */ - 'has-articles': GObject.ParamSpec.boolean('has-articles', - 'Has articles', - 'Indicates whether category has any articles under it', - GObject.ParamFlags.READWRITE, - false) - }, - - _init: function(params) { - this._subcategories = {}; - this.parent(params); - }, - - /** - * Method: addSubcategory - * Add a subcategory to this model - * - * Parameters: - * modelObj - another <CategoryModel> that is to be a subcategory of this - * one. - * - * Does nothing if this category already has a subcategory with _modelObj_'s - * ID. - */ - addSubcategory: function (modelObj) { - if (!this._subcategories.hasOwnProperty(modelObj.id)) { - this._subcategories[modelObj.id] = modelObj; - } - }, - - /** - * Method: getSubcategories - * List this model's subcategories - * - * Returns: - * An array of <CategoryModels> representing this category's - * subcategories, or an empty array if there are none. - */ - getSubcategories: function () { - let retval = []; - for (let id in this._subcategories) { - retval.push(this._subcategories[id]); - } - return retval; - } -}); - -/** - * Function: newFromJson - * Construct a new <CategoryModel> from data exported by the CMS - * - * Parameters: - * json - a category object created by parsing the JSON file - * - * Returns: - * A newly created <CategoryModel> with no subcategories. - * - * See <DomainWikiModel.loadFromJson> for the structure of the JSON object. - */ -function newFromJson(json) { - let retval = new CategoryModel({ - id: json['category_name'], - description: json['content_text'], - title: json['category_name'], - image_uri: json['image_file'], - image_thumbnail_uri: json['image_thumb_uri'], - is_main_category: json['is_main_category'] - }); - return retval; -} diff --git a/wikipedia/models/domain_wiki_model.js b/wikipedia/models/domain_wiki_model.js deleted file mode 100644 index ef41d3e..0000000 --- a/wikipedia/models/domain_wiki_model.js +++ /dev/null @@ -1,159 +0,0 @@ - -const Endless = imports.gi.Endless; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Lang = imports.lang; - -// Local libraries -const ArticleModel = imports.wikipedia.models.article_model; -const CategoryModel = imports.wikipedia.models.category_model; - -const DomainWikiModel = new Lang.Class({ - - Name: "DomainWikiModel", - Extends: GObject.Object, - - _init: function(params) { - this._articles = []; - this._mainCategory = null; - this._linked_articles = undefined; - this._categories = {}; - this.parent(params); - }, - - /** - * Method: loadFromJson - * Populate the model from the CMS's exported JSON file - * - * Parameters: - * json - an object created by parsing the JSON file - * - * Call this once, when creating the model, to populate it using the JSON - * file defining the categories and articles. - * The JSON file adheres to the following format: - * - * > <MAIN> = - * > { - * > "categories": [ <CATEGORY>, <CATEGORY>, ... ], - * > "articles": [ <ARTICLE>, <ARTICLE>, ... ] - * > } - * > <CATEGORY> = - * > { - * > "category_name": <string>, - * > "content_text": <string>, - * > "image_file": <string>, - * > "image_thumb_uri": <string>, - * > "is_main_category": <boolean>, - * > "subcategories": [ <string>, <string>, ... ] - * > } - * - * "subcategories" is a list of "category_name" strings from other - * categories. - * "subcategories" can be empty. - * "is_main_category" will probably disappear from a future version. - * - * > <ARTICLE> = - * > { - * > "title": <string>, - * > "url": <string>, - * > "categories": [ <string>, <string>, ... ], - * > } - * - * "categories" is a list of "category_name" strings from the categories this - * article is associated with. - * "categories" can be empty, but generally should not. - */ - loadFromJson: function (json) { - // Load list of articles - this._articles = json['articles'].map(function (article) { - return ArticleModel.newFromJson(article); - }); - - // First create flat list of category models, indexed by ID - json['categories'].forEach(function (category) { - let modelObj = CategoryModel.newFromJson(category); - if (modelObj.is_main_category) - this._mainCategory = modelObj; - this._categories[modelObj.id] = modelObj; - modelObj.has_articles = this._getCategoryHasArticles(modelObj.id); - }, this); - // Create links between all the category models in a tree - json['categories'].forEach(function (category) { - category['subcategories'].forEach(function(subcatId) { - this._categories[category['category_name']].addSubcategory( - this._categories[subcatId]); - }, this); - }, this); - }, - - setLinkedArticles:function(articles){ - this._linked_articles = articles; - }, - - getLinkedArticles:function(){ - if(this._linked_articles !== undefined) - return this._linked_articles["app_articles"].concat(this._linked_articles["extra_linked_articles"]); - else - return []; - }, - - /** - * Method: getArticles - * Articles available in this library - */ - getArticles: function () { - return this._articles; - }, - - /** - * Method: getArticlesForCategory - * Articles belonging to a category in this library - * - * Parameters: - * id - The string ID of a category - * - * Returns: - * An array of <ArticleModels> belonging to the category signified by _id_ - * or an empty array if there were none or _id_ was not found - */ - getArticlesForCategory: function (id) { - return this._articles.filter(function (article) { - return article.getCategories().indexOf(id) != -1; - }); - }, - - // A faster version of getArticlesForCategory() that just returns true if - // there were any articles in this category - _getCategoryHasArticles: function (id) { - return this._articles.some(function (article) { - return article.getCategories().indexOf(id) != -1; - }); - }, - - /** - * Method: getCategory - * Category corresponding to a string ID - * - * Parameters: - * id - The string ID of a category - * - * Returns: - * A <CategoryModel> that corresponds to _id_, or undefined if _id_ was - * not found. - */ - getCategory: function (id) { - return this._categories[id]; - }, - - /** - * Method: getMainCategory - * Category marked as "main" for this library - * - * Returns: - * A <CategoryModel> that has been marked as the "main" category, or null - * if the main category has not been set yet. - */ - getMainCategory: function () { - return this._mainCategory; - } -}); diff --git a/wikipedia/models/utils/json_utils.js b/wikipedia/models/utils/json_utils.js deleted file mode 100644 index b66b388..0000000 --- a/wikipedia/models/utils/json_utils.js +++ /dev/null @@ -1,56 +0,0 @@ -const Gio = imports.gi.Gio; -const Json = imports.gi.Json; -const Gettext = imports.gettext; - -const _JSON_VAL_STRING = 0; -const _JSON_VAL_INT = 1; -const _JSON_VAL_DOUBLE = 2; -const _JSON_VAL_BOOLEAN = 3; - - -function getJsonMemberStringValue(reader, key) { - - return _getJsonMemberValue(reader, key, _JSON_VAL_STRING); -} - -function getJsonMemberIntValue(reader, key) { - - return _getJsonMemberValue(reader, key, _JSON_VAL_INT); -} - -function getJsonMemberDoubleValue(reader, key) { - - return _getJsonMemberValue(reader, key, _JSON_VAL_DOUBLE); -} - -function getJsonMemberBooleanValue(reader, key) { - - return _getJsonMemberValue(reader, key, _JSON_VAL_BOOLEAN); -} - -function getJsonMemberLocalizedValue(reader, key) { - - return Gettext.gettext(_getJsonMemberValue(reader, key + '_', _JSON_VAL_STRING)); -} - -function _getJsonMemberValue(reader, key, type) { - - reader.read_member(key); - let value; - switch(type) { - case _JSON_VAL_STRING: - value = reader.get_string_value(); - break; - case _JSON_VAL_INT: - value = reader.get_int_value(); - break; - case _JSON_VAL_DOUBLE: - value = reader.get_double_value(); - break; - case _JSON_VAL_BOOLEAN: - value = reader.get_boolean_value(); - break; - } - reader.end_member(); - return value; -} diff --git a/wikipedia/models/utils/locale_utils.js b/wikipedia/models/utils/locale_utils.js deleted file mode 100644 index 71d177a..0000000 --- a/wikipedia/models/utils/locale_utils.js +++ /dev/null @@ -1,19 +0,0 @@ -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; - - -function getSubdirectoryWithLocale(theDir) { - - let locales = GLib.get_language_names(); - let dir = Gio.File.new_for_path(theDir); - let localeSegment = 'C'; - - for(let i=0; i<locales.length; i++) { - let currLocale = dir.get_child(locales[i]); - if(currLocale.query_exists(null)) { - localeSegment = locales[i]; - break; - } - } - return theDir + localeSegment + '/'; -}
\ No newline at end of file diff --git a/wikipedia/presenters/domain_wiki_presenter.js b/wikipedia/presenters/domain_wiki_presenter.js deleted file mode 100644 index 66701d2..0000000 --- a/wikipedia/presenters/domain_wiki_presenter.js +++ /dev/null @@ -1,110 +0,0 @@ -const Endless = imports.gi.Endless; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Lang = imports.lang; -const System = imports.system; - -//Local Libraries -const Utils = imports.wikipedia.utils; - -const CategoryModel = imports.wikipedia.models.category_model; -const ArticleModel = imports.wikipedia.models.article_model; - - -function _resourceUriToPath(uri) { - if(uri.startsWith('resource://')) - return uri.slice('resource://'.length); - throw new Error('Resource URI did not start with "resource://"'); -} - -function _pathnameToAppName(uri) { - let parts = uri.split("/"); - let filename = parts[parts.length-1]; - // Split by both dashes and periods in order - // to retrieve, e.g. 'health' from 'health-Guatemala.json' - let filename_parts = filename.split(/[\-\.]/); - return filename_parts[0]; -} - -const DomainWikiPresenter = new Lang.Class({ - Name: "DomainWikiPresenter", - Extends: GObject.Object, - - _init: function(model, view, app_filename, linked_articles_filename) { - this._model = model; - this._view = view; - this._view.set_presenter(this); - this._view.connect('category-chosen', - Lang.bind(this, this._onCategoryClicked)); - this._view.connect('article-chosen', - Lang.bind(this, this._onArticleClicked)); - this._view.connect('category-back-clicked', - Lang.bind(this, this._onCategoryBackClicked)); - this._view.connect('article-back-clicked', - Lang.bind(this, this._onArticleBackClicked)); - - this.initAppInfoFromJsonFile(app_filename); - - if(linked_articles_filename !== '') - this.initPageRankFromJsonFile(linked_articles_filename); - - let firstLevel = this._model.getMainCategory().getSubcategories(); - firstLevel.push(this._model.getMainCategory()); - this._view.set_categories(firstLevel); - - let to_show = this._model.getLinkedArticles(); - this._view.set_showable_links(to_show); - - let app_name = _pathnameToAppName(app_filename); - let personality = Endless.get_system_personality(); - - this._view.set_personality(personality); - this._view.set_app_name(app_name); - this.parent(); - }, - - initPageRankFromJsonFile: function(filename){ - let articles = JSON.parse(Utils.load_file_from_resource(filename)); - this._model.setLinkedArticles(articles); - }, - - initAppInfoFromJsonFile: function(filename) { - try { - let app_content = JSON.parse(Utils.load_file_from_resource(filename)); - this._model.loadFromJson(app_content); - } catch(e) { - print(e); - if (e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { - print("****** This app does not support the personality", - Endless.get_system_personality(), "******"); - } - System.exit(1); - } - }, - - // Respond to the front page's 'category-clicked' signal by loading the - // articles belonging to that category and switching to the category page - _onCategoryClicked: function (page, categoryId) { - let newCategory = this._model.getCategory(categoryId); - let articles = this._model.getArticlesForCategory(categoryId); - - this._view.set_category_info(newCategory, articles); - - this._view.show_category_page(); - }, - - // Respond to the category page's 'article-clicked' signal by loading that - // article and switching to the article page - _onArticleClicked: function (articleList, title, uri) { - this._view.set_article_info(title, uri); - this._view.show_article_page(); - }, - - _onCategoryBackClicked: function(button) { - this._view.show_front_page(); - }, - - _onArticleBackClicked: function(button) { - this._view.show_category_page(); - } -}); diff --git a/wikipedia/utils.js b/wikipedia/utils.js deleted file mode 100644 index 0838bd5..0000000 --- a/wikipedia/utils.js +++ /dev/null @@ -1,199 +0,0 @@ -const Gio = imports.gi.Gio; -const GdkPixbuf = imports.gi.GdkPixbuf; -const GLib = imports.gi.GLib; - -const set_default = function(obj, key, val) { - // Similar to python's dict.setdefault(key, val) - if(obj[key] === undefined) - obj[key] = val; -} - -const default_param = function(variable, defaultValue) { - // Emulate python's default parameter values - if(variable === undefined) - return defaultValue; - else - return variable; -} - -const range = function(a, b, step) { - // Emulate python's range function - var A = []; - if(typeof a == 'number'){ - if(typeof b == 'undefined'){ - b = a - 1; - a = 0; - } - A[0] = a; - step = step || 1; - while(a + step < b){ - A[A.length] = a += step; - } - } - return A; -} - -/* - * ...Taken from utils.js from the eos-weather branch... - */ -function load_file_from_resource(filename) { - // Return the text stored in the file at filename - var file = Gio.file_new_for_uri(filename); - var fstream = file.read(null); - var dstream = new Gio.DataInputStream({ - base_stream: fstream - }); - var data = dstream.read_until("", null); - fstream.close(null); - return data[0]; -} - -function get_path_for_relative_path(relative_path){ - let file = Gio.file_new_for_path(relative_path); - return file.get_path(); -} - -function write_contents_to_file(filename, content){ - let file = Gio.file_new_for_path(filename); - file.replace_contents(content, null, false, 0, null); - return file.get_uri(); -} - -function write_contents_to_temp_file(name, content){ - let file = Gio.file_new_tmp("XXXXXX" + name)[0]; - file.replace_contents(content, null, false, 0, null); - return file.get_uri(); -} - -function make_temp_dir(name){ - return GLib.dir_make_tmp(name + "XXXXXX"); -} - -/* - * ...Taken from utils.js from the eos-weather branch... - */ -function load_file(filename) { - // Return the text stored in the file at filename - var file = Gio.file_new_for_path(filename); - var fstream = file.read(null); - var dstream = new Gio.DataInputStream({ - base_stream: fstream - }); - var data = dstream.read_until("", null); - fstream.close(null); - return data[0]; -} - -/* - * Compares two lists *a* and *b* to see if they contain - * the same contents, ignoring order. Contents are defined - * to be equal via JSON representation, unless they are - * primitives, then String() casting is used. - * - * If passed non-list objects, this method has undefined - * behavior. Algorithm is not exceptionally optimized and has - * O(n^2) performance. - * - * Method treats elements that are logically equivalent but - * not type-equivalent to be the same. Thus the string of - * "3" is considered to equal the integer 3 in these comparisons. - * - * Returns true if a and b contain the same elements in - * any order. - */ -const set_equals = function (a, b) { - if (typeof a != "object" || typeof b != "object") { - return false; - } - if (a.length != b.length) { - // Optimization - return false; - } - let matched_of_a = 0; - for (let i = 0; i < a.length; i++) { - let i_string = typeof a[i] == "object" ? JSON.stringify (a[i]) : String(a[i]); - for (let j = 0; j < b.length; j++) { - let j_string = typeof b[j] == "object" ? JSON.stringify (b[j]) : String(b[j]); - if (j_string == i_string) { - matched_of_a++; - } - } - } - let matched_of_b = 0; - for (let i = 0; i < b.length; i++) { - let i_string = typeof b[i] == "object" ? JSON.stringify (b[i]) : String(b[i]); - for (let j = 0; j < a.length; j++) { - let j_string = typeof a[j] == "object" ? JSON.stringify (a[j]) : String(a[j]); - if (j_string == i_string) { - matched_of_b++; - } - } - } - if (matched_of_a == a.length && - matched_of_b == matched_of_a) - { - return true; - } - return false; -}; - -/* - * Checks to see if an array *arr* contains on element *obj*. If - * *same_type* is provided (and is true), the objects must - * actually be the same type as well to be considered part of the - * array. - * - * Somehow reminds the user of a pirate. - */ -const array_contains = function (arr, obj, same_type) { - if (same_type == true) { - for (let i = 0; i < arr.length; i++) { - if (arr[i] === obj) { - return true; - } - } - } else { - for (let i = 0; i < arr.length; i++) { - if (arr[i] == obj) { - return true; - } - } - } - return false; -}; - -/* - * Loads a pixbuf sized to cover the dest_width and dest_height with the - * image in res_path, while mataining the aspect ratio of the image. - * The anchor point for cropping is the bottom left of the image. - */ -function load_pixbuf_cover(res_path, dest_width, dest_height) { - let [load_width, load_height] = [dest_width, dest_height]; - // TODO: We need to get the size of the source image, so right now we - // are loading the image twice, once to get the size, and the again at - // the proper size. We should eventually use a GdkPixbuf.Loader and - // connect to the size-prepared signal, as described in the - // documentation - let temp_pixbuf = GdkPixbuf.Pixbuf.new_from_resource(res_path); - let source_aspect = temp_pixbuf.width / temp_pixbuf.height; - let dest_aspect = dest_width / dest_height; - if(dest_aspect > source_aspect) - load_height = -1; - else - load_width = -1; - let source_pixbuf = GdkPixbuf.Pixbuf.new_from_resource_at_scale(res_path, - load_width, load_height, true); - let cropped_pixbuf = source_pixbuf; - if(dest_width < source_pixbuf.width || dest_height < source_pixbuf.height) - cropped_pixbuf = source_pixbuf.new_subpixbuf(0, source_pixbuf.height - dest_height, - dest_width, dest_height); - return cropped_pixbuf; -} - -// Convenience function to convert a resource URI to a resource path, for -// APIs that expect a path rather than an URI -function resourceUriToPath(uri) { - if(uri.startsWith('resource://')) - return uri.slice('resource://'.length); - throw new Error('Resource URI did not start with "resource://"'); -} diff --git a/wikipedia/views/domain_wiki_view.js b/wikipedia/views/domain_wiki_view.js deleted file mode 100644 index 06a936d..0000000 --- a/wikipedia/views/domain_wiki_view.js +++ /dev/null @@ -1,267 +0,0 @@ -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const Lang = imports.lang; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Gdk = imports.gi.Gdk; -const GLib = imports.gi.GLib; -const Endless = imports.gi.Endless; - -const BackButton = imports.wikipedia.widgets.BackButton; - -const SIDEBAR_BACK_BUTTON_URI = "/com/endlessm/wikipedia-domain/assets/image_strip_back_button.png"; -const SUBMENU_SEPARATOR_A_URI = "/com/endlessm/wikipedia-domain/assets/submenu_separator_shadow_a.png"; -const SUBMENU_SEPARATOR_B_URI = "/com/endlessm/wikipedia-domain/assets/submenu_separator_shadow_b.png"; - -const DomainWikiView = new Lang.Class({ - Name: "DomainWikiView", - Extends: GObject.Object, - Signals: { - 'category-chosen': { - param_types: [GObject.TYPE_STRING] - }, - 'article-chosen': { - param_types: [GObject.TYPE_STRING, GObject.TYPE_STRING] - }, - 'category-back-clicked': {}, - 'article-back-clicked': {} - }, - - _init: function(application) { - this.parent(); - this._presenter = null; - - this._window = new Endless.Window({ - 'application': application, - 'font-scaling-active': true - }); - - // These need to be called first - this.create_front_page(); - this.create_category_page(); - this.create_article_page(); - - this._window.page_manager.transition_duration = 200; // ms - this._window.page_manager.add(this._front_page, { - name: 'front' - }); - - this._window.page_manager.add(this._category_page, { - name: 'category', - left_topbar_widget: this._category_back_button - }); - - this._window.page_manager.add(this._article_page, { - name: 'article', - left_topbar_widget: this._article_back_button - }) - - this._window.show_all(); - }, - - create_front_page: function(){ - this._front_page = new EndlessWikipedia.PrebuiltFrontPage(); - this._front_page.connect('category-chosen', - Lang.bind(this, this._onCategoryClicked)); - }, - - create_article_page: function(){ - // Article page - this._article_page = new Gtk.Grid({ - orientation: Gtk.Orientation.HORIZONTAL - }); - - this._sidebar_frame = new Gtk.Frame({ - name: "sidebar_frame" - }); - this._sidebar_frame.set_size_request(40, -1); - - this._article_sidebar_back_button = new Gtk.Button({ - name: "side_bar_button", - vexpand: true, - image: new Gtk.Image({ - resource: SIDEBAR_BACK_BUTTON_URI - }) - }) - - this._article_view = new EndlessWikipedia.PrebuiltArticlesPage(); - this._article_list = new EndlessWikipedia.ArticleList({ - halign: Gtk.Align.START, - hexpand: false - }); - - this._submenu_separator_a = new Gtk.Image({ - halign: Gtk.Align.END, - resource: SUBMENU_SEPARATOR_A_URI - }); - - this._submenu_separator_b = new Gtk.Image({ - halign: Gtk.Align.START, - resource: SUBMENU_SEPARATOR_B_URI - }); - - this._overlay_left = new Gtk.Overlay(); - this._overlay_left.add(this._sidebar_frame); - this._overlay_left.add_overlay(this._submenu_separator_a); - this._overlay_left.add_overlay(this._article_sidebar_back_button); - - this._overlay_right = new Gtk.Overlay(); - this._overlay_right.add(this._article_view); - this._overlay_right.add_overlay(this._submenu_separator_b); - - this._article_page.add(this._overlay_left); - - this._article_page.add(this._article_list); - - this._article_page.add(this._overlay_right); - - this._article_back_button = new BackButton.BackButton(); - this._article_back_button.show(); - - this._article_list.connect('article-chosen', - Lang.bind(this, this._onArticleClicked)); - this._article_back_button.connect('clicked', - Lang.bind(this, this._onArticleBackClicked)); - this._article_sidebar_back_button.connect('clicked', Lang.bind(this, function() { - this._onArticleBackClicked(); - })); - }, - - create_category_page: function(){ - // Category page - this._category_page = new Gtk.Grid({ - orientation: Gtk.Orientation.HORIZONTAL - }); - this._category_view = new EndlessWikipedia.PrebuiltCategoryPage({ - name: "category_frame" - }); - // _category_article_list is eventually going to be the same widget as - // _article_list, so that's why it's not built into the - // PrebuiltCategoryPage - this._category_article_list = new EndlessWikipedia.ArticleList({ - halign: Gtk.Align.END, - hexpand: false - }); - this._category_page.add(this._category_view); - this._category_page.add(this._category_article_list); - - this._category_back_button = new BackButton.BackButton(); - this._category_back_button.show(); - - this._category_article_list.connect('article-chosen', - Lang.bind(this, this._onArticleClicked)); - - this._category_back_button.connect('clicked', - Lang.bind(this, this._onCategoryBackClicked)); - - this._category_view.connect('go-back-home', - Lang.bind(this, this._onCategoryBackClicked)); - }, - - _set_article_sidebar_uri: function(uri){ - let frame_css = "#sidebar_frame{background-image: url('" + uri + "');background-repeat:no-repeat;background-size:cover;}"; - let provider = new Gtk.CssProvider(); - provider.load_from_data(frame_css); - let context = this._sidebar_frame.get_style_context(); - context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - }, - - set_presenter: function(presenter) { - this._presenter = presenter; - }, - - set_category_info: function(category, articles) { - this._category_view.title = category.title; - this._category_view.description = category.description; - this._category_view.image_uri = category.image_uri; - - this._set_article_sidebar_uri(category.image_uri); - - this._category_article_list.setArticles(articles); - this._article_list.setArticles(articles); - this._article_back_button.label = category.title.toUpperCase(); - }, - - /** - * Method: set_article_info - * Proxy method to set the article displaying on the article page - */ - set_article_info: function (title, uri) { - // Note: Must set article title first - this._article_view.article_title = title; - this._article_view.article_uri = uri; - }, - - /** - * Method: show_front_page - * Transition to the front page of the view - */ - show_front_page: function () { - if (this._window.page_manager.visible_child_name === "front") - return; - this._window.page_manager.transition_type = Gtk.StackTransitionType.SLIDE_RIGHT; - this._window.page_manager.visible_child_name = "front"; - }, - - /** - * Method: show_category_page - * Transition to the category page of the view - */ - show_category_page: function () { - if (this._window.page_manager.visible_child_name === "category") - return; - this._category_article_list.scrollToTop(); - if (this._window.page_manager.visible_child_name === "front") - this._window.page_manager.transition_type = Gtk.StackTransitionType.SLIDE_LEFT; - else - this._window.page_manager.transition_type = Gtk.StackTransitionType.SLIDE_RIGHT; - this._window.page_manager.visible_child_name = "category"; - }, - - /** - * Method: show_article_page - * Transition to the article page of the view - */ - show_article_page: function () { - if (this._window.page_manager.visible_child_name === "article") - return; - this._article_list.scrollToTop(); - this._window.page_manager.transition_type = Gtk.StackTransitionType.SLIDE_LEFT; - this._window.page_manager.visible_child_name = "article"; - }, - - set_categories: function(categories){ - this._front_page.setCategories(categories); - }, - - set_showable_links: function(linked_articles){ - this._article_view.setShowableLinks(linked_articles); - }, - - set_app_name: function (app_name) { - this._article_view.set_app_name(app_name); - }, - - set_personality: function (personality) { - this._article_view.set_personality(personality); - }, - - // Proxy signal, respond to front page's 'category-chosen' signal by - // emitting our own - _onCategoryClicked: function (page, categoryId) { - this.emit('category-chosen', categoryId); - }, - - // Proxy signal, respond to category page's 'article-chosen' signal by - // emitting our own - _onArticleClicked: function (articleList, title, uri) { - this.emit('article-chosen', title, uri); - }, - - _onCategoryBackClicked: function(button) { - this.emit('category-back-clicked'); - }, - - _onArticleBackClicked: function(button) { - this.emit('article-back-clicked'); - } -}); diff --git a/wikipedia/widgets/BackButton.js b/wikipedia/widgets/BackButton.js deleted file mode 100644 index 2d44e3f..0000000 --- a/wikipedia/widgets/BackButton.js +++ /dev/null @@ -1,26 +0,0 @@ -const Endless = imports.gi.Endless; -const Gettext = imports.gettext; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const Config = imports.wikipedia.config; - -const _ = function(string) { return GLib.dgettext('eos-sdk', string); }; -Gettext.bindtextdomain('eos-sdk', Config.DATADIR + '/locale'); - -const BACK_BUTTON_URI = "resource://com/endlessm/wikipedia-domain/assets/topbar_back_icon_normal.png"; - -const BackButton = new Lang.Class({ - Name: 'BackButton', - Extends: Endless.AssetButton, - - _init: function(props) { - props = props || {}; - props.label = _("BACK"); - props.normal_image_uri = BACK_BUTTON_URI; - - this.parent(props); - } -}); diff --git a/wikipedia/widgets/FixedSizeTextView.js b/wikipedia/widgets/FixedSizeTextView.js deleted file mode 100644 index f655d88..0000000 --- a/wikipedia/widgets/FixedSizeTextView.js +++ /dev/null @@ -1,14 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const CATEGORY_DESCRIPTION_WIDTH = 520; - -const FixedSizeTextView = new Lang.Class({ - Name: "FixedSizeTextView", - Extends: Gtk.TextView, - - vfunc_get_preferred_width: function(){ - return [CATEGORY_DESCRIPTION_WIDTH, CATEGORY_DESCRIPTION_WIDTH]; - } -}); diff --git a/wikipedia/widgets/ListTextButton.js b/wikipedia/widgets/ListTextButton.js deleted file mode 100644 index 41a7585..0000000 --- a/wikipedia/widgets/ListTextButton.js +++ /dev/null @@ -1,58 +0,0 @@ -const Lang = imports.lang; -const Gdk = imports.gi.Gdk; -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gtk = imports.gi.Gtk; -const Pango = imports.gi.Pango; - -// This is an approximate number of characters that will keep the label from -// going over its specified width -const ARTICLE_LABEL_MAX_WIDTH_CHARS = 20; - -const ListTextButton = new Lang.Class({ - Name: 'EndlessListTextButton', - Extends: Gtk.Button, - - // This is a button for the article list widget. It has a label and an icon image. - // The icon image will only appear on hover or press of button - _init: function(hover_icon_path, label_text, params) { - params.hexpand = true; - this.parent(params); - - this._hover_icon_pixbuf = GdkPixbuf.Pixbuf.new_from_resource(hover_icon_path); - - this._image = new Gtk.Image({ - opacity: 0, - }); - this._image.set_from_pixbuf(this._hover_icon_pixbuf); - - this._box = new Gtk.Box({ - orientation: Gtk.Orientation.HORIZONTAL - }); - - this._label = new Gtk.Label({ - label: label_text, - max_width_chars: ARTICLE_LABEL_MAX_WIDTH_CHARS, - ellipsize: Pango.EllipsizeMode.END - }); - - this._box.pack_start(this._label, false, false, 0); - this._box.pack_end(this._image, false, false, 0); - - this.add(this._box); - this.connect('state-changed', Lang.bind(this, this._update_appearance)); - this.show_all(); - }, - - _update_appearance: function(widget, state) { - // If button is hovered over and/or pressed, then show the arrow icon - if (widget.get_state_flags() & Gtk.StateFlags.ACTIVE || - widget.get_state_flags() & Gtk.StateFlags.PRELIGHT) { - this._image.set_opacity(1); - return false; - } - // If no hover or press, then hide the arrow icon - this._image.set_opacity(0); - return false; - } -}); - diff --git a/wikipedia/widgets/category_back_button.js b/wikipedia/widgets/category_back_button.js deleted file mode 100644 index e959fa8..0000000 --- a/wikipedia/widgets/category_back_button.js +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2014 Endless Mobile, Inc. - -const Gettext = imports.gettext; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const CompositeButton = imports.wikipedia.widgets.composite_button; -const Config = imports.wikipedia.config; - -const _ = function (string) { return GLib.dgettext('eos-sdk', string); }; -Gettext.bindtextdomain('eos-sdk', Config.DATADIR + '/locale'); - -const CATEGORY_BACK_BUTTON_RESOURCE_URI = 'resource:///com/endlessm/wikipedia-domain/assets/wikipedia-category-back-symbolic.svg'; -const CATEGORY_BACK_BUTTON_SIZE_PIXELS = 68; -const STYLE_CONTEXT_LABEL = 'label'; -const STYLE_CONTEXT_BACK = 'back'; - -const CategoryBackButton = new Lang.Class({ - Name: 'CategoryBackButton', - GTypeName: 'CategoryBackButton', - Extends: CompositeButton.CompositeButton, - - _init: function(props) { - this.parent(props); - - let gicon = new Gio.FileIcon({ - file: Gio.File.new_for_uri(CATEGORY_BACK_BUTTON_RESOURCE_URI) - }); - let icon = Gtk.Image.new_from_gicon(gicon, Gtk.IconSize.DIALOG); - icon.pixel_size = CATEGORY_BACK_BUTTON_SIZE_PIXELS; - let label = new Gtk.Label({ - label: _("OTHER CATEGORIES") - }); - let innerGrid = new Gtk.Grid({ - expand: true, - valign: Gtk.Align.CENTER - }); - - innerGrid.add(icon); - innerGrid.add(label); - this.add(innerGrid); - this.setSensitiveChildren([icon, label]); - - // Define style classes for CSS - icon.get_style_context().add_class(Gtk.STYLE_CLASS_IMAGE); - label.get_style_context().add_class(STYLE_CONTEXT_LABEL); - this.get_style_context().add_class(STYLE_CONTEXT_BACK); - } -}); diff --git a/wikipedia/widgets/category_button.js b/wikipedia/widgets/category_button.js deleted file mode 100644 index c116018..0000000 --- a/wikipedia/widgets/category_button.js +++ /dev/null @@ -1,203 +0,0 @@ -const Gdk = imports.gi.Gdk; -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gio = imports.gi.Gio; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const CompositeButton = imports.wikipedia.widgets.composite_button; -const EndlessWikipedia = imports.wikipedia.EndlessWikipedia; -const Utils = imports.wikipedia.utils; - -const CATEGORY_LABEL_LEFT_MARGIN_PIXELS = 5; // in addition to the 20px below -const CATEGORY_LABEL_SPACING_PIXELS = 20; -const CATEGORY_BUTTON_SIZE_PIXELS = 42; -const CATEGORY_BUTTON_RESOURCE_URI = 'resource:///com/endlessm/wikipedia-domain/assets/wikipedia-category-forward-symbolic.svg'; -const CATEGORY_MIN_WIDTH = 120; // pixels - -GObject.ParamFlags.READWRITE = GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE; - -const CategoryButton = new Lang.Class({ - Name: 'CategoryButton', - Extends: CompositeButton.CompositeButton, - Properties: { - // resource URI for the category's accompanying image - 'image-uri': GObject.ParamSpec.string('image-uri', - 'Image URI', - 'Resource URI for the image file accompanying the category', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - - // Title of the category to display - 'category-title': GObject.ParamSpec.string('category-title', - 'Category title', - 'Display name for the category', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - ''), - - // Boolean whether this button is clickable - 'clickable-category': GObject.ParamSpec.boolean('clickable-category', - 'Clickable Category', - 'Flag whether this category button should be clickable', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - true), - - // Boolean whether this button is the main category - 'is-main-category': GObject.ParamSpec.boolean('is-main-category', - 'Is Main Category', - 'Flag whether this category button is the main category', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - false) - }, - - _init: function(props) { - // Get ready for property construction - this._image_uri = null; - this._category_title = null; - this._clickable_category = null; - this._is_main_category = null; - this._pixbuf = null; - - this._inner_grid = new Gtk.Grid({ - valign: Gtk.Align.END, - halign: Gtk.Align.FILL, - border_width: CATEGORY_LABEL_SPACING_PIXELS, - column_spacing: CATEGORY_LABEL_SPACING_PIXELS, - expand: true - }); - this._label = new Gtk.Label({ - margin_left: CATEGORY_LABEL_LEFT_MARGIN_PIXELS, - halign: Gtk.Align.START, - valign: Gtk.Align.BASELINE, - xalign: 0.0, // deprecated Gtk.Misc properties; necessary because - wrap: true, // "wrap" doesn't respect "halign" - max_width_chars: 20 - }); - this._arrow = new Gtk.Image({ - gicon: new Gio.FileIcon({ - file: Gio.File.new_for_uri(CATEGORY_BUTTON_RESOURCE_URI) - }), - pixel_size: CATEGORY_BUTTON_SIZE_PIXELS, - hexpand: true, - halign: Gtk.Align.END, - valign: Gtk.Align.END - }); - this._arrow.get_style_context().add_class(Gtk.STYLE_CLASS_IMAGE); - - let context = this._label.get_style_context(); - context.add_class(EndlessWikipedia.STYLE_CLASS_TITLE); - context.add_class(EndlessWikipedia.STYLE_CLASS_CATEGORY); - context.add_class(EndlessWikipedia.STYLE_CLASS_FRONT_PAGE); - - // Parent constructor sets all properties - this.parent(props); - - // Put widgets together - this.setSensitiveChildren([this._arrow]); - this._inner_grid.add(this._label); - this._inner_grid.add(this._arrow); - this.add(this._inner_grid); - this.show_all(); - - // For some reason, on the NUC, setting opacity in CSS for this button does not work. - // So we have to set it in Gtk code. Also, we have to set the opacity - // to zero upfront. I am putting that here instead of in the initialisation - // of the arrow since it is part of this NUC-specific hack - this._arrow.connect('state-flags-changed', Lang.bind(this, this._update_appearance)); - this._arrow.set_opacity(0) - }, - - _update_appearance: function(widget) { - // If button is hovered over and/or pressed, then show the arrow icon - if ((widget.get_state_flags() & Gtk.StateFlags.ACTIVE || - widget.get_state_flags() & Gtk.StateFlags.PRELIGHT) && - this._clickable_category) { - this._arrow.set_opacity(1); - return false; - } - // If no hover or press, then hide the arrow icon - this._arrow.set_opacity(0); - return false; - }, - - get image_uri() { - return this._image_uri; - }, - - set image_uri(value) { - this._image_uri = value; - }, - - get category_title() { - return this._category_title; - }, - - set category_title(value) { - this._category_title = value; - if(this._label) - this._label.set_text(value.toUpperCase()); - }, - - get clickable_category() { - return this._clickable_category; - }, - - set clickable_category(value) { - this._clickable_category = value; - this._update_appearance(this._arrow); - }, - - get is_main_category() { - return this._is_main_category; - }, - - set is_main_category(value) { - this._is_main_category = value; - if(this._is_main_category) { - let context = this._label.get_style_context(); - context.add_class(EndlessWikipedia.STYLE_CLASS_MAIN); - this._label.max_width_chars = 9; - } - }, - - // OVERRIDES - - // Sometimes our label content runs too long and the min window width can - // be greater than the screen width. So we provide our own min width for - // category buttons here, and allow the GtkLabels to be cut off if there's - // no space. We ask for width for height management so the height will be - // allocated first. - vfunc_get_request_mode: function() { - return Gtk.SizeRequestMode.WIDTH_FOR_HEIGHT; - }, - - vfunc_get_preferred_width_for_height: function(height) { - let natural_width = this.parent(height)[1]; - return [CATEGORY_MIN_WIDTH, natural_width]; - }, - - // Reloads the pixbuf from the gresource at the proper size if necessary - _update_pixbuf: function () { - if (this._image_uri === "" || this._image_uri === null) - return; - let allocation = this.get_allocation(); - if (this._pixbuf === null || this._pixbuf.get_width() !== allocation.width || - this._pixbuf.get_height() !== allocation.height) - this._pixbuf = Utils.load_pixbuf_cover(Utils.resourceUriToPath(this._image_uri), - allocation.width, allocation.height); - }, - - vfunc_draw: function (cr) { - this._update_pixbuf(); - if (this._pixbuf !== null) { - Gdk.cairo_set_source_pixbuf(cr, this._pixbuf, 0, 0); - cr.paint(); - } - let ret = this.parent(cr); - // We need to manually call dispose on cairo contexts. This is somewhat related to the bug listed here - // https://bugzilla.gnome.org/show_bug.cgi?id=685513 for the shell. We should see if they come up with - // a better fix in the future, i.e. fix this through gjs. - cr.$dispose(); - return ret; - } -}); diff --git a/wikipedia/widgets/category_layout_manager.js b/wikipedia/widgets/category_layout_manager.js deleted file mode 100644 index cb2f94a..0000000 --- a/wikipedia/widgets/category_layout_manager.js +++ /dev/null @@ -1,74 +0,0 @@ -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const MAIN_CATEGORY_SCREEN_WIDTH_PERCENTAGE = 37; -const SUB_CATEGORY_SCREEN_WIDTH_PERCENTAGE = 30; - -const CategoryLayoutManager = new Lang.Class({ - Name: 'CategoryLayoutManager', - Extends: Gtk.Grid, - - _init: function(props) { - props = props || {}; - props.row_homogeneous = true; - props.column_homogeneous = true; - this.parent(props); - - this._childWidgets = []; - this._mainWidget = null; - }, - - // Distribute children in two columns, except for the last one if an odd - // number; that should span two columns. The width must be divided by - // percentage according to the spec, so we consider each column in the grid - // one percent - _redistributeChildren: function() { - let numChildren = this._childWidgets.length; - let oddNumber = numChildren % 2 == 1; - - let numRows = 1; - this._childWidgets.forEach(function(child, index) { - let column = (index % 2) * SUB_CATEGORY_SCREEN_WIDTH_PERCENTAGE + MAIN_CATEGORY_SCREEN_WIDTH_PERCENTAGE; - let row = Math.floor(index / 2); - - if(numRows < row + 1) - numRows = row + 1; //our running count of how many rows we have, which we - //need when we add the main widget. - - if(child.get_parent() === this) - Gtk.Container.prototype.remove.call(this, this._childWidgets[index]); - - if(oddNumber && index == numChildren - 1) - this.attach(child, column, row, SUB_CATEGORY_SCREEN_WIDTH_PERCENTAGE * 2, 1); - else - this.attach(child, column, row, SUB_CATEGORY_SCREEN_WIDTH_PERCENTAGE, 1); - }, this); - - if(this._mainWidget) { - if(this._mainWidget.get_parent() === this) { - Gtk.Container.prototype.remove.call(this, this._mainWidget); - } - this.attach(this._mainWidget, 0, 0, MAIN_CATEGORY_SCREEN_WIDTH_PERCENTAGE, numRows); - } - }, - - add: function(child) { - if(child.is_main_category) { - this._mainWidget = child; - } else { - this._childWidgets.push(child); - } - this._redistributeChildren(); - }, - - remove: function(child) { - let index = this._childWidgets.indexOf(child); - if(index == -1) { - printerr('Widget', System.addressOf(child), - 'is not contained in CategoryLayoutManager'); - return; - } - this._childWidgets.splice(index, 1); // remove - this._redistributeChildren(); - } -}); diff --git a/wikipedia/widgets/category_selector_view.js b/wikipedia/widgets/category_selector_view.js deleted file mode 100644 index 72eff07..0000000 --- a/wikipedia/widgets/category_selector_view.js +++ /dev/null @@ -1,56 +0,0 @@ -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -const CategoryButton = imports.wikipedia.widgets.category_button; -const CategoryLayoutManager = imports.wikipedia.widgets.category_layout_manager; - -const CATEGORY_COLUMN_SPACING = 10; // pixels -const CATEGORY_ROW_SPACING = 10; // pixels - -const CategorySelectorView = new Lang.Class({ - Name: 'CategorySelectorView', - Extends: CategoryLayoutManager.CategoryLayoutManager, - Signals: { - 'category-chosen': { - param_types: [GObject.TYPE_STRING] - } - }, - - _init: function(props) { - props = props || {}; - props.column_spacing = CATEGORY_COLUMN_SPACING; - props.row_spacing = CATEGORY_ROW_SPACING; - this.parent(props); - }, - - /** - * Method: setCategories - * Create buttons in this view for a list of categories to display - * - * Parameters: - * categories - An array of <CategoryModels> - * - */ - setCategories: function(categories) { - categories.forEach(function (category) { - let button = new CategoryButton.CategoryButton({ - category_title: category.title, - image_uri: category.image_thumbnail_uri, - clickable_category: category.has_articles, - is_main_category: category.is_main_category, - }); - button.id = category.id; // ID to return to when clicked - //if the category has no articles, you shouldn't be able to click on it. - if (category.has_articles) { - button.connect('clicked', Lang.bind(this, this._onButtonClicked)); - } - - this.add(button); - }, this); - }, - - _onButtonClicked: function(button) { - this.emit('category-chosen', button.id); - } -});
\ No newline at end of file diff --git a/wikipedia/widgets/composite_button.js b/wikipedia/widgets/composite_button.js deleted file mode 100644 index 2fb0666..0000000 --- a/wikipedia/widgets/composite_button.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 Endless Mobile, Inc. - -const Gtk = imports.gi.Gtk; -const Lang = imports.lang; - -// Class for buttons whose :hover and :active CSS pseudoclass states should be -// inherited by some of their child widgets, since as of GTK 3.10 these flags no -// longer propagate from a widget to its children. Widgets in sensitiveChildren -// will listen to this widget's state-flags-changed event and inherit all flag -// values listed in _INHERITED_FLAGS. - -const CompositeButton = new Lang.Class({ - Name: 'CompositeButton', - GTypeName: 'CompositeButton', - Extends: Gtk.Button, - - _INHERITED_FLAGS: [Gtk.StateFlags.PRELIGHT, Gtk.StateFlags.ACTIVE], - - _init: function (props) { - this._handlerSet = false; - this._sensitiveChildren = []; - this.parent(props); - }, - - // Set the list of child widgets which will inherit the CompositeButton's - // hover/active state flags. - setSensitiveChildren: function (children) { - this._sensitiveChildren = children; - // If the handlers for mouse events aren't already set, connect them - if (!this._handlerSet) { - this._connectStateChangedHandler(); - } - }, - - _connectStateChangedHandler: function () { - this.connect('state-flags-changed', - Lang.bind(this, this._stateChangedHandler)); - this._handlerSet = true; - }, - - _stateChangedHandler: function (widget, flags) { - let myFlags = this.get_state_flags(); - this._sensitiveChildren.forEach(function (child) { - this._INHERITED_FLAGS.forEach(function (flag) { - // for each flag we want the children to inherit, grab this - // widget's flag value, and set the child's matching flag - // accordingly - let myFlag = myFlags & flag; - if (myFlag !== 0) - child.set_state_flags(flag, false); - else - child.unset_state_flags(flag); - - }); - }, this); - } -}); |