2024-04-20 02:38 BST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0002404NetSurfBeOS-specificpublic2016-02-16 14:11
ReporterPulkoMandy 
Assigned ToVincent Sanders 
SeverityminorReproducibilityalways 
StatusclosedResolutionfixed 
Product Version3.3 
Target VersionFixed in Version3.4 
Summary0002404: [PATCH] Cookie Manager for BeOS
DescriptionThis patch adds a cookie manager to the BeOS user interface.
https://gist.github.com/AdrianArroyoCalle/a733017f9ea1d06ca5a0
TagsNo tags attached.
Fixed in CI build #3271
Reported in CI build #
URL of problem page
Attached Files
  • patch file icon 0003-Cookie-Manager-for-Haiku.patch (14,756 bytes) 2015-12-27 09:28 -
    From 739784309d6bee1a86defe4701f0f9b22a3461c1 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Adri=C3=A1n=20Arroyo=20Calle?=
     <adrian.arroyocalle@gmail.com>
    Date: Thu, 24 Dec 2015 14:21:25 +0100
    Subject: [PATCH 3/3] Cookie Manager for Haiku
    
    ---
     beos/Makefile.target |   5 +-
     beos/cookies.cpp     | 416 +++++++++++++++++++++++++++++++++++++++++++++++++++
     beos/cookies.h       |  24 +++
     beos/scaffolding.cpp |  20 ++-
     4 files changed, 452 insertions(+), 13 deletions(-)
     create mode 100644 beos/cookies.cpp
     create mode 100644 beos/cookies.h
    
    diff --git a/beos/Makefile.target b/beos/Makefile.target
    index d762c52..88177cd 100644
    --- a/beos/Makefile.target
    +++ b/beos/Makefile.target
    @@ -57,7 +57,7 @@ else
         NETLDFLAGS := -lnetwork
     endif
     
    -LDFLAGS += -lbe -ltranslation -ltracker $(NETLDFLAGS)
    +LDFLAGS += -lbe -ltranslation -ltracker -lcolumnlistview $(NETLDFLAGS)
     ifeq ($(CC_MAJOR),2)
         LDFLAGS += -lstdc++.r4
     else
    @@ -85,7 +85,8 @@ endif
     # ----------------------------------------------------------------------------
     
     # S_BEOS are sources purely for the BeOS build
    -S_BEOS := about.cpp bitmap.cpp download.cpp fetch_rsrc.cpp filetype.cpp \
    +S_BEOS := about.cpp bitmap.cpp cookies.cpp \
    +	download.cpp fetch_rsrc.cpp filetype.cpp \
     	font.cpp gui.cpp login.cpp gui_options.cpp plotters.cpp		\
     	scaffolding.cpp search.cpp schedule.cpp throbber.cpp window.cpp
     S_BEOS := $(addprefix beos/,$(S_BEOS))
    diff --git a/beos/cookies.cpp b/beos/cookies.cpp
    new file mode 100644
    index 0000000..acd0ac1
    --- /dev/null
    +++ b/beos/cookies.cpp
    @@ -0,0 +1,416 @@
    +/*
    + * Copyright 2015 Adrián Arroyo Calle <adrian.arroyocalle@gmail.com>
    + *
    + * This file is part of NetSurf, http://www.netsurf-browser.org/
    + *
    + * NetSurf is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; version 2 of the License.
    + *
    + * NetSurf is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    + */
    +
    +#define __STDBOOL_H__	1
    +#include <stdio.h>
    +#include <stdlib.h>
    +#include <string.h>
    +extern "C" {
    +#include "desktop/mouse.h"
    +#include "utils/log.h"
    +#include "desktop/cookie_manager.h"
    +#include "desktop/plotters.h"
    +#include "desktop/tree.h"
    +#include "desktop/textinput.h"
    +#include "content/urldb.h"
    +}
    +#include "beos/cookies.h"
    +
    +#include <Application.h>
    +#include <InterfaceKit.h>
    +#include <String.h>
    +#include <Button.h>
    +#include <Catalog.h>
    +#include <private/interface/ColumnListView.h>
    +#include <private/interface/ColumnTypes.h>
    +#include <GroupLayoutBuilder.h>
    +#include <NetworkCookieJar.h>
    +#include <OutlineListView.h>
    +#include <ScrollView.h>
    +#include <StringView.h>
    +
    +#include <vector>
    +
    +static std::vector<struct cookie_data*> cookieJar;
    +
    +class CookieWindow : public BWindow {
    +public:
    +								CookieWindow(BRect frame);
    +	virtual	void				MessageReceived(BMessage* message);
    +	virtual void				Show();
    +	virtual	bool				QuitRequested();
    +
    +private:
    +			void				_BuildDomainList();
    +			BStringItem*		_AddDomain(BString domain, bool fake);
    +			void				_ShowCookiesForDomain(BString domain);
    +			void				_DeleteCookies();
    +
    +private:
    +	BOutlineListView*			fDomains;
    +	BColumnListView*			fCookies;
    +	BStringView*				fHeaderView;
    +};
    +
    +enum {
    +	COOKIE_IMPORT = 'cimp',
    +	COOKIE_EXPORT = 'cexp',
    +	COOKIE_DELETE = 'cdel',
    +	COOKIE_REFRESH = 'rfsh',
    +
    +	DOMAIN_SELECTED = 'dmsl'
    +};
    +
    +
    +class CookieDateColumn: public BDateColumn
    +{
    +public:
    +	CookieDateColumn(const char* title, float width)
    +		:
    +		BDateColumn(title, width, width / 2, width * 2)
    +	{
    +	}
    +
    +	void DrawField(BField* field, BRect rect, BView* parent) {
    +		BDateField* dateField = (BDateField*)field;
    +		if (dateField->UnixTime() == -1) {
    +			DrawString("Session cookie", parent, rect);
    +		} else {
    +			BDateColumn::DrawField(field, rect, parent);
    +		}
    +	}
    +};
    +
    +
    +class CookieRow: public BRow
    +{
    +public:
    +	CookieRow(BColumnListView* list, struct cookie_data& cookie)
    +		:
    +		BRow(),
    +		fCookie(cookie)
    +	{
    +		list->AddRow(this);
    +		SetField(new BStringField(cookie.name), 0);
    +		SetField(new BStringField(cookie.path), 1);
    +		time_t expiration = cookie.expires;
    +		SetField(new BDateField(&expiration), 2);
    +		SetField(new BStringField(cookie.value), 3);
    +
    +		BString flags;
    +		if (cookie.secure)
    +			flags = "https ";
    +		if (cookie.http_only)
    +			flags = "http ";
    +
    +		SetField(new BStringField(flags.String()), 4);
    +	}
    +
    +public:
    +	struct cookie_data	fCookie;
    +};
    +
    +
    +class DomainItem: public BStringItem
    +{
    +public:
    +	DomainItem(BString text, bool empty)
    +		:
    +		BStringItem(text),
    +		fEmpty(empty)
    +	{
    +	}
    +
    +public:
    +	bool	fEmpty;
    +};
    +
    +
    +CookieWindow::CookieWindow(BRect frame)
    +	:
    +	BWindow(frame,"Cookie manager", B_TITLED_WINDOW,
    +		B_NORMAL_WINDOW_FEEL,
    +		B_AUTO_UPDATE_SIZE_LIMITS | B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE)
    +{
    +	BGroupLayout* root = new BGroupLayout(B_HORIZONTAL, 0.0);
    +	SetLayout(root);
    +
    +	fDomains = new BOutlineListView("domain list");
    +	root->AddView(new BScrollView("scroll", fDomains, 0, false, true), 1);
    +
    +	fHeaderView = new BStringView("label","The cookie jar is empty!");
    +	fCookies = new BColumnListView("cookie list", B_WILL_DRAW, B_FANCY_BORDER,
    +		false);
    +
    +	float em = fCookies->StringWidth("M");
    +	float flagsLength = fCookies->StringWidth("Mhttps hostOnly" B_UTF8_ELLIPSIS);
    +
    +	fCookies->AddColumn(new BStringColumn("Name",
    +		20 * em, 10 * em, 50 * em, 0), 0);
    +	fCookies->AddColumn(new BStringColumn("Path",
    +		10 * em, 10 * em, 50 * em, 0), 1);
    +	fCookies->AddColumn(new CookieDateColumn("Expiration",
    +		fCookies->StringWidth("88/88/8888 88:88:88 AM")), 2);
    +	fCookies->AddColumn(new BStringColumn("Value",
    +		20 * em, 10 * em, 50 * em, 0), 3);
    +	fCookies->AddColumn(new BStringColumn("Flags",
    +		flagsLength, flagsLength, flagsLength, 0), 4);
    +
    +	root->AddItem(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING)
    +		.SetInsets(5, 5, 5, 5)
    +		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
    +			.Add(fHeaderView)
    +			.AddGlue()
    +		.End()
    +		.Add(fCookies)
    +		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
    +			.SetInsets(5, 5, 5, 5)
    +			.AddGlue()
    +			.Add(new BButton("delete", "Delete",
    +				new BMessage(COOKIE_DELETE))), 3);
    +
    +	fDomains->SetSelectionMessage(new BMessage(DOMAIN_SELECTED));
    +}
    +
    +
    +void
    +CookieWindow::MessageReceived(BMessage* message)
    +{
    +	switch(message->what) {
    +		case DOMAIN_SELECTED:
    +		{
    +			int32 index = message->FindInt32("index");
    +			BStringItem* item = (BStringItem*)fDomains->ItemAt(index);
    +			if (item != NULL) {
    +				BString domain = item->Text();
    +				_ShowCookiesForDomain(domain);
    +			}
    +			return;
    +		}
    +
    +		case COOKIE_REFRESH:
    +			_BuildDomainList();
    +			return;
    +
    +		case COOKIE_DELETE:
    +			_DeleteCookies();
    +			return;
    +	}
    +	BWindow::MessageReceived(message);
    +}
    +
    +
    +void
    +CookieWindow::Show()
    +{
    +	BWindow::Show();
    +	if (IsHidden())
    +		return;
    +
    +	PostMessage(COOKIE_REFRESH);
    +}
    +
    +
    +bool
    +CookieWindow::QuitRequested()
    +{
    +	if (!IsHidden())
    +		Hide();
    +	cookieJar.clear();
    +	return false;
    +}
    +
    +
    +void
    +CookieWindow::_BuildDomainList()
    +{
    +	// Empty the domain list (TODO should we do this when hiding instead?)
    +	for (int i = fDomains->FullListCountItems() - 1; i >= 1; i--) {
    +		delete fDomains->FullListItemAt(i);
    +	}
    +	fDomains->MakeEmpty();
    +
    +	// BOutlineListView does not handle parent = NULL in many methods, so let's
    +	// make sure everything always has a parent.
    +	DomainItem* rootItem = new DomainItem("", true);
    +	fDomains->AddItem(rootItem);
    +
    +	// Populate the domain list - TODO USE STL VECTOR
    +
    +
    +	for(std::vector<struct cookie_data*>::iterator it = cookieJar.begin(); it != cookieJar.end(); ++it) {
    +		_AddDomain((*it)->domain, false);
    +	}
    +
    +	int i = 1;
    +	while (i < fDomains->FullListCountItems())
    +	{
    +		DomainItem* item = (DomainItem*)fDomains->FullListItemAt(i);
    +		// Detach items from the fake root
    +		item->SetOutlineLevel(item->OutlineLevel() - 1);
    +		i++;
    +	}
    +	fDomains->RemoveItem(rootItem);
    +	delete rootItem;
    +
    +	i = 0;
    +	int firstNotEmpty = i;
    +	// Collapse empty items to keep the list short
    +	while (i < fDomains->FullListCountItems())
    +	{
    +		DomainItem* item = (DomainItem*)fDomains->FullListItemAt(i);
    +		if (item->fEmpty == true) {
    +			if (fDomains->CountItemsUnder(item, true) == 1) {
    +				// The item has no cookies, and only a single child. We can
    +				// remove it and move its child one level up in the tree.
    +
    +				int count = fDomains->CountItemsUnder(item, false);
    +				int index = fDomains->FullListIndexOf(item) + 1;
    +				for (int j = 0; j < count; j++) {
    +					BListItem* child = fDomains->FullListItemAt(index + j);
    +					child->SetOutlineLevel(child->OutlineLevel() - 1);
    +				}
    +
    +				fDomains->RemoveItem(item);
    +				delete item;
    +
    +				// The moved child is at the same index the removed item was.
    +				// We continue the loop without incrementing i to process it.
    +				continue;
    +			} else {
    +				// The item has no cookies, but has multiple children. Mark it
    +				// as disabled so it is not selectable.
    +				item->SetEnabled(false);
    +				if (i == firstNotEmpty)
    +					firstNotEmpty++;
    +			}
    +		}
    +
    +		i++;
    +	}
    +
    +	fDomains->Select(firstNotEmpty);
    +}
    +
    +
    +BStringItem*
    +CookieWindow::_AddDomain(BString domain, bool fake)
    +{
    +	BStringItem* parent = NULL;
    +	int firstDot = domain.FindFirst('.');
    +	if (firstDot >= 0) {
    +		BString parentDomain(domain);
    +		parentDomain.Remove(0, firstDot + 1);
    +		parent = _AddDomain(parentDomain, true);
    +	} else {
    +		parent = (BStringItem*)fDomains->FullListItemAt(0);
    +	}
    +
    +	BListItem* existing;
    +	int i = 0;
    +	// check that we aren't already there
    +	while ((existing = fDomains->ItemUnderAt(parent, true, i++)) != NULL) {
    +		DomainItem* stringItem = (DomainItem*)existing;
    +		if (stringItem->Text() == domain) {
    +			if (fake == false)
    +				stringItem->fEmpty = false;
    +			return stringItem;
    +		}
    +	}
    +
    +	// Insert the new item, keeping the list alphabetically sorted
    +	BStringItem* domainItem = new DomainItem(domain, fake);
    +	domainItem->SetOutlineLevel(parent->OutlineLevel() + 1);
    +	BStringItem* sibling = NULL;
    +	int siblingCount = fDomains->CountItemsUnder(parent, true);
    +	for (i = 0; i < siblingCount; i++) {
    +		sibling = (BStringItem*)fDomains->ItemUnderAt(parent, true, i);
    +		if (strcmp(sibling->Text(), domainItem->Text()) > 0) {
    +			fDomains->AddItem(domainItem, fDomains->FullListIndexOf(sibling));
    +			return domainItem;
    +		}
    +	}
    +
    +	if (sibling) {
    +		// There were siblings, but all smaller than what we try to insert.
    +		// Insert after the last one (and its subitems)
    +		fDomains->AddItem(domainItem, fDomains->FullListIndexOf(sibling)
    +			+ fDomains->CountItemsUnder(sibling, false) + 1);
    +	} else {
    +		// There were no siblings, insert right after the parent
    +		fDomains->AddItem(domainItem, fDomains->FullListIndexOf(parent) + 1);
    +	}
    +
    +	return domainItem;
    +}
    +
    +
    +void
    +CookieWindow::_ShowCookiesForDomain(BString domain)
    +{
    +	BString label;
    +	label.SetToFormat("Cookies for %s", domain.String());
    +	fHeaderView->SetText(label);
    +
    +	// Empty the cookie list
    +	fCookies->Clear();
    +
    +	// Populate the domain list
    +
    +	for(std::vector<struct cookie_data*>::iterator it = cookieJar.begin(); it != cookieJar.end(); ++it) {
    +		if((*it)->domain == domain) {
    +			new CookieRow(fCookies,**it);
    +		}
    +	}
    +}
    +
    +static bool nsbeos_cookie_parser(const struct cookie_data* data)
    +{
    +	cookieJar.push_back((struct cookie_data*)data);
    +	return true;
    +}
    +
    +void
    +CookieWindow::_DeleteCookies()
    +{
    +	// TODO shall we handle multiple selection here?
    +	CookieRow* row = (CookieRow*)fCookies->CurrentSelection();
    +	if (row == NULL) {
    +		// TODO see if a domain is selected in the domain list, and delete all
    +		// cookies for that domain
    +		return;
    +	}
    +
    +	fCookies->RemoveRow(row);
    +
    +	urldb_delete_cookie(row->fCookie.domain, row->fCookie.path, row->fCookie.name);
    +	cookieJar.clear();
    +	urldb_iterate_cookies(&nsbeos_cookie_parser);
    +
    +	delete row;
    +}
    +
    +/**
    + * Creates the Cookie Manager
    + */
    +void nsbeos_cookies_init(void)
    +{
    +	CookieWindow* cookWin=new CookieWindow(BRect(100,100,400,400));
    +	cookWin->Show();
    +	urldb_iterate_cookies(&nsbeos_cookie_parser);
    +}
    diff --git a/beos/cookies.h b/beos/cookies.h
    new file mode 100644
    index 0000000..977ccd2
    --- /dev/null
    +++ b/beos/cookies.h
    @@ -0,0 +1,24 @@
    +/*
    + * Copyright 2015 Adrián Arroyo Calle <adrian.arroyocalle@gmail.com>
    + *
    + * This file is part of NetSurf, http://www.netsurf-browser.org/
    + *
    + * NetSurf is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License as published by
    + * the Free Software Foundation; version 2 of the License.
    + *
    + * NetSurf is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    + */
    +
    +#ifndef __BEOS_COOKIES_H__
    +#define __BEOS_COOKIES_H__
    +
    +void nsbeos_cookies_init();
    +
    +#endif /* __BEOS_ABOUT_H__ */
    diff --git a/beos/scaffolding.cpp b/beos/scaffolding.cpp
    index 392bfde..3e14973 100644
    --- a/beos/scaffolding.cpp
    +++ b/beos/scaffolding.cpp
    @@ -81,6 +81,7 @@ extern "C" {
     #include "beos/window.h"
     #include "beos/schedule.h"
     //#include "beos/download.h"
    +#include "beos/cookies.h"
     
     #define TOOLBAR_HEIGHT 32
     #define DRAGGER_WIDTH 8
    @@ -1191,9 +1192,15 @@ void nsbeos_scaffolding_dispatch_event(nsbeos_scaffolding *scaffold, BMessage *m
     		case HOTLIST_SHOW:
     			break;
     		case COOKIES_SHOW:
    +		{
    +			nsbeos_cookie_init();
     			break;
    +		}
     		case COOKIES_DELETE:
    +		{
    +			nsbeos_cookie_init();
     			break;
    +		}
     		case BROWSER_PAGE:
     			break;
     		case BROWSER_PAGE_INFO:
    @@ -1976,18 +1983,9 @@ nsbeos_scaffolding *nsbeos_new_scaffolding(struct gui_window *toplevel)
     		item = make_menu_item("HistGlobal", message);
     		submenu->AddItem(item);
     
    -
    -		submenu = new BMenu(messages_get("Cookies"));
    -		menu->AddItem(submenu);
    -
     		message = new BMessage(COOKIES_SHOW);
    -		item = make_menu_item("ShowCookies", message);
    -		submenu->AddItem(item);
    -
    -		message = new BMessage(COOKIES_DELETE);
    -		item = make_menu_item("DeleteCookies", message);
    -		submenu->AddItem(item);
    -
    +		item = make_menu_item("Cookie manager", message, true);
    +		menu->AddItem(item);
     
     		message = new BMessage(BROWSER_FIND_TEXT);
     		item = make_menu_item("FindText", message);
    -- 
    2.6.4
    
    
    patch file icon 0003-Cookie-Manager-for-Haiku.patch (14,756 bytes) 2015-12-27 09:28 +

-Relationships
+Relationships

-Notes
Vincent Sanders

~0001156

Vincent Sanders (administrator)

applied patch
Vincent Sanders

~0001244

Vincent Sanders (administrator)

Confirmed fixed in 3.4 release
+Notes

-Issue History
Date Modified Username Field Change
2015-12-21 20:29 PulkoMandy New Issue
2015-12-27 09:28 PulkoMandy File Added: 0003-Cookie-Manager-for-Haiku.patch
2016-01-19 14:09 Vincent Sanders Fixed in CI build # => 3271
2016-01-19 14:09 Vincent Sanders Note Added: 0001156
2016-01-19 14:09 Vincent Sanders Assigned To => Vincent Sanders
2016-01-19 14:09 Vincent Sanders Status new => resolved
2016-01-19 14:09 Vincent Sanders Resolution open => fixed
2016-01-19 14:09 Vincent Sanders Fixed in Version => 3.4
2016-02-16 14:11 Vincent Sanders Note Added: 0001244
2016-02-16 14:11 Vincent Sanders Status resolved => closed
+Issue History