mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 701380 - Implement a native about:home (start page) r=mfinkle
--HG-- extra : rebase_source : 3b61498dc4a17fbec21531bd831994f81fb85532
This commit is contained in:
parent
96cd9b3757
commit
7842ed81b5
@ -45,6 +45,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
DIRS = profile/extensions
|
||||
|
||||
PREF_JS_EXPORTS = $(srcdir)/mobile.js
|
||||
DIST_FILES = recommended-addons.json
|
||||
|
||||
ifndef LIBXUL_SDK
|
||||
ifneq (Android,$(OS_TARGET))
|
||||
|
1
mobile/android/app/recommended-addons.json
Normal file
1
mobile/android/app/recommended-addons.json
Normal file
File diff suppressed because one or more lines are too long
273
mobile/android/base/AboutHomeContent.java
Normal file
273
mobile/android/base/AboutHomeContent.java
Normal file
@ -0,0 +1,273 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brad Lassey <blassey@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.widget.*;
|
||||
import android.database.*;
|
||||
import android.view.*;
|
||||
import android.graphics.*;
|
||||
import android.content.*;
|
||||
import android.provider.Browser;
|
||||
import android.util.Log;
|
||||
import java.util.Date;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Browser;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.SimpleCursorAdapter;
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
import android.os.Handler;
|
||||
import org.json.*;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
public class AboutHomeContent extends LinearLayout {
|
||||
public interface UriLoadCallback {
|
||||
public void callback(String uriSpec);
|
||||
}
|
||||
|
||||
UriLoadCallback mUriLoadCallback = null;
|
||||
|
||||
void setUriLoadCallback(UriLoadCallback uriLoadCallback) {
|
||||
mUriLoadCallback = uriLoadCallback;
|
||||
}
|
||||
|
||||
public AboutHomeContent(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
private static final String LOGTAG = "GeckoAboutHome";
|
||||
private static final String TITLE_KEY = "title";
|
||||
private static final String kAbouthomeWhereClause = Browser.BookmarkColumns.BOOKMARK + " = 1";
|
||||
private static final int kTileWidth = 122;
|
||||
|
||||
private Cursor mCursor;
|
||||
private Uri mUri;
|
||||
private String mTitle;
|
||||
|
||||
protected ListAdapter mGridAdapter;
|
||||
protected ArrayAdapter<String> mAddonAdapter;
|
||||
protected GridView mGrid;
|
||||
protected ListView mAddonList;
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
public void onActivityContentChanged(Activity activity) {
|
||||
mGrid = (GridView)findViewById(R.id.grid);
|
||||
if (mGrid == null)
|
||||
return;
|
||||
|
||||
mGrid.setOnItemClickListener(mGridOnClickListener);
|
||||
|
||||
// we want to do this: mGrid.setNumColumns(GridView.AUTO_FIT); but it doesn't work
|
||||
Display display = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
int width = display.getWidth();
|
||||
mGrid.setNumColumns((int) Math.floor(width / kTileWidth));
|
||||
mAddonList = (ListView)findViewById(R.id.recommended_addon_list);
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mGrid.setAdapter(mGridAdapter);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private AdapterView.OnItemClickListener mGridOnClickListener = new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
|
||||
{
|
||||
onGridItemClick((GridView)parent, v, position, id);
|
||||
}
|
||||
};
|
||||
|
||||
void init(final Activity activity) {
|
||||
LayoutInflater inflater =
|
||||
(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
inflater.inflate(R.layout.abouthome_content, this);
|
||||
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
mCursor = activity.managedQuery(Browser.BOOKMARKS_URI,
|
||||
null, kAbouthomeWhereClause, null, null);
|
||||
activity.startManagingCursor(mCursor);
|
||||
|
||||
onActivityContentChanged(activity);
|
||||
mAddonAdapter = new ArrayAdapter<String>(activity, R.layout.abouthome_addon_list_item);
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
final SimpleCursorAdapter gridAdapter =
|
||||
new SimpleCursorAdapter(activity, R.layout.abouthome_grid_box, mCursor,
|
||||
new String[] {Browser.BookmarkColumns.TITLE,
|
||||
Browser.BookmarkColumns.FAVICON,
|
||||
Browser.BookmarkColumns.URL,
|
||||
"thumbnail"},
|
||||
new int[] {R.id.bookmark_title, R.id.bookmark_icon, R.id.bookmark_url, R.id.screenshot});
|
||||
mGrid.setAdapter(gridAdapter);
|
||||
gridAdapter.setViewBinder(new AwesomeCursorViewBinder());
|
||||
mAddonList.setAdapter(mAddonAdapter);
|
||||
}
|
||||
});
|
||||
readRecommendedAddons(activity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void readRecommendedAddons(final Activity activity) {
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
File applicationPackage = new File(activity.getApplication().getPackageResourcePath());
|
||||
byte[] buf = new byte[32768];
|
||||
ZipFile zip = new ZipFile(applicationPackage);
|
||||
ZipEntry fileEntry = zip.getEntry("recommended-addons.json");
|
||||
|
||||
InputStream fileStream;
|
||||
fileStream = zip.getInputStream(fileEntry);
|
||||
StringBuffer jsonString = new StringBuffer();
|
||||
int read = 0;
|
||||
while ((read = fileStream.read(buf, 0, 32768)) != -1) {
|
||||
jsonString.append(new String(buf, 0, read));
|
||||
}
|
||||
final JSONArray array = new JSONObject(jsonString.toString()).getJSONArray("addons");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
JSONObject jsonobj = array.getJSONObject(i);
|
||||
mAddonAdapter.add(jsonobj.getString("name"));
|
||||
Log.i("GeckoAddons", "addon #" + i +": " + jsonobj.getString("name"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i("GeckoAddons", "error reading json file", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.i("GeckoAddons", "error reading json file", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void onGridItemClick(GridView l, View v, int position, long id) {
|
||||
mCursor.moveToPosition(position);
|
||||
String spec = mCursor.getString(mCursor.getColumnIndex(Browser.BookmarkColumns.URL));
|
||||
Log.i(LOGTAG, "clicked: " + spec);
|
||||
if (mUriLoadCallback != null)
|
||||
mUriLoadCallback.callback(spec);
|
||||
}
|
||||
|
||||
}
|
||||
class AwesomeCursorViewBinder implements SimpleCursorAdapter.ViewBinder {
|
||||
private boolean updateImage(View view, Cursor cursor, int faviconIndex) {
|
||||
byte[] b = cursor.getBlob(faviconIndex);
|
||||
ImageView favicon = (ImageView) view;
|
||||
|
||||
if (b == null) {
|
||||
favicon.setImageResource(R.drawable.favicon);
|
||||
} else {
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
favicon.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateTitle(View view, Cursor cursor, int titleIndex) {
|
||||
String title = cursor.getString(titleIndex);
|
||||
TextView titleView = (TextView)view;
|
||||
// Use the URL instead of an empty title for consistency with the normal URL
|
||||
// bar view - this is the equivalent of getDisplayTitle() in Tab.java
|
||||
if (title == null || title.length() == 0) {
|
||||
int urlIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
|
||||
title = cursor.getString(urlIndex);
|
||||
}
|
||||
|
||||
titleView.setText(title);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean updateUrl(View view, Cursor cursor, int urlIndex) {
|
||||
String title = cursor.getString(urlIndex);
|
||||
TextView urlView = (TextView)view;
|
||||
if (title != null) {
|
||||
int index;
|
||||
if ((index = title.indexOf("://")) != -1)
|
||||
title = title.substring(index + 3);
|
||||
if (title.startsWith("www."))
|
||||
title = title.substring(4);
|
||||
if (title.endsWith("/"))
|
||||
title = title.substring(0, title.length() -1);
|
||||
}
|
||||
urlView.setText(title);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
|
||||
int faviconIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.FAVICON);
|
||||
if (columnIndex == faviconIndex) {
|
||||
return updateImage(view, cursor, faviconIndex);
|
||||
}
|
||||
|
||||
int titleIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
|
||||
if (columnIndex == titleIndex) {
|
||||
return updateTitle(view, cursor, titleIndex);
|
||||
}
|
||||
|
||||
int urlIndex = cursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
|
||||
if (columnIndex == urlIndex) {
|
||||
return updateUrl(view, cursor, urlIndex);
|
||||
}
|
||||
|
||||
int thumbIndex = cursor.getColumnIndexOrThrow("thumbnail");
|
||||
|
||||
if (columnIndex == thumbIndex) {
|
||||
return updateImage(view, cursor, thumbIndex);
|
||||
}
|
||||
|
||||
// Other columns are handled automatically
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -122,6 +122,7 @@ abstract public class GeckoApp
|
||||
private static LayerController mLayerController;
|
||||
private static PlaceholderLayerClient mPlaceholderLayerClient;
|
||||
private static GeckoSoftwareLayerClient mSoftwareLayerClient;
|
||||
AboutHomeContent mAboutHomeContent;
|
||||
boolean mUserDefinedProfile = false;
|
||||
|
||||
private Vector<View> mPluginViews = new Vector<View>();
|
||||
@ -888,6 +889,8 @@ abstract public class GeckoApp
|
||||
mBrowserToolbar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
} else if (event.equals("AboutHome:Show")) {
|
||||
showAboutHome();
|
||||
} else if (event.equals("AgentMode:Changed")) {
|
||||
Tab.AgentMode agentMode = message.getString("agentMode").equals("mobile") ? Tab.AgentMode.MOBILE : Tab.AgentMode.DESKTOP;
|
||||
int tabId = message.getInt("tabId");
|
||||
@ -904,6 +907,40 @@ abstract public class GeckoApp
|
||||
}
|
||||
}
|
||||
|
||||
public void showAboutHome() {
|
||||
Runnable r = new AboutHomeRunnable(true);
|
||||
mMainHandler.postAtFrontOfQueue(r);
|
||||
}
|
||||
|
||||
public void hideAboutHome() {
|
||||
Runnable r = new AboutHomeRunnable(false);
|
||||
mMainHandler.postAtFrontOfQueue(r);
|
||||
}
|
||||
|
||||
public class AboutHomeRunnable implements Runnable {
|
||||
boolean mShow;
|
||||
AboutHomeRunnable(boolean show) {
|
||||
mShow = show;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if (mAboutHomeContent == null) {
|
||||
mAboutHomeContent = new AboutHomeContent(GeckoApp.mAppContext, null);
|
||||
mAboutHomeContent.init(GeckoApp.mAppContext);
|
||||
mAboutHomeContent.setUriLoadCallback(new AboutHomeContent.UriLoadCallback() {
|
||||
public void callback(String url) {
|
||||
mBrowserToolbar.setProgressVisibility(true);
|
||||
loadUrl(url, AwesomeBar.Type.EDIT);
|
||||
}
|
||||
});
|
||||
mGeckoLayout.addView(mAboutHomeContent);
|
||||
}
|
||||
if (mLayerController != null && mLayerController.getView() != null)
|
||||
mLayerController.getView().setVisibility(mShow ? View.GONE : View.VISIBLE);
|
||||
mAboutHomeContent.setVisibility(mShow ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
void updateAgentModeMenuItem(final Tab tab, final Tab.AgentMode agentMode) {
|
||||
if (sMenu == null)
|
||||
return;
|
||||
@ -985,10 +1022,16 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
void handleSelectTab(int tabId) {
|
||||
Tab selTab = Tabs.getInstance().getSelectedTab();
|
||||
final Tab tab = Tabs.getInstance().selectTab(tabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
if (selTab.getURL().equals("about:home") && !tab.getURL().equals("about:home"))
|
||||
hideAboutHome();
|
||||
else if (tab.getURL().equals("about:home"))
|
||||
showAboutHome();
|
||||
|
||||
updateAgentModeMenuItem(tab, tab.getAgentMode());
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
@ -1328,6 +1371,7 @@ abstract public class GeckoApp
|
||||
GeckoAppShell.registerGeckoEventListener("ToggleChrome:Hide", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("ToggleChrome:Show", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("AgentMode:Changed", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("AboutHome:Show", GeckoApp.mAppContext);
|
||||
|
||||
mConnectivityFilter = new IntentFilter();
|
||||
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
@ -1543,6 +1587,16 @@ abstract public class GeckoApp
|
||||
unregisterReceiver(mBatteryReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContentChanged() {
|
||||
super.onContentChanged();
|
||||
if (mAboutHomeContent == null)
|
||||
return;
|
||||
mAboutHomeContent = (AboutHomeContent) findViewById(R.id.abouthome_content);
|
||||
mAboutHomeContent.onActivityContentChanged(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(android.content.res.Configuration newConfig)
|
||||
{
|
||||
@ -1860,6 +1914,7 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
public void loadUrl(String url, AwesomeBar.Type type) {
|
||||
hideAboutHome();
|
||||
mBrowserToolbar.setTitle(url);
|
||||
Log.d(LOGTAG, type.name());
|
||||
if (type == AwesomeBar.Type.ADD) {
|
||||
|
@ -62,6 +62,16 @@ public class GeckoThread extends Thread {
|
||||
public void run() {
|
||||
final GeckoApp app = GeckoApp.mAppContext;
|
||||
Intent intent = mIntent;
|
||||
String uri = intent.getDataString();
|
||||
String title = uri;
|
||||
if (!app.mUserDefinedProfile && (uri == null || uri.length() == 0)) {
|
||||
SharedPreferences prefs = app.getSharedPreferences("GeckoApp", app.MODE_PRIVATE);
|
||||
uri = prefs.getString("last-uri", "");
|
||||
title = prefs.getString("last-title", uri);
|
||||
}
|
||||
if (uri == null || uri.equals("") || uri.equals("about:home")) {
|
||||
app.showAboutHome();
|
||||
}
|
||||
File cacheFile = GeckoAppShell.getCacheDir();
|
||||
File libxulFile = new File(cacheFile, "libxul.so");
|
||||
|
||||
@ -93,23 +103,14 @@ public class GeckoThread extends Thread {
|
||||
Log.w(LOGTAG, "zerdatime " + new Date().getTime() + " - runGecko");
|
||||
|
||||
// and then fire us up
|
||||
try {
|
||||
String uri = intent.getDataString();
|
||||
String title = uri;
|
||||
if (!app.mUserDefinedProfile &&
|
||||
(uri == null || uri.length() == 0)) {
|
||||
SharedPreferences prefs = app.getSharedPreferences("GeckoApp", app.MODE_PRIVATE);
|
||||
uri = prefs.getString("last-uri", "");
|
||||
title = prefs.getString("last-title", uri);
|
||||
|
||||
final String activityTitle = title;
|
||||
app.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
app.mBrowserToolbar.setTitle(activityTitle);
|
||||
}
|
||||
|
||||
final String awesomeTitle = title;
|
||||
app.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
app.mBrowserToolbar.setTitle(awesomeTitle);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
try {
|
||||
Log.w(LOGTAG, "RunGecko - URI = " + uri);
|
||||
|
||||
GeckoAppShell.runGecko(app.getApplication().getPackageResourcePath(),
|
||||
|
@ -48,6 +48,7 @@ DIRS = locales
|
||||
DIST_FILES = package-name.txt
|
||||
|
||||
JAVAFILES = \
|
||||
AboutHomeContent.java \
|
||||
AlertNotification.java \
|
||||
AwesomeBar.java \
|
||||
AwesomeBarTabs.java \
|
||||
@ -183,6 +184,8 @@ RES_LAYOUT = \
|
||||
res/layout/tabs_tray.xml \
|
||||
res/layout/list_item_header.xml \
|
||||
res/layout/select_dialog_list.xml \
|
||||
res/layout/abouthome_content.xml \
|
||||
res/layout/abouthome_grid_box.xml \
|
||||
$(NULL)
|
||||
|
||||
RES_LAYOUT_V11 = \
|
||||
@ -378,6 +381,8 @@ MOZ_ANDROID_DRAWABLES += mobile/android/base/resources/drawable/address_bar_bg.x
|
||||
mobile/android/base/resources/drawable/tabs_tray_bg.9.png \
|
||||
mobile/android/base/resources/drawable/checkerboard.png \
|
||||
mobile/android/base/resources/drawable/shadow.png \
|
||||
mobile/android/base/resources/drawable/rounded_grey_border.xml \
|
||||
mobile/android/base/resources/drawable/rounded_grey_box.xml \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFFFF" />
|
||||
<stroke android:width="2dip" android:color="#ffD0D0D0"/>
|
||||
<padding
|
||||
android:left="7dp"
|
||||
android:top="7dp"
|
||||
android:right="7dp"
|
||||
android:bottom="7dp" />
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
@ -0,0 +1,7 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFD0D0D0" />
|
||||
<stroke android:width="2dip" android:color="#FFD0D0D0"/>
|
||||
<padding android:left="7dp" android:top="7dp"
|
||||
android:right="7dp" android:bottom="7dp" />
|
||||
<corners android:radius="4dp" />
|
||||
</shape>
|
43
mobile/android/base/resources/layout/abouthome_content.xml
Normal file
43
mobile/android/base/resources/layout/abouthome_content.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<LinearLayout
|
||||
android:id="@+id/abouthome_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:isScrollContainer="true" >
|
||||
<ImageView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="100dip"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:src="@drawable/icon" />
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dip"
|
||||
android:textColor="#FF202020"
|
||||
android:textStyle="bold"
|
||||
android:text="Recommended Addons"
|
||||
android:isScrollContainer="false" />
|
||||
<ListView
|
||||
android:id="@+id/recommended_addon_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:divider="@android:color/transparent"
|
||||
android:isScrollContainer="false"
|
||||
android:dividerHeight="8dip" />
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dip"
|
||||
android:textColor="#FF202020"
|
||||
android:textStyle="bold"
|
||||
android:isScrollContainer="false"
|
||||
android:text="Favorite Sites" />
|
||||
<GridView
|
||||
android:id="@+id/grid"
|
||||
android:layout_width="fill_parent"
|
||||
android:isScrollContainer="false"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</merge>
|
41
mobile/android/base/resources/layout/abouthome_grid_box.xml
Normal file
41
mobile/android/base/resources/layout/abouthome_grid_box.xml
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="100dip"
|
||||
android:layout_height="150dip"
|
||||
android:padding="6dip"
|
||||
android:gravity="center_horizontal">
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/rounded_grey_box" >
|
||||
<ImageView
|
||||
android:id="@+id/screenshot"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="80dip" />
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent" >
|
||||
<ImageView
|
||||
android:id="@+id/bookmark_icon"
|
||||
android:layout_width="16dip"
|
||||
android:layout_height="16dip"
|
||||
android:layout_marginRight="6dip" />
|
||||
<TextView
|
||||
android:id="@+id/bookmark_title"
|
||||
android:singleLine="true"
|
||||
android:textColor="#FF202020"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#FF202020"
|
||||
android:id="@+id/bookmark_url"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="marquee" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -4,12 +4,8 @@
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
|
||||
%globalDTD;
|
||||
<!ENTITY % preferenceDTD SYSTEM "chrome://browser/locale/preferences.dtd" >
|
||||
%preferenceDTD;
|
||||
<!ENTITY % aboutDTD SYSTEM "chrome://browser/locale/aboutHome.dtd" >
|
||||
%aboutDTD;
|
||||
]>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
@ -53,458 +49,23 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&homepage.default;</title>
|
||||
<meta name="viewport" content="width=480; initial-scale=.6667; user-scalable=0" />
|
||||
<link rel="icon" type="image/png" href="chrome://branding/content/favicon32.png" />
|
||||
<link rel="stylesheet" href="chrome://browser/skin/aboutHome.css" type="text/css"/>
|
||||
<link rel="icon" type="image/png"
|
||||
href="chrome://branding/content/favicon32.png" />
|
||||
</head>
|
||||
|
||||
<body dir="&locale.dir;" onload="init();" onunload="uninit();">
|
||||
<div id="wrapper">
|
||||
<div id="header"><div id="logo"><img src="chrome://branding/content/logo.png"/></div>&aboutHome.header;</div>
|
||||
|
||||
<div id="content">
|
||||
<div id="recentTabs" class="section-box">
|
||||
<h1>&aboutHome.recentTabs;</h1>
|
||||
<div id="loadingTabs" class="loading">
|
||||
<img src="chrome://browser/skin/images/throbber.png"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="remoteTabs" class="section-row" onclick="openRemoteTabs();" role="button">
|
||||
<div>
|
||||
<img class="favicon" src="chrome://browser/skin/images/remotetabs-32.png"/>
|
||||
<div>&aboutHome.remoteTabs;</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="newAddons" class="section-row" onclick="goToAddons(' ');" role="button">
|
||||
<div>
|
||||
<img class="favicon" src="chrome://browser/skin/images/addons-32.png"/>
|
||||
<div>&aboutHome.recommendedAddons2;</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="newAddonsList" class="section-box" style="display: none;">
|
||||
</div>
|
||||
|
||||
<div id="locale" class="section-row" style="display: none;" onclick="openLocalePicker();" role="button">
|
||||
<div>&aboutHome.getLocale;</div>
|
||||
</div>
|
||||
|
||||
<div id="footer-wrapper">
|
||||
<span id="feedback" style="width: &aboutHome.footerWidth;" class="section-row" pref="app.feedbackURL" onclick="openLink(this);" role="button">&aboutHome.giveFeedback;</span
|
||||
><span id="support" style="width: &aboutHome.footerWidth;" class="section-row" pref="app.support.baseURL" onclick="openLink(this);" role="button">&aboutHome.getHelp;</span>
|
||||
</div>
|
||||
<div id="sync-setup">
|
||||
<a id="syncSetupSync" href="#" onclick="openSetupSyncWizard();">&aboutHome.setupSync;</a>
|
||||
<a id="syncPairDevice" href="#" onclick="openPairDeviceWizard();">&aboutHome.syncPairDevice;</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- l10n hack -->
|
||||
<div style="display: none">
|
||||
<span id="text-openalltabs">&aboutHome.openAllTabs;</span>
|
||||
<span id="text-notabs">&aboutHome.noTabs;</span>
|
||||
<span id="text-noaddons">&aboutHome.noAddons;</span>
|
||||
</div>
|
||||
|
||||
<!-- Lightbox -->
|
||||
<div id="lightbox">
|
||||
<div id="lightbox-background"></div>
|
||||
<div id="lightbox-wrapper">
|
||||
<div id="lightbox-container">
|
||||
<img id="lightbox-logo" src="chrome://browser/skin/images/aurora-lightbox-logo.png"/>
|
||||
<div id="lightbox-message">
|
||||
<p class="title">&aboutHome.getInBeforeBeta;</p>
|
||||
<p class="message">&aboutHome.tryAurora;</p>
|
||||
</div>
|
||||
<a id="lightbox-link">
|
||||
<div id="lightbox-button">
|
||||
<p class="title">&aboutHome.downloadAurora;</p>
|
||||
<p class="sub-title">&aboutHome.forAndroid;</p>
|
||||
</div>
|
||||
</a>
|
||||
<img id="lightbox-close" src="chrome://browser/skin/images/aurora-lightbox-close.png" alt="Aurora Close"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<body onload="init();" >
|
||||
<script type="application/javascript;version=1.8"><![CDATA[
|
||||
let Ci = Components.interfaces, Cc = Components.classes, Cu = Components.utils;
|
||||
let gChromeWin = null;
|
||||
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
function openLink(aElement) {
|
||||
try {
|
||||
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
||||
let url = formatter.formatURLPref(aElement.getAttribute("pref"));
|
||||
openTabs([url]);
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
function getChromeWin() {
|
||||
if (!gChromeWin) {
|
||||
gChromeWin = window
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
.rootTreeItem
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow)
|
||||
.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||
}
|
||||
return gChromeWin;
|
||||
}
|
||||
|
||||
function openLocalePicker() {
|
||||
let win = getChromeWin();
|
||||
win.BrowserUI.showPanel("prefs-container");
|
||||
win.document.getElementById("prefs-uilanguage-button").click();
|
||||
}
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
|
||||
function init() {
|
||||
initTabs();
|
||||
initAddons();
|
||||
initSetupSync();
|
||||
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).QueryInterface(Ci.nsIPrefBranch2);
|
||||
if (prefs.getBoolPref("browser.firstrun.show.uidiscovery")) {
|
||||
startDiscovery();
|
||||
prefs.setBoolPref("browser.firstrun.show.uidiscovery", false);
|
||||
document.getElementById("locale").style.display = "block";
|
||||
} else {
|
||||
endDiscovery();
|
||||
}
|
||||
|
||||
initLightbox();
|
||||
}
|
||||
|
||||
function uninit() {
|
||||
uninitAddons();
|
||||
uninitSetupSync();
|
||||
}
|
||||
|
||||
function _readFile(aFile, aCallback) {
|
||||
let channel = NetUtil.newChannel(aFile);
|
||||
channel.contentType = "application/json";
|
||||
NetUtil.asyncFetch(channel, function(aStream, aResult) {
|
||||
if (!Components.isSuccessCode(aResult)) {
|
||||
Cu.reportError("AboutHome: Could not read from " + aFile.leafName);
|
||||
aCallback(null);
|
||||
return;
|
||||
}
|
||||
|
||||
let fileSize = aStream.available();
|
||||
let cvstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
|
||||
cvstream.init(aStream, "UTF-8", fileSize, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
|
||||
let content = {};
|
||||
cvstream.readString(fileSize, content);
|
||||
cvstream.close();
|
||||
aStream.close();
|
||||
|
||||
aCallback(content.value.replace(/\r\n?/g, "\n"));
|
||||
});
|
||||
}
|
||||
|
||||
function openTabs(aURLs) {
|
||||
let BrowserUI = getChromeWin().BrowserUI;
|
||||
let owner = getChromeWin().Browser.selectedTab;
|
||||
for (let i=0; i < aURLs.length; i++) {
|
||||
BrowserUI.newTab(aURLs[i], owner);
|
||||
}
|
||||
}
|
||||
|
||||
function initTabs() {
|
||||
function noRecentTabs() {
|
||||
let placeHolder = document.getElementById("loadingTabs");
|
||||
placeHolder.innerHTML = "<div class='no-items'>" + document.getElementById("text-notabs").textContent + "</div>";
|
||||
}
|
||||
|
||||
let dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
let session = dirService.get("ProfD", Ci.nsILocalFile);
|
||||
session.append("sessionstore.bak");
|
||||
if (!session.exists()) {
|
||||
noRecentTabs();
|
||||
return;
|
||||
}
|
||||
|
||||
_readFile(session, function(aContent) {
|
||||
let data = JSON.parse(aContent);
|
||||
if (!data || data.windows.length == 0) {
|
||||
noRecentTabs();
|
||||
return;
|
||||
}
|
||||
|
||||
let chromeWin = getChromeWin();
|
||||
let allPageURLs = [];
|
||||
|
||||
let list = document.getElementById("recentTabs");
|
||||
|
||||
let tabs = data.windows[0].tabs;
|
||||
for (let i=0; i<tabs.length; i++) {
|
||||
let tabData = tabs[i];
|
||||
let tabEntry = tabData.entries[tabData.index - 1];
|
||||
|
||||
let url = tabEntry.url;
|
||||
if (url.indexOf("about:") == 0)
|
||||
continue;
|
||||
|
||||
let title = tabEntry.title;
|
||||
if (!title)
|
||||
continue;
|
||||
|
||||
let uri = chromeWin.Util.makeURI(url);
|
||||
let favicon = chromeWin.gFaviconService.getFaviconImageForPage(uri).spec;
|
||||
|
||||
let outer = document.createElement("a");
|
||||
outer.setAttribute("role", "button");
|
||||
outer.setAttribute("href", url);
|
||||
|
||||
allPageURLs.push(url);
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.className = "favicon";
|
||||
img.setAttribute("src", favicon);
|
||||
outer.appendChild(img);
|
||||
|
||||
let inner = document.createElement("div");
|
||||
inner.className = "inner";
|
||||
|
||||
let titlePart = document.createElement("div");
|
||||
titlePart.textContent = title;
|
||||
titlePart.className = "title";
|
||||
inner.appendChild(titlePart);
|
||||
|
||||
outer.appendChild(inner);
|
||||
list.appendChild(outer);
|
||||
}
|
||||
|
||||
if (allPageURLs.length > 0) {
|
||||
let loading = document.getElementById("loadingTabs");
|
||||
loading.parentNode.removeChild(loading);
|
||||
|
||||
if (allPageURLs.length > 1) {
|
||||
let outer = document.createElement("div");
|
||||
outer.className = "openall";
|
||||
outer.textContent = document.getElementById("text-openalltabs").textContent;
|
||||
outer.setAttribute("role", "button");
|
||||
|
||||
outer.addEventListener("click", function() {
|
||||
openTabs(allPageURLs);
|
||||
}, false);
|
||||
|
||||
list.appendChild(outer);
|
||||
let bridge = Cc["@mozilla.org/android/bridge;1"].getService(Ci.nsIAndroidBridge);
|
||||
let obj = { gecko: {
|
||||
type: "AboutHome:Show"
|
||||
}
|
||||
} else {
|
||||
noRecentTabs();
|
||||
}
|
||||
});
|
||||
};
|
||||
bridge.handleGeckoMessage(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
function openRemoteTabs() {
|
||||
getChromeWin().CommandUpdater.doCommand("cmd_remoteTabs");
|
||||
}
|
||||
|
||||
function goToAddons(aSearchString) {
|
||||
let chromeWin = getChromeWin();
|
||||
let BrowserUI = chromeWin.BrowserUI;
|
||||
BrowserUI.showPanel("addons-container");
|
||||
if (aSearchString) {
|
||||
// ExtensionsView initialization is delayed, so need to delay triggering
|
||||
// the search as well
|
||||
setTimeout(function () {
|
||||
// do the search
|
||||
chromeWin.ExtensionsView.doSearch(aSearchString);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
var RecommendedAddons = {
|
||||
_getFile: function() {
|
||||
let dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||
let file = dirService.get("ProfD", Ci.nsILocalFile);
|
||||
file.append("recommended-addons.json");
|
||||
return file;
|
||||
},
|
||||
|
||||
_loadAddons: function(aAddons) {
|
||||
if (aAddons.length == 0)
|
||||
return;
|
||||
|
||||
// Clear all content before filling the addons
|
||||
let list = document.getElementById("newAddonsList");
|
||||
while (list.firstElementChild)
|
||||
list.removeChild(list.firstElementChild);
|
||||
|
||||
for (let i=0; i<aAddons.length; i++) {
|
||||
let addon = aAddons[i];
|
||||
let outer = document.createElement("div");
|
||||
outer.setAttribute("role", "button");
|
||||
outer.setAttribute("addonID", addon.id);
|
||||
|
||||
let addonName = aAddons[i].name;
|
||||
outer.addEventListener("click", function() {
|
||||
goToAddons(addonName);
|
||||
}, false)
|
||||
|
||||
let img = document.createElement("img");
|
||||
img.className = "favicon";
|
||||
img.setAttribute("src", addon.iconURL);
|
||||
outer.appendChild(img);
|
||||
|
||||
let inner = document.createElement("div");
|
||||
inner.className = "inner";
|
||||
|
||||
let titlePart = document.createElement("span");
|
||||
titlePart.textContent = addon.name;
|
||||
titlePart.className = "title";
|
||||
inner.appendChild(titlePart);
|
||||
|
||||
let versionPart = document.createElement("span");
|
||||
versionPart.textContent = addon.version;
|
||||
versionPart.className = "version";
|
||||
inner.appendChild(versionPart);
|
||||
|
||||
outer.appendChild(inner);
|
||||
list.appendChild(outer);
|
||||
}
|
||||
|
||||
list.style.display = "block";
|
||||
document.getElementById("newAddons").setAttribute("showlist", "true");
|
||||
},
|
||||
|
||||
loadFromCache: function loadFromCache() {
|
||||
let self = this;
|
||||
let file = this._getFile();
|
||||
if (file.exists()) {
|
||||
_readFile(file, function(aContent) {
|
||||
let json = JSON.parse(aContent);
|
||||
if (!json || json.addons.length == 0) {
|
||||
self._loadAddons([]);
|
||||
return;
|
||||
}
|
||||
|
||||
self._loadAddons(json.addons);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateAddons() {
|
||||
RecommendedAddons.loadFromCache();
|
||||
}
|
||||
|
||||
function initAddons() {
|
||||
getChromeWin().Services.obs.addObserver(updateAddons, "recommended-addons-cache-updated", false);
|
||||
updateAddons();
|
||||
}
|
||||
|
||||
function uninitAddons() {
|
||||
getChromeWin().Services.obs.removeObserver(updateAddons, "recommended-addons-cache-updated");
|
||||
}
|
||||
|
||||
function startDiscovery() {
|
||||
let win = getChromeWin();
|
||||
|
||||
// If a sidebar is completely open, just bail
|
||||
let [leftWidth, rightWidth] = win.Browser.computeSidebarVisibility();
|
||||
if (leftWidth == 1 || rightWidth == 1 || win.Util.isTablet()) {
|
||||
endDiscovery();
|
||||
return;
|
||||
}
|
||||
|
||||
let doc = win.document;
|
||||
let broadcaster = doc.getElementById("bcast_uidiscovery");
|
||||
|
||||
doc.addEventListener("animationend", endDiscovery, false);
|
||||
doc.addEventListener("PanBegin", endDiscovery, false);
|
||||
broadcaster.setAttribute("mode", "discovery");
|
||||
}
|
||||
|
||||
function endDiscovery() {
|
||||
let doc = getChromeWin().document;
|
||||
let broadcaster = doc.getElementById("bcast_uidiscovery");
|
||||
|
||||
broadcaster.removeAttribute("mode");
|
||||
doc.removeEventListener("animationend", endDiscovery, false);
|
||||
doc.removeEventListener("PanBegin", endDiscovery, false);
|
||||
}
|
||||
|
||||
function initSetupSync() {
|
||||
let services = getChromeWin().Services;
|
||||
if (services.prefs.prefHasUserValue("services.sync.username")) {
|
||||
syncConnected();
|
||||
} else {
|
||||
syncDisconnected();
|
||||
}
|
||||
services.obs.addObserver(syncConnected, "weave:service:setup-complete", false);
|
||||
services.obs.addObserver(syncDisconnected, "weave:service:start-over", false);
|
||||
}
|
||||
|
||||
function uninitSetupSync() {
|
||||
let services = getChromeWin().Services;
|
||||
services.obs.removeObserver(syncConnected, "weave:service:setup-complete");
|
||||
services.obs.removeObserver(syncDisconnected, "weave:service:start-over");
|
||||
}
|
||||
|
||||
function syncConnected() {
|
||||
document.getElementById("syncSetupSync").style.display = "none";
|
||||
document.getElementById("syncPairDevice").style.display = "inline";
|
||||
}
|
||||
|
||||
function syncDisconnected() {
|
||||
document.getElementById("syncSetupSync").style.display = "inline";
|
||||
document.getElementById("syncPairDevice").style.display = "none";
|
||||
}
|
||||
|
||||
function openSetupSyncWizard() {
|
||||
let chromeWin = getChromeWin();
|
||||
chromeWin.WeaveGlue.open();
|
||||
}
|
||||
|
||||
function openPairDeviceWizard() {
|
||||
let chromeWin = getChromeWin();
|
||||
chromeWin.SyncPairDevice.open();
|
||||
}
|
||||
|
||||
function initLightbox() {
|
||||
let prefs = getChromeWin().Services.prefs;
|
||||
let channel = prefs.getCharPref("app.update.channel");
|
||||
let startupCount = 0;
|
||||
try {
|
||||
startupCount = prefs.getIntPref("app.promo.aurora");
|
||||
if(startupCount != 6)
|
||||
prefs.setIntPref("app.promo.aurora", ++startupCount);
|
||||
} catch(e) {
|
||||
prefs.setIntPref("app.promo.aurora", 1);
|
||||
}
|
||||
|
||||
// This should appear only on "beta" channel on the fifth launch.
|
||||
if ((channel == "beta") && (startupCount == 5)) {
|
||||
let close = document.getElementById("lightbox-close");
|
||||
close.addEventListener("click", function() {
|
||||
document.getElementById("lightbox").style.display = "none";
|
||||
}, false);
|
||||
|
||||
let link = document.getElementById("lightbox-link");
|
||||
link.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
document.getElementById("lightbox").style.display = "none";
|
||||
|
||||
let BrowserUI = getChromeWin().BrowserUI;
|
||||
let owner = getChromeWin().Browser.selectedTab;
|
||||
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
||||
let linkUrl = formatter.formatURLPref("app.channelURL");
|
||||
BrowserUI.newTab(linkUrl, owner);
|
||||
}, false);
|
||||
|
||||
// Giving a chance for any page transitions to happen, if any, before displaying the lightbox
|
||||
setTimeout(function() {
|
||||
document.getElementById("lightbox").style.display = "block";
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
]]></script>
|
||||
]]></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -88,6 +88,7 @@
|
||||
@BINPATH@/res/drawable
|
||||
@BINPATH@/res/drawable-hdpi
|
||||
@BINPATH@/res/layout
|
||||
@BINPATH@/recommended-addons.json
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_PLATFORM_MAEMO
|
||||
|
@ -1,31 +0,0 @@
|
||||
<!ENTITY aboutHome.header "<span>&brandShortName; </span><span id='header-suffix'>Start</span>">
|
||||
<!ENTITY aboutHome.recentTabs "Your tabs from last time">
|
||||
<!ENTITY aboutHome.remoteTabs "Tabs from your other computers">
|
||||
<!ENTITY aboutHome.recommendedAddons2 "Add-ons for your &brandShortName;">
|
||||
<!ENTITY aboutHome.giveFeedback "Give Feedback">
|
||||
<!ENTITY aboutHome.getHelp "Get Help">
|
||||
<!ENTITY aboutHome.footerWidth "10em">
|
||||
<!ENTITY aboutHome.openAllTabs "Open all in tabs">
|
||||
<!ENTITY aboutHome.noTabs "No tabs from last time">
|
||||
<!ENTITY aboutHome.noAddons "No recommended add-ons">
|
||||
<!ENTITY aboutHome.getLocale "Change Language">
|
||||
<!ENTITY aboutHome.getInBeforeBeta "Get in before Beta.">
|
||||
<!ENTITY aboutHome.tryAurora "Try Firefox Aurora and help shape the future of Firefox.">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
(aboutHome.downloadAurora): First line of a multi-line button. Treat as a title.
|
||||
-->
|
||||
<!ENTITY aboutHome.downloadAurora "Download Aurora">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
(aboutHome.forAndroid): Second line of a multi-line button. Treat as a subtitle.
|
||||
-->
|
||||
<!ENTITY aboutHome.forAndroid "for Android">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
(aboutHome.setupSync): This string should match the desktop
|
||||
equivalent, in particular concerning syncBrand.fullName.label.
|
||||
-->
|
||||
<!ENTITY aboutHome.setupSync "Set Up Sync">
|
||||
<!-- LOCALIZATION NOTE:
|
||||
(aboutHome.syncPairDevice): This string should match the desktop
|
||||
equivalent, in particular concerning syncBrand.fullName.label.
|
||||
-->
|
||||
<!ENTITY aboutHome.syncPairDevice "Pair a Device">
|
@ -6,7 +6,6 @@
|
||||
locale/@AB_CD@/browser/aboutAddons.dtd (%chrome/aboutAddons.dtd)
|
||||
locale/@AB_CD@/browser/aboutAddons.properties (%chrome/aboutAddons.properties)
|
||||
locale/@AB_CD@/browser/aboutCertError.dtd (%chrome/aboutCertError.dtd)
|
||||
locale/@AB_CD@/browser/aboutHome.dtd (%chrome/aboutHome.dtd)
|
||||
locale/@AB_CD@/browser/browser.dtd (%chrome/browser.dtd)
|
||||
locale/@AB_CD@/browser/browser.properties (%chrome/browser.properties)
|
||||
locale/@AB_CD@/browser/config.dtd (%chrome/config.dtd)
|
||||
|
@ -1,413 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Mobile Browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mark Finkle <mfinkle@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
html {
|
||||
background: white;
|
||||
font-family: "Nokia Sans", Tahoma, sans-serif !important;
|
||||
font-size: 24px;
|
||||
margin: 0px 20px;
|
||||
}
|
||||
|
||||
#wrapper {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#logo {
|
||||
float: right;
|
||||
margin-top: -24px;
|
||||
-moz-margin-end: -34px;
|
||||
/* Trick to ensure this is shown above the opacity transform happening to content*/
|
||||
-moz-transform: translate(0,0);
|
||||
}
|
||||
|
||||
body[dir="rtl"] #logo {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#header {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
background: transparent -moz-linear-gradient(top, rgba(57,89,117,1) 0%, rgba(30,66,98,1) 50%, rgba(24,54,82,1) 90%);
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
padding-bottom: 14px;
|
||||
margin-bottom: 12px;
|
||||
margin-top: 20px;
|
||||
box-shadow: inset rgba(0, 0, 0, 0.2) 0 -3px 0px, rgba(0, 0, 0, 0.1) 0px 2px 0px;
|
||||
}
|
||||
|
||||
#header-suffix {
|
||||
color: rgb(112,136,156);
|
||||
}
|
||||
|
||||
.section-box {
|
||||
background-color: white;
|
||||
padding: 0;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(0,0,0,0.3);
|
||||
box-shadow:
|
||||
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
|
||||
inset rgba(0, 0, 0, 0.1) 0 -3px 0px,
|
||||
rgba(0, 0, 0, 0.1) 0px 2px 0px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-box > h1 {
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
color: black;
|
||||
background: transparent -moz-linear-gradient(top, rgba(235,235,235,0.2) 0%, rgba(235,235,235,1) 90%);
|
||||
margin: 0;
|
||||
padding: 4px 12px 8px 12px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.section-box > div,
|
||||
.section-box > a {
|
||||
border-bottom: 1px solid rgba(0,0,0,0.1);
|
||||
padding: 8px;
|
||||
padding-bottom: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-box > a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.section-box > div:last-child,
|
||||
.section-box > a:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
/* Make room for the image */
|
||||
.section-box > div > div,
|
||||
.section-box > a > div,
|
||||
.section-row > div > div {
|
||||
-moz-margin-start: 48px;
|
||||
}
|
||||
|
||||
.section-box .title {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.section-box .openall {
|
||||
font-size: 18px;
|
||||
padding: 12px 8px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
body[dir="ltr"] .section-box .openall {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.section-box .version {
|
||||
/* The addon title is not localized, so keep the margin on the left side */
|
||||
margin-left: 12px;
|
||||
font-size: 18px;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.section-box .inner {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.section-box .favicon {
|
||||
border: none;
|
||||
top: 8px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
body[dir="ltr"] .section-box .favicon {
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
body[dir="ltr"] .section-box .favicon {
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
body[dir="ltr"] #newAddons > div:not(.loading) {
|
||||
background: url("images/arrowright-16.png") 99% center no-repeat;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #newAddons > div:not(.loading) {
|
||||
background: url("images/arrowleft-16.png") 1% center no-repeat;
|
||||
}
|
||||
|
||||
#remoteTabs[disabled=true] {
|
||||
pointer-events: none;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
#remoteTabs[disabled=true] > div > .favicon {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.section-row {
|
||||
color: black;
|
||||
background: transparent -moz-linear-gradient(top, rgba(235,235,235,0.2) 0%, rgba(235,235,235,1) 90%);
|
||||
padding: 8px;
|
||||
padding-bottom: 12px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(0,0,0,0.3);
|
||||
box-shadow:
|
||||
inset rgba(255, 255, 255, 0.5) 0 1px 0px,
|
||||
inset rgba(0, 0, 0, 0.1) 0 -3px 0px,
|
||||
rgba(0, 0, 0, 0.1) 0px 2px 0px;
|
||||
margin: 24px auto;
|
||||
}
|
||||
|
||||
.section-row > div {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.section-row .favicon {
|
||||
border: none;
|
||||
top: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#newAddons {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Make sure the button and list match up nicely */
|
||||
#newAddons[showlist] {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
box-shadow: none;
|
||||
margin: 0 -2px 0 0;
|
||||
}
|
||||
|
||||
#newAddonsList {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
body[dir="ltr"] {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
body[dir="rtl"] {
|
||||
right: 4px;
|
||||
}
|
||||
|
||||
.loading > img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.no-items {
|
||||
text-align: center;
|
||||
-moz-margin-start: 0 !important;
|
||||
}
|
||||
|
||||
#footer-wrapper {
|
||||
font-size: 18px;
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#feedback {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#support {
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#sync-setup {
|
||||
font-size: 18px;
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#syncSetupSync,
|
||||
#syncPairDevice {
|
||||
text-decoration: underline;
|
||||
color: blue;
|
||||
}
|
||||
|
||||
/* Lightbox for Aurora */
|
||||
#lightbox {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#lightbox-background {
|
||||
background-color: #000;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
#lightbox-wrapper {
|
||||
background: transparent;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#lightbox-container {
|
||||
max-width: 300px;
|
||||
margin: 40px auto;
|
||||
background: #000 url("images/aurora-lightbox-bg.jpg") center top no-repeat;
|
||||
border-radius: 6px;
|
||||
padding: 26px 0px 0px;
|
||||
border: 1px solid #000;
|
||||
box-shadow: rgba(0, 0, 0, 0.75) 0px 0px 10px 2px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#lightbox-logo {
|
||||
width: 65%;
|
||||
max-width: 195px;
|
||||
display: block;
|
||||
margin: 0px auto;
|
||||
}
|
||||
|
||||
#lightbox-message {
|
||||
width: 100%;
|
||||
padding: 34px 0px 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#lightbox-message > p,
|
||||
#lightbox-button > p {
|
||||
font-family: Georgia;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#lightbox-message > p.title ,
|
||||
#lightbox-button > p.title {
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
color: #fff;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#lightbox-message > p.message,
|
||||
#lightbox-button > p.sub-title {
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
#lightbox-message > p.message {
|
||||
color: #c0b5b5;
|
||||
}
|
||||
|
||||
#lightbox-container a,
|
||||
#lightbox-container a:hover,
|
||||
#lightbox-container a:visited {
|
||||
outline: 0px;
|
||||
border: 0px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#lightbox-button {
|
||||
background: -moz-linear-gradient(center top , #84C63C 0%, #489615 100%) repeat scroll 0 0 transparent;
|
||||
margin: 10px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
padding: 18px 0px;
|
||||
box-shadow: rgba(0, 0, 0, 0) 0px 0px, inset rgba(0, 0, 0, 0.1) 0px -3px;
|
||||
}
|
||||
|
||||
#lightbox-button > p.title,
|
||||
#lightbox-button > p.sub-title {
|
||||
text-shadow: rgba(136, 136, 136, 0.39) 0px 0px 0px -1px;
|
||||
}
|
||||
|
||||
#lightbox-button > p.sub-title {
|
||||
font-style: italic;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#lightbox-close {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 399px) {
|
||||
#support {
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 400px) {
|
||||
body[dir="ltr"] #feedback {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #feedback {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
#support {
|
||||
-moz-border-start: none;
|
||||
}
|
||||
|
||||
body[dir="ltr"] #support {
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #support {
|
||||
border-radius: 8px 0 0 8px;
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ chrome.jar:
|
||||
skin/aboutPage.css (aboutPage.css)
|
||||
skin/about.css (about.css)
|
||||
skin/aboutAddons.css (aboutAddons.css)
|
||||
skin/aboutHome.css (aboutHome.css)
|
||||
* skin/browser.css (browser.css)
|
||||
* skin/content.css (content.css)
|
||||
skin/config.css (config.css)
|
||||
@ -90,7 +89,6 @@ chrome.jar:
|
||||
skin/gingerbread/aboutPage.css (aboutPage.css)
|
||||
skin/gingerbread/about.css (about.css)
|
||||
skin/gingerbread/aboutAddons.css (aboutAddons.css)
|
||||
skin/gingerbread/aboutHome.css (aboutHome.css)
|
||||
* skin/gingerbread/browser.css (gingerbread/browser.css)
|
||||
* skin/gingerbread/content.css (gingerbread/content.css)
|
||||
skin/gingerbread/config.css (config.css)
|
||||
@ -168,7 +166,6 @@ chrome.jar:
|
||||
skin/honeycomb/aboutPage.css (aboutPage.css)
|
||||
skin/honeycomb/about.css (about.css)
|
||||
skin/honeycomb/aboutAddons.css (aboutAddons.css)
|
||||
skin/honeycomb/aboutHome.css (aboutHome.css)
|
||||
* skin/honeycomb/browser.css (honeycomb/browser.css)
|
||||
* skin/honeycomb/content.css (content.css)
|
||||
skin/honeycomb/config.css (config.css)
|
||||
|
@ -298,6 +298,7 @@ DIST_FILES = \
|
||||
chrome.manifest \
|
||||
update.locale \
|
||||
removed-files \
|
||||
recommended-addons.json \
|
||||
$(NULL)
|
||||
|
||||
NON_DIST_FILES = \
|
||||
|
Loading…
Reference in New Issue
Block a user