Merge branch 'develop' of github.com:mozilla/f1 into develop
8
Makefile
|
@ -2,7 +2,8 @@ APPNAME = server-shared-send
|
||||||
DEPS = server-share-core
|
DEPS = server-share-core
|
||||||
VIRTUALENV = virtualenv
|
VIRTUALENV = virtualenv
|
||||||
NOSE = bin/nosetests
|
NOSE = bin/nosetests
|
||||||
NOSETESTS_ARGS = -s --with-xunit --with-coverage --cover-package=linkdrop,linkoauth --cover-erase
|
NOSETESTS_ARGS = -s
|
||||||
|
NOSETESTS_ARGS_C = -s --with-xunit --with-coverage --cover-package=linkdrop,linkoauth --cover-erase
|
||||||
TESTS = linkdrop/tests deps/server-share-core/linkoauth/tests
|
TESTS = linkdrop/tests deps/server-share-core/linkoauth/tests
|
||||||
PYTHON = bin/python
|
PYTHON = bin/python
|
||||||
version = $(shell $(PYTHON) setup.py --version)
|
version = $(shell $(PYTHON) setup.py --version)
|
||||||
|
@ -111,6 +112,9 @@ build:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
$(NOSE) $(NOSETESTS_ARGS) $(TESTS)
|
$(NOSE) $(NOSETESTS_ARGS) $(TESTS)
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
$(NOSE) $(NOSETESTS_ARGS_C) $(TESTS)
|
||||||
$(COVERAGE) xml
|
$(COVERAGE) xml
|
||||||
|
|
||||||
.PHONY: xpi clean dist rpm build test
|
.PHONY: xpi clean dist rpm build test coverage
|
||||||
|
|
26
README.md
|
@ -21,25 +21,25 @@ Some directory explanations:
|
||||||
git clone https://github.com/mozilla/f1.git
|
git clone https://github.com/mozilla/f1.git
|
||||||
cd f1
|
cd f1
|
||||||
|
|
||||||
### Setup a virtual environment (optional, recommended):
|
### Setup dependencies:
|
||||||
|
|
||||||
sudo easy_install virtualenv
|
make build
|
||||||
virtualenv env
|
|
||||||
source env/bin/activate
|
|
||||||
|
|
||||||
### Dependency installation
|
If you get this error on Mac OS X:
|
||||||
|
|
||||||
python setup.py develop
|
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/stdarg.h:4:25: error: stdarg.h: No such file or directory
|
||||||
|
|
||||||
### Make a config file as follows::
|
It could be because the default version of GCC is too high. If you do
|
||||||
|
|
||||||
# **skip this step for now**
|
ls -la /usr/bin/gcc
|
||||||
# paster make-config f1 config.ini
|
|
||||||
|
|
||||||
### Tweak the config file as appropriate and then setup the application::
|
And it points to gcc-4.2, then change it to point to gcc-4.0 (warning affects all gcc calls from then on):
|
||||||
|
|
||||||
|
sudo rm /usr/bin/gcc
|
||||||
|
sudo ln -s /usr/bin/gcc-4.0 /usr/bin/gcc
|
||||||
|
|
||||||
|
Info taken from [this web site](http://blog.coredumped.org/2009/09/snow-leopard-and-lxml.html)
|
||||||
|
|
||||||
# **skip this step for now**
|
|
||||||
# paster setup-app config.ini
|
|
||||||
|
|
||||||
### Running f1
|
### Running f1
|
||||||
|
|
||||||
|
@ -65,5 +65,3 @@ To test: Once that is done, you can bypass normal access to your domain by addin
|
||||||
Update development.ini and add your key/secret for the google configuration, restart paster.
|
Update development.ini and add your key/secret for the google configuration, restart paster.
|
||||||
|
|
||||||
Then in the web browser, hit f1 with http://your.host.com.
|
Then in the web browser, hit f1 with http://your.host.com.
|
||||||
|
|
||||||
|
|
||||||
|
|
174
_build.py
|
@ -1,174 +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 Sync Server
|
|
||||||
#
|
|
||||||
# The Initial Developer of the Original Code is the Mozilla Foundation.
|
|
||||||
# Portions created by the Initial Developer are Copyright (C) 2010
|
|
||||||
# the Initial Developer. All Rights Reserved.
|
|
||||||
#
|
|
||||||
# Contributor(s):
|
|
||||||
# Tarek Ziade (tarek@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 *****
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
|
|
||||||
CURDIR = os.path.dirname(__file__)
|
|
||||||
REPO_ROOT = 'git@github.com:mozilla/%s.git'
|
|
||||||
PYTHON = sys.executable
|
|
||||||
|
|
||||||
|
|
||||||
def verify_tag(tag):
|
|
||||||
if tag == 'tip' or tag.isdigit():
|
|
||||||
return True
|
|
||||||
sub = subprocess.Popen('hg tags', shell=True, stdout=subprocess.PIPE)
|
|
||||||
tags = [tag_ for tag_ in
|
|
||||||
[line.split()[0] for line in
|
|
||||||
sub.stdout.read().strip().split('\n')]
|
|
||||||
if tag_.startswith('rpm-')]
|
|
||||||
return tag in tags
|
|
||||||
|
|
||||||
|
|
||||||
def get_latest_tag():
|
|
||||||
sub = subprocess.Popen('hg tags', shell=True, stdout=subprocess.PIPE)
|
|
||||||
tags = [tag for tag in
|
|
||||||
[line.split()[0] for line in
|
|
||||||
sub.stdout.read().strip().split('\n')]
|
|
||||||
if tag.startswith('rpm-')]
|
|
||||||
if len(tags) == 0:
|
|
||||||
raise ValueError('Could not find a rpm tag')
|
|
||||||
|
|
||||||
return tags[0]
|
|
||||||
|
|
||||||
|
|
||||||
def _run(command):
|
|
||||||
print(command)
|
|
||||||
os.system(command)
|
|
||||||
|
|
||||||
|
|
||||||
def _envname(name):
|
|
||||||
return name.upper().replace('-', '_')
|
|
||||||
|
|
||||||
|
|
||||||
def _update_cmd(project, latest_tags=False):
|
|
||||||
if latest_tags:
|
|
||||||
return 'git checkout -r "%s"' % get_latest_tag()
|
|
||||||
else:
|
|
||||||
|
|
||||||
# looking for an environ with a specific tag or rev
|
|
||||||
rev = os.environ.get(_envname(project))
|
|
||||||
if rev is not None:
|
|
||||||
|
|
||||||
if not verify_tag(rev):
|
|
||||||
print('Unknown tag or revision: %s' % rev)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return 'git checkout -r "%s"' % rev
|
|
||||||
return 'git checkout'
|
|
||||||
|
|
||||||
|
|
||||||
def build_app(name, latest_tags, deps):
|
|
||||||
# building deps first
|
|
||||||
build_deps(deps, latest_tags)
|
|
||||||
|
|
||||||
# build the app now
|
|
||||||
if not _has_spec():
|
|
||||||
latest_tags = False
|
|
||||||
|
|
||||||
_run(_update_cmd(name, latest_tags))
|
|
||||||
_run('%s setup.py develop' % PYTHON)
|
|
||||||
|
|
||||||
|
|
||||||
def build_deps(deps, latest_tags):
|
|
||||||
"""Will make sure dependencies are up-to-date"""
|
|
||||||
location = os.getcwd()
|
|
||||||
# do we want the latest tags ?
|
|
||||||
try:
|
|
||||||
deps_dir = os.path.abspath(os.path.join(CURDIR, 'deps'))
|
|
||||||
if not os.path.exists(deps_dir):
|
|
||||||
os.mkdir(deps_dir)
|
|
||||||
|
|
||||||
for dep in deps:
|
|
||||||
repo = REPO_ROOT % dep
|
|
||||||
target = os.path.join(deps_dir, dep)
|
|
||||||
if os.path.exists(target):
|
|
||||||
os.chdir(target)
|
|
||||||
_run('git pull')
|
|
||||||
else:
|
|
||||||
_run('git clone %s %s' % (repo, target))
|
|
||||||
os.chdir(target)
|
|
||||||
|
|
||||||
update_cmd = _update_cmd(dep, latest_tags)
|
|
||||||
_run(update_cmd)
|
|
||||||
_run('%s setup.py develop' % PYTHON)
|
|
||||||
finally:
|
|
||||||
os.chdir(location)
|
|
||||||
|
|
||||||
|
|
||||||
def _has_spec():
|
|
||||||
specs = [file_ for file_ in os.listdir('.')
|
|
||||||
if file_.endswith('.spec')]
|
|
||||||
return len(specs)
|
|
||||||
|
|
||||||
|
|
||||||
def main(project_name, deps):
|
|
||||||
# check the provided values in the environ
|
|
||||||
latest_tags = 'LATEST_TAGS' in os.environ
|
|
||||||
|
|
||||||
if not latest_tags:
|
|
||||||
# if we have some tags in the environ, check that they are all defined
|
|
||||||
projects = list(deps)
|
|
||||||
|
|
||||||
# is the root a project itself or just a placeholder ?
|
|
||||||
if _has_spec():
|
|
||||||
projects.append(project_name)
|
|
||||||
|
|
||||||
tags = {}
|
|
||||||
missing = 0
|
|
||||||
for project in projects:
|
|
||||||
tag = _envname(project)
|
|
||||||
if tag in os.environ:
|
|
||||||
tags[tag] = os.environ[tag]
|
|
||||||
else:
|
|
||||||
tags[tag] = 'Not provided'
|
|
||||||
missing += 1
|
|
||||||
|
|
||||||
# we want all tag or no tag
|
|
||||||
if missing > 0 and missing < len(projects):
|
|
||||||
print("You did not specify all tags: ")
|
|
||||||
for project, tag in tags.items():
|
|
||||||
print(' %s: %s' % (project, tag))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
build_app(project_name, latest_tags, deps)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
project_name = sys.argv[1]
|
|
||||||
deps = [dep.strip() for dep in sys.argv[2].split(',')]
|
|
||||||
main(project_name, deps)
|
|
172
build.py
|
@ -33,71 +33,141 @@
|
||||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
"""
|
|
||||||
Bootstrap file -- will try to make sure _build.py is up-to-date, then run it.
|
|
||||||
"""
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib2
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def _rename(path):
|
CURDIR = os.path.dirname(__file__)
|
||||||
if not os.path.exists(path):
|
REPO_ROOT = 'https://github.com/mozilla/%s.git'
|
||||||
return
|
PYTHON = sys.executable
|
||||||
|
|
||||||
root = 0
|
|
||||||
newname = path + '.bak.%d' % root
|
|
||||||
while os.path.exists(newname):
|
|
||||||
root += 1
|
|
||||||
newname = path + '.bak.%d' % root
|
|
||||||
os.rename(path, newname)
|
|
||||||
|
|
||||||
|
|
||||||
def _update():
|
def _get_tags():
|
||||||
# getting the file age
|
sub = subprocess.Popen('git tag', shell=True, stdout=subprocess.PIPE)
|
||||||
if os.path.exists('._build.etag'):
|
tags = [line.strip()
|
||||||
with open('._build.etag') as f:
|
for line in sub.stdout.read().strip().split('\n')
|
||||||
current_etag = f.read().strip()
|
if line.strip() != '']
|
||||||
headers = {'If-None-Match': current_etag}
|
tags.reverse()
|
||||||
|
return tags
|
||||||
|
|
||||||
|
|
||||||
|
def verify_tag(tag):
|
||||||
|
if tag == 'tip' or tag.isdigit():
|
||||||
|
return True
|
||||||
|
return tag in _get_tags()
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_tag():
|
||||||
|
tags = _get_tags()
|
||||||
|
if len(tags) == 0:
|
||||||
|
raise ValueError('Could not find a tag')
|
||||||
|
return tags[0]
|
||||||
|
|
||||||
|
|
||||||
|
def _run(command):
|
||||||
|
print(command)
|
||||||
|
os.system(command)
|
||||||
|
|
||||||
|
|
||||||
|
def _envname(name):
|
||||||
|
return name.upper().replace('-', '_')
|
||||||
|
|
||||||
|
|
||||||
|
def _update_cmd(project, latest_tags=False):
|
||||||
|
if latest_tags:
|
||||||
|
return 'git checkout -r "%s"' % get_latest_tag()
|
||||||
else:
|
else:
|
||||||
headers = {}
|
|
||||||
current_etag = None
|
|
||||||
|
|
||||||
request = urllib2.Request('http://moz.ziade.org/_build.py',
|
# looking for an environ with a specific tag or rev
|
||||||
headers=headers)
|
rev = os.environ.get(_envname(project))
|
||||||
|
if rev is not None:
|
||||||
|
|
||||||
# checking the last version on our server
|
if not verify_tag(rev):
|
||||||
|
print('Unknown tag or revision: %s' % rev)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
return 'git checkout -r "%s"' % rev
|
||||||
|
return 'git checkout'
|
||||||
|
|
||||||
|
|
||||||
|
def build_app(name, latest_tags, deps):
|
||||||
|
# building deps first
|
||||||
|
build_deps(deps, latest_tags)
|
||||||
|
|
||||||
|
# build the app now
|
||||||
|
if not _has_spec():
|
||||||
|
latest_tags = False
|
||||||
|
|
||||||
|
_run(_update_cmd(name, latest_tags))
|
||||||
|
_run('%s setup.py develop' % PYTHON)
|
||||||
|
|
||||||
|
|
||||||
|
def build_deps(deps, latest_tags):
|
||||||
|
"""Will make sure dependencies are up-to-date"""
|
||||||
|
location = os.getcwd()
|
||||||
|
# do we want the latest tags ?
|
||||||
try:
|
try:
|
||||||
url = urllib2.urlopen(request, timeout=5)
|
deps_dir = os.path.abspath(os.path.join(CURDIR, 'deps'))
|
||||||
etag = url.headers.get('ETag')
|
if not os.path.exists(deps_dir):
|
||||||
except urllib2.HTTPError, e:
|
os.mkdir(deps_dir)
|
||||||
if e.getcode() != 412:
|
|
||||||
raise
|
|
||||||
# we're up-to-date (precondition failed)
|
|
||||||
etag = current_etag
|
|
||||||
except urllib2.URLError:
|
|
||||||
# timeout error
|
|
||||||
etag = None
|
|
||||||
|
|
||||||
if etag is not None and current_etag != etag:
|
for dep in deps:
|
||||||
# we need to update our version
|
repo = REPO_ROOT % dep
|
||||||
_rename('_build.py')
|
target = os.path.join(deps_dir, dep)
|
||||||
content = url.read()
|
if os.path.exists(target):
|
||||||
with open('_build.py', 'w') as f:
|
os.chdir(target)
|
||||||
f.write(content)
|
_run('git pull')
|
||||||
|
else:
|
||||||
|
_run('git clone %s %s' % (repo, target))
|
||||||
|
os.chdir(target)
|
||||||
|
|
||||||
with open('._build.etag', 'w') as f:
|
update_cmd = _update_cmd(dep, latest_tags)
|
||||||
f.write(etag)
|
_run(update_cmd)
|
||||||
|
_run('%s setup.py develop' % PYTHON)
|
||||||
|
finally:
|
||||||
|
os.chdir(location)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def _has_spec():
|
||||||
#_update()
|
specs = [file_ for file_ in os.listdir('.')
|
||||||
# we're good, let's import the file and run it
|
if file_.endswith('.spec')]
|
||||||
mod = __import__('_build')
|
return len(specs)
|
||||||
project_name = sys.argv[1]
|
|
||||||
deps = [dep.strip() for dep in sys.argv[2].split(',')]
|
|
||||||
mod.main(project_name, deps)
|
def main(project_name, deps):
|
||||||
|
# check the provided values in the environ
|
||||||
|
latest_tags = 'LATEST_TAGS' in os.environ
|
||||||
|
|
||||||
|
if not latest_tags:
|
||||||
|
# if we have some tags in the environ, check that they are all defined
|
||||||
|
projects = list(deps)
|
||||||
|
|
||||||
|
# is the root a project itself or just a placeholder ?
|
||||||
|
if _has_spec():
|
||||||
|
projects.append(project_name)
|
||||||
|
|
||||||
|
tags = {}
|
||||||
|
missing = 0
|
||||||
|
for project in projects:
|
||||||
|
tag = _envname(project)
|
||||||
|
if tag in os.environ:
|
||||||
|
tags[tag] = os.environ[tag]
|
||||||
|
else:
|
||||||
|
tags[tag] = 'Not provided'
|
||||||
|
missing += 1
|
||||||
|
|
||||||
|
# we want all tag or no tag
|
||||||
|
if missing > 0 and missing < len(projects):
|
||||||
|
print("You did not specify all tags: ")
|
||||||
|
for project, tag in tags.items():
|
||||||
|
print(' %s: %s' % (project, tag))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
build_app(project_name, latest_tags, deps)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
project_name = sys.argv[1]
|
||||||
|
deps = [dep.strip() for dep in sys.argv[2].split(',')]
|
||||||
|
main(project_name, deps)
|
||||||
|
|
|
@ -11,8 +11,8 @@ import = %(here)s/private.ini
|
||||||
smtp_server = localhost
|
smtp_server = localhost
|
||||||
error_email_from = paste@localhost
|
error_email_from = paste@localhost
|
||||||
|
|
||||||
oauth_failure = /0.3.3/auth.html#oauth_failure
|
oauth_failure = /0.3.4/auth.html#oauth_failure
|
||||||
oauth_success = /0.3.3/auth.html#oauth_success
|
oauth_success = /0.3.4/auth.html#oauth_success
|
||||||
|
|
||||||
# Register with twitter at http://dev.twitter.com/apps/new
|
# Register with twitter at http://dev.twitter.com/apps/new
|
||||||
oauth.twitter.com.request = https://twitter.com/oauth/request_token
|
oauth.twitter.com.request = https://twitter.com/oauth/request_token
|
||||||
|
|
2
setup.py
|
@ -28,7 +28,7 @@ except ImportError:
|
||||||
use_setuptools()
|
use_setuptools()
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
VERSION='0.3.3'
|
VERSION='0.3.4'
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='linkdrop',
|
name='linkdrop',
|
||||||
|
|
|
@ -11,8 +11,8 @@ import = %(here)s/private.ini
|
||||||
smtp_server = localhost
|
smtp_server = localhost
|
||||||
error_email_from = paste@localhost
|
error_email_from = paste@localhost
|
||||||
|
|
||||||
oauth_failure = /0.3.3/auth.html#oauth_failure
|
oauth_failure = /0.3.4/auth.html#oauth_failure
|
||||||
oauth_success = /0.3.3/auth.html#oauth_success
|
oauth_success = /0.3.4/auth.html#oauth_success
|
||||||
|
|
||||||
# Register with twitter at http://dev.twitter.com/apps/new
|
# Register with twitter at http://dev.twitter.com/apps/new
|
||||||
oauth.twitter.com.request = https://twitter.com/oauth/request_token
|
oauth.twitter.com.request = https://twitter.com/oauth/request_token
|
||||||
|
|
|
@ -0,0 +1,323 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Firefox Share OAuthorization</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
|
|
||||||
|
<script src="/0.3.4/scripts/requireplugins-jquery.js" charset="utf-8"></script>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 100%;
|
||||||
|
color: #0A0A0A;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 21px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connecting {
|
||||||
|
margin-top: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connecting img {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#oauth {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -150px;
|
||||||
|
margin-top: -95px;
|
||||||
|
width: 300px;
|
||||||
|
background-image: url("/0.3.4/i/f1Logo.png");
|
||||||
|
background-position: center top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
padding: 100px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#oauth .text {
|
||||||
|
display: block;
|
||||||
|
margin: 0 0 7px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#oauth .subtext {
|
||||||
|
margin-left: 7px;
|
||||||
|
color: #666666;
|
||||||
|
font-family: "Lucida Grande", Verdana, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
height: 30px;
|
||||||
|
border-width: 1px 1px 1px 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
-moz-border-radius: 0 2px 2px 0;
|
||||||
|
-webkit-border-radius: 0 2px 2px 0;
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
|
||||||
|
background-image: -moz-linear-gradient(center top , #fafafa 0%, #ddd 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fafafa), color-stop(100%, #ddd));
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
-moz-box-shadow: 0 0 1px #666666 inset;
|
||||||
|
-webkit-box-shadow: 0 0 1px #666666 inset;
|
||||||
|
box-shadow: 0 0 1px #666666 inset;
|
||||||
|
|
||||||
|
background-image: -moz-linear-gradient(center top , #eee 0%, #ccc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eee), color-stop(100%, #ccc));
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #888;
|
||||||
|
font-family: "Lucida Grande", Verdana, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
-moz-border-radius: 2px 0 0 2px;
|
||||||
|
-moz-box-shadow:0 3px 3px -3px rgba(0, 0, 0, 0.25) inset, 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
-moz-box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.25) inset, 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.google {
|
||||||
|
background-image: url("/0.3.4/i/sprite.png");
|
||||||
|
background-position: 5px -159px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
padding: 0 0 0 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
require(["require", "jquery", "blade/url", "services", "jquery.cookie"],
|
||||||
|
function (require, $, url, services) {
|
||||||
|
var target = window.location.href.split('#')[1];
|
||||||
|
if (target && (target === 'oauth_success' || target === 'oauth_failure')) {
|
||||||
|
|
||||||
|
//TODO: ideally lock down the domain be location.hostname, but
|
||||||
|
//a problem for 127 addresses?
|
||||||
|
// XXX hacky way to handle fennec, since we didn't open a window,
|
||||||
|
// catch the exception when using window.opener and redirect
|
||||||
|
var data = {
|
||||||
|
target: target,
|
||||||
|
account: JSON.parse($.cookie("account_tokens"))
|
||||||
|
};
|
||||||
|
window.opener.postMessage(JSON.stringify(data), '*');
|
||||||
|
// clear the cookie, we no longer want it around
|
||||||
|
$.cookie("account_tokens", "", {"path": "/"});
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
var search = window.location.href.split('?')[1];
|
||||||
|
if (search) {
|
||||||
|
search = search.split('#')[0];
|
||||||
|
|
||||||
|
var args = url.queryToObject(search),
|
||||||
|
domain = args.domain;
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
if (domain) {
|
||||||
|
// add a force login param to the form if asked.
|
||||||
|
if (args.forceLogin) {
|
||||||
|
var forceLogin = services.domains[domain].forceLogin;
|
||||||
|
if (forceLogin) {
|
||||||
|
$('<input type="hidden" name="' +
|
||||||
|
forceLogin.name +
|
||||||
|
'" value="' + forceLogin.value + '">').appendTo('[name="authForm"]');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#domain").attr("value", args['domain']);
|
||||||
|
|
||||||
|
if (args['domain'] == 'googleapps.com') {
|
||||||
|
// show UI for googleapp
|
||||||
|
$('#oauth').removeClass('hidden');
|
||||||
|
$('#message').addClass('hidden');
|
||||||
|
$('#submitbtn').click(function (evt) {
|
||||||
|
$('#oauth').addClass('hidden');
|
||||||
|
$('#message').removeClass('hidden');
|
||||||
|
document.authForm.submit();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
document.authForm.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body class="settings">
|
||||||
|
|
||||||
|
<div id="oauth" class="authorize hidden">
|
||||||
|
<form name="authForm" action="/api/account/authorize" method="POST">
|
||||||
|
<input type="hidden" name="domain" id="domain" value="">
|
||||||
|
<span class="text">Enter your Google Apps domain</span>
|
||||||
|
<div class="controls hbox">
|
||||||
|
<input class="boxFlex google" name="openid_identifier" id="openid_identifier" value="">
|
||||||
|
<input class="boxFlex google" type="hidden" name="end_point_success" value="/0.3.4/auth.html#oauth_success">
|
||||||
|
<input class="boxFlex google" type="hidden" name="end_point_auth_failure" value="/0.3.4/auth.html#oauth_failure">
|
||||||
|
<button id='submitbtn' type="submit">submit</button>
|
||||||
|
</div>
|
||||||
|
<span class="subtext">ex: yourappdomain.com</span>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div style="clear: both"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id='message' class="connecting"><img src="i/loader-w.gif"> connecting...</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
({
|
||||||
|
baseUrl: "scripts/",
|
||||||
|
paths: {
|
||||||
|
"index": "../index",
|
||||||
|
"jquery": "requireplugins-jquery"
|
||||||
|
},
|
||||||
|
name: "index",
|
||||||
|
exclude: ['jquery'],
|
||||||
|
out: './index.js'
|
||||||
|
})
|
После Ширина: | Высота: | Размер: 1.1 KiB |
После Ширина: | Высота: | Размер: 469 B |
После Ширина: | Высота: | Размер: 716 B |
После Ширина: | Высота: | Размер: 494 B |
После Ширина: | Высота: | Размер: 142 B |
После Ширина: | Высота: | Размер: 139 B |
После Ширина: | Высота: | Размер: 136 B |
После Ширина: | Высота: | Размер: 139 B |
После Ширина: | Высота: | Размер: 389 B |
После Ширина: | Высота: | Размер: 4.7 KiB |
После Ширина: | Высота: | Размер: 4.4 KiB |
После Ширина: | Высота: | Размер: 448 B |
После Ширина: | Высота: | Размер: 43 B |
После Ширина: | Высота: | Размер: 1.5 KiB |
После Ширина: | Высота: | Размер: 10 KiB |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 1.4 KiB |
После Ширина: | Высота: | Размер: 107 B |
После Ширина: | Высота: | Размер: 106 B |
После Ширина: | Высота: | Размер: 347 B |
После Ширина: | Высота: | Размер: 324 B |
После Ширина: | Высота: | Размер: 111 B |
После Ширина: | Высота: | Размер: 352 B |
После Ширина: | Высота: | Размер: 340 B |
После Ширина: | Высота: | Размер: 103 B |
После Ширина: | Высота: | Размер: 503 B |
После Ширина: | Высота: | Размер: 96 B |
После Ширина: | Высота: | Размер: 70 B |
После Ширина: | Высота: | Размер: 506 B |
После Ширина: | Высота: | Размер: 203 B |
После Ширина: | Высота: | Размер: 176 B |
После Ширина: | Высота: | Размер: 15 KiB |
После Ширина: | Высота: | Размер: 468 B |
После Ширина: | Высота: | Размер: 2.7 KiB |
После Ширина: | Высота: | Размер: 67 KiB |
После Ширина: | Высота: | Размер: 62 KiB |
После Ширина: | Высота: | Размер: 3.4 KiB |
После Ширина: | Высота: | Размер: 27 KiB |
После Ширина: | Высота: | Размер: 23 KiB |
После Ширина: | Высота: | Размер: 5.2 KiB |
После Ширина: | Высота: | Размер: 27 KiB |
После Ширина: | Высота: | Размер: 1.2 KiB |
После Ширина: | Высота: | Размер: 4.1 KiB |
После Ширина: | Высота: | Размер: 4.1 KiB |
После Ширина: | Высота: | Размер: 4.2 KiB |
После Ширина: | Высота: | Размер: 3.4 KiB |
После Ширина: | Высота: | Размер: 390 B |
После Ширина: | Высота: | Размер: 494 B |
|
@ -0,0 +1,172 @@
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:og="http://opengraphprotocol.org/schema/"
|
||||||
|
xmlns:fb="http://www.facebook.com/2008/fbml">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/0.3.4/style.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/0.3.4/jquery.fancybox-1.3.4.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="resource://ffshare/chrome/skin/web/installed.css">
|
||||||
|
|
||||||
|
<title>Mozilla F1</title>
|
||||||
|
<script type="text/javascript" data-main="/0.3.4/index.js" src="/0.3.4/scripts/requireplugins-jquery.js"></script>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/0.3.4/favicon.png" />
|
||||||
|
|
||||||
|
<!-- https://github.com/mozilla/f1/wiki/Page-Meta-Properties -->
|
||||||
|
|
||||||
|
<link rel="shortlink" href="http://bit.ly/mozillaF1"/>
|
||||||
|
<link rel="canonical" href="http://f1.mozillamessaging.com/"/>
|
||||||
|
|
||||||
|
<meta property="og:title" content="Mozilla F1"/>
|
||||||
|
<meta property="og:type" content="website"/>
|
||||||
|
<meta property="og:url" content="http://f1.mozillamessaging.com/"/>
|
||||||
|
<meta property="og:image" content="http://f1.mozillamessaging.com/i/f1LogoVert.png"/>
|
||||||
|
<meta property="og:site_name" content="Mozilla F1"/>
|
||||||
|
<meta property="og:description"
|
||||||
|
content="F1 is a browser extension that allows you to share links in a
|
||||||
|
fast and fun way. Share links from within the browser, from any
|
||||||
|
webpage, using the same services you already know and love."/>
|
||||||
|
|
||||||
|
<meta property="fb:app_id" content="173375079345318,146290642084944"/>
|
||||||
|
|
||||||
|
<meta name="title" content="Mozilla F1"/>
|
||||||
|
<meta name="description"
|
||||||
|
content="F1 is a browser extension that allows you to share links in a
|
||||||
|
fast and fun way. Share links from within the browser, from any
|
||||||
|
webpage, using the same services you already know and love."/>
|
||||||
|
|
||||||
|
<meta name="application-url" content="http://f1.mozillamessaging.com/"/>
|
||||||
|
|
||||||
|
<link rel="image_src" href="http://f1.mozillamessaging.com/i/f1LogoVert.png"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<div id="header" class="row">
|
||||||
|
<div class="c2 logo">
|
||||||
|
/ <a href="http://mozillalabs.com/messaging/">F1 Blog »</a>
|
||||||
|
</div>
|
||||||
|
<div class="c1 dl">
|
||||||
|
<button id="downloadFF4" class="download downloadXpi">
|
||||||
|
Install Mozilla F1
|
||||||
|
<span class="meta">available for Firefox 4 beta</span>
|
||||||
|
</button>
|
||||||
|
<button id="firefox" class="download">
|
||||||
|
Get Firefox 4 beta to use <br>this add-on
|
||||||
|
</button>
|
||||||
|
<a id="no36" href="#info36">*Firefox 3.6 is no longer supported</a>
|
||||||
|
<div id="noButtonFF4">
|
||||||
|
<img src="/0.3.4/i/check.png"> status: installed
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row headline">
|
||||||
|
<div class="c1 description">
|
||||||
|
<h1>Share links fast.</h1>
|
||||||
|
<h2>So, what’s F1?</h2>
|
||||||
|
F1 is a browser extension that allows you to share links in a fast and fun way. Share links from within the browser, from any webpage, using the same services you already know and love. Mozilla F1 is made by Mozilla Messaging.
|
||||||
|
<button class="fancybox">watch demo</button>
|
||||||
|
</div>
|
||||||
|
<div class="c2">
|
||||||
|
<img src="/i/panel/f1panel.png">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<hr>
|
||||||
|
<div class="c2 description">
|
||||||
|
<img src="/i/panel/f1accounts.png">
|
||||||
|
</div>
|
||||||
|
<div class="c1 description">
|
||||||
|
<h2>Share with your<br> favorite services</h2>
|
||||||
|
With support for Facebook, Twitter, Gmail, Google Apps, Yahoo Mail and LinkedIn, we have your favorite services covered—and we're adding more services with every release.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row about">
|
||||||
|
<hr>
|
||||||
|
<div class="c3 description">
|
||||||
|
<h2>Once you've installed F1 sharing is as easy as...</h2>
|
||||||
|
</div>
|
||||||
|
<div class="c1 description steps">
|
||||||
|
<span class="step">1</span> Hit the F1 icon in the URL bar
|
||||||
|
<img src="i/panel/step-01.png">
|
||||||
|
</div>
|
||||||
|
<div class="c1 description steps">
|
||||||
|
<span class="step">2</span> Choose your service in the menu
|
||||||
|
<img src="i/panel/step-022.png">
|
||||||
|
</div>
|
||||||
|
<div class="c1 description steps">
|
||||||
|
<span class="step">3</span> Express yourself and hit share!
|
||||||
|
<img src="i/panel/step-03.png">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="info36" class="row">
|
||||||
|
<div class="c3">
|
||||||
|
<strong>*Firefox 3.6 support</strong>: F1 uses some advanced technology
|
||||||
|
and UI capabilities that are not possible in Firefox 3.6 and earlier.
|
||||||
|
If you installed the previous version of F1 that works with Firefox 3.6,
|
||||||
|
it will continue to work while Firefox 4 is in beta. Once Firefox 4 is
|
||||||
|
released, the older 3.6 compatible extension will be phased out.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="footer" class="row">
|
||||||
|
<div class="c3">
|
||||||
|
<a href="http://mozillamessaging.com">Mozilla Messaging 2011</a> | <a href="/0.3.4/service/privacy.html">Privacy Policy</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<iframe id="installFrame" src="/0.3.4/blank.html"></iframe>
|
||||||
|
|
||||||
|
<!-- START OF SmartSource Data Collector TAG -->
|
||||||
|
<!-- Copyright (c) 1996-2011 WebTrends Inc. All rights reserved. -->
|
||||||
|
<!-- Version: 9.3.0 -->
|
||||||
|
<!-- Tag Builder Version: 3.1 -->
|
||||||
|
<!-- Created: 3/15/2011 5:10:56 PM -->
|
||||||
|
<script src="/0.3.4/scripts/webtrends.js" type="text/javascript"></script>
|
||||||
|
<!-- ----------------------------------------------------------------------------------- -->
|
||||||
|
<!-- Warning: The two script blocks below must remain inline. Moving them to an external -->
|
||||||
|
<!-- JavaScript include file can cause serious problems with cross-domain tracking. -->
|
||||||
|
<!-- ----------------------------------------------------------------------------------- -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
var _tag=new WebTrends();
|
||||||
|
_tag.dcsGetId();
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
_tag.dcsCustom=function(){
|
||||||
|
// Add custom parameters here.
|
||||||
|
//_tag.DCSext.param_name=param_value;
|
||||||
|
}
|
||||||
|
_tag.dcsCollect();
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
<noscript>
|
||||||
|
<div><img alt="DCSIMG" id="DCSIMG" width="1" height="1" src="http://statse.webtrendslive.com/dcsjd66bq10000k73ngwoin8k_7d1l/njs.gif?dcsuri=/nojavascript&WT.js=No&WT.tv=9.3.0&WT.dcssip=www.mozillamessaging.com"/></div>
|
||||||
|
</noscript>
|
||||||
|
<!-- END OF SmartSource Data Collector TAG -->
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,32 @@
|
||||||
|
define("hashDispatch",[],function(){return function(b){function g(){var i=location.href.split("#")[1]||"_default",l,f;f=i.indexOf(":");if(f!==-1){l=i.substring(f+1,i.length);i=i.substring(0,f)}if(i in b)b[i](l);else b._catchAll&&b._catchAll(i,l)}g();window.addEventListener("hashchange",g,false)}});
|
||||||
|
(function(b){var g,i,l,f,x,m,D,o,A,B,r=0,e={},p=[],q=0,d={},n=[],F=null,u=new Image,J=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,W=/[^\.]\.(swf)\s*$/i,K,L=1,z=0,v="",s,k,j=false,C=b.extend(b("<div/>")[0],{prop:0}),M=b.browser.msie&&b.browser.version<7&&!window.XMLHttpRequest,N=function(){i.hide();u.onerror=u.onload=null;F&&F.abort();g.empty()},O=function(){if(false===e.onError(p,r,e)){i.hide();j=false}else{e.titleShow=false;e.width="auto";e.height="auto";g.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');
|
||||||
|
E()}},I=function(){var a=p[r],c,h,t,G,P,w;N();e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));w=e.onStart(p,r,e);if(w===false)j=false;else{if(typeof w=="object")e=b.extend(e,w);t=e.title||(a.nodeName?b(a).attr("title"):a.title)||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?b(a).children("img:first"):b(a);if(t===""&&e.orig&&e.titleFromAlt)t=e.orig.attr("alt");c=e.href||(a.nodeName?b(a).attr("href"):a.href)||null;if(/^(?:javascript)/i.test(c)||
|
||||||
|
c=="#")c=null;if(e.type){h=e.type;if(!c)c=e.content}else if(e.content)h="html";else if(c)h=c.match(J)?"image":c.match(W)?"swf":b(a).hasClass("iframe")?"iframe":c.indexOf("#")===0?"inline":"ajax";if(h){if(h=="inline"){a=c.substr(c.indexOf("#"));h=b(a).length>0?"inline":"ajax"}e.type=h;e.href=c;e.title=t;if(e.autoDimensions)if(e.type=="html"||e.type=="inline"||e.type=="ajax"){e.width="auto";e.height="auto"}else e.autoDimensions=false;if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=
|
||||||
|
false;e.enableEscapeButton=false;e.showCloseButton=false}e.padding=parseInt(e.padding,10);e.margin=parseInt(e.margin,10);g.css("padding",e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(m.children())});switch(h){case "html":g.html(e.content);E();break;case "inline":if(b(a).parent().is("#fancybox-content")===true){j=false;return}b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",function(){b(this).replaceWith(m.children())}).bind("fancybox-cancel",
|
||||||
|
function(){b(this).replaceWith(g.children())});b(a).appendTo(g);E();break;case "image":j=false;b.fancybox.showActivity();u=new Image;u.onerror=function(){O()};u.onload=function(){j=true;u.onerror=u.onload=null;X()};u.src=c;break;case "swf":e.scrolling="no";G='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+c+'"></param>';P="";b.each(e.swf,function(y,H){G+='<param name="'+y+'" value="'+H+'"></param>';P+=" "+y+'="'+
|
||||||
|
H+'"'});G+='<embed src="'+c+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+P+"></embed></object>";g.html(G);E();break;case "ajax":j=false;b.fancybox.showActivity();e.ajax.win=e.ajax.success;F=b.ajax(b.extend({},e.ajax,{url:c,data:e.ajax.data||{},error:function(y){y.status>0&&O()},success:function(y,H,Q){if((typeof Q=="object"?Q:F).status==200){if(typeof e.ajax.win=="function"){w=e.ajax.win(c,y,H,Q);if(w===false){i.hide();return}else if(typeof w=="string"||typeof w==
|
||||||
|
"object")y=w}g.html(y);E()}}}));break;case "iframe":R();break}}else O()}},E=function(){var a=e.width,c=e.height;a=a.toString().indexOf("%")>-1?parseInt((b(window).width()-e.margin*2)*parseFloat(a)/100,10)+"px":a=="auto"?"auto":a+"px";c=c.toString().indexOf("%")>-1?parseInt((b(window).height()-e.margin*2)*parseFloat(c)/100,10)+"px":c=="auto"?"auto":c+"px";g.wrapInner('<div style="width:'+a+";height:"+c+";overflow: "+(e.scrolling=="auto"?"auto":e.scrolling=="yes"?"scroll":"hidden")+';position:relative;"></div>');
|
||||||
|
e.width=g.width();e.height=g.height();R()},X=function(){e.width=u.width;e.height=u.height;b("<img />").attr({id:"fancybox-img",src:u.src,alt:e.title}).appendTo(g);R()},R=function(){var a,c;i.hide();if(f.is(":visible")&&false===d.onCleanup(n,q,d)){b.event.trigger("fancybox-cancel");j=false}else{j=true;b(m.add(l)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");f.is(":visible")&&d.titlePosition!=="outside"&&f.css("height",f.height());n=p;q=r;d=e;if(d.overlayShow){l.css({"background-color":d.overlayColor,
|
||||||
|
opacity:d.overlayOpacity,cursor:d.hideOnOverlayClick?"pointer":"auto",height:b(document).height()});if(!l.is(":visible")){M&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});l.show()}}else l.hide();k=Y();Z();if(f.is(":visible")){b(D.add(A).add(B)).hide();a=f.position();s={top:a.top,left:a.left,width:f.width(),height:f.height()};c=s.width==k.width&&s.height==
|
||||||
|
k.height;m.fadeTo(d.changeFade,0.3,function(){var h=function(){m.html(g.contents()).fadeTo(d.changeFade,1,S)};b.event.trigger("fancybox-change");m.empty().removeAttr("filter").css({"border-width":d.padding,width:k.width-d.padding*2,height:e.autoDimensions?"auto":k.height-z-d.padding*2});if(c)h();else{C.prop=0;b(C).animate({prop:1},{duration:d.changeSpeed,easing:d.easingChange,step:T,complete:h})}})}else{f.removeAttr("style");m.css("border-width",d.padding);if(d.transitionIn=="elastic"){s=V();m.html(g.contents());
|
||||||
|
f.show();if(d.opacity)k.opacity=0;C.prop=0;b(C).animate({prop:1},{duration:d.speedIn,easing:d.easingIn,step:T,complete:S})}else{d.titlePosition=="inside"&&z>0&&o.show();m.css({width:k.width-d.padding*2,height:e.autoDimensions?"auto":k.height-z-d.padding*2}).html(g.contents());f.css(k).fadeIn(d.transitionIn=="none"?0:d.speedIn,S)}}}},$=function(a){if(a&&a.length){if(d.titlePosition=="float")return'<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">'+
|
||||||
|
a+'</td><td id="fancybox-title-float-right"></td></tr></table>';return'<div id="fancybox-title-'+d.titlePosition+'">'+a+"</div>"}return false},Z=function(){v=d.title||"";z=0;o.empty().removeAttr("style").removeClass();if(d.titleShow!==false){v=b.isFunction(d.titleFormat)?d.titleFormat(v,n,q,d):$(v);if(!(!v||v==="")){o.addClass("fancybox-title-"+d.titlePosition).html(v).appendTo("body").show();switch(d.titlePosition){case "inside":o.css({width:k.width-d.padding*2,marginLeft:d.padding,marginRight:d.padding});
|
||||||
|
z=o.outerHeight(true);o.appendTo(x);k.height+=z;break;case "over":o.css({marginLeft:d.padding,width:k.width-d.padding*2,bottom:d.padding}).appendTo(x);break;case "float":o.css("left",parseInt((o.width()-k.width-40)/2,10)*-1).appendTo(f);break;default:o.css({width:k.width-d.padding*2,paddingLeft:d.padding,paddingRight:d.padding}).appendTo(f);break}}}o.hide()},aa=function(){if(d.enableEscapeButton||d.enableKeyboardNav)b(document).bind("keydown.fb",function(a){if(a.keyCode==27&&d.enableEscapeButton){a.preventDefault();
|
||||||
|
b.fancybox.close()}else if((a.keyCode==37||a.keyCode==39)&&d.enableKeyboardNav&&a.target.tagName!=="INPUT"&&a.target.tagName!=="TEXTAREA"&&a.target.tagName!=="SELECT"){a.preventDefault();b.fancybox[a.keyCode==37?"prev":"next"]()}});if(d.showNavArrows){if(d.cyclic&&n.length>1||q!==0)A.show();if(d.cyclic&&n.length>1||q!=n.length-1)B.show()}else{A.hide();B.hide()}},S=function(){if(!b.support.opacity){m.get(0).style.removeAttribute("filter");f.get(0).style.removeAttribute("filter")}e.autoDimensions&&
|
||||||
|
m.css("height","auto");f.css("height","auto");v&&v.length&&o.show();d.showCloseButton&&D.show();aa();d.hideOnContentClick&&m.bind("click",b.fancybox.close);d.hideOnOverlayClick&&l.bind("click",b.fancybox.close);b(window).bind("resize.fb",b.fancybox.resize);d.centerOnScroll&&b(window).bind("scroll.fb",b.fancybox.center);if(d.type=="iframe")b('<iframe id="fancybox-frame" name="fancybox-frame'+(new Date).getTime()+'" frameborder="0" hspace="0" '+(b.browser.msie?'allowtransparency="true""':"")+' scrolling="'+
|
||||||
|
e.scrolling+'" src="'+d.href+'"></iframe>').appendTo(m);f.show();j=false;b.fancybox.center();d.onComplete(n,q,d);ba()},ba=function(){var a,c;if(n.length-1>q){a=n[q+1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}if(q>0){a=n[q-1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}},T=function(a){var c={width:parseInt(s.width+(k.width-s.width)*a,10),height:parseInt(s.height+(k.height-s.height)*a,10),top:parseInt(s.top+(k.top-s.top)*a,10),left:parseInt(s.left+(k.left-
|
||||||
|
s.left)*a,10)};if(typeof k.opacity!=="undefined")c.opacity=a<0.5?0.5:a;f.css(c);m.css({width:c.width-d.padding*2,height:c.height-z*a-d.padding*2})},U=function(){return[b(window).width()-d.margin*2,b(window).height()-d.margin*2,b(document).scrollLeft()+d.margin,b(document).scrollTop()+d.margin]},Y=function(){var a=U(),c={},h=d.autoScale,t=d.padding*2;c.width=d.width.toString().indexOf("%")>-1?parseInt(a[0]*parseFloat(d.width)/100,10):d.width+t;c.height=d.height.toString().indexOf("%")>-1?parseInt(a[1]*
|
||||||
|
parseFloat(d.height)/100,10):d.height+t;if(h&&(c.width>a[0]||c.height>a[1]))if(e.type=="image"||e.type=="swf"){h=d.width/d.height;if(c.width>a[0]){c.width=a[0];c.height=parseInt((c.width-t)/h+t,10)}if(c.height>a[1]){c.height=a[1];c.width=parseInt((c.height-t)*h+t,10)}}else{c.width=Math.min(c.width,a[0]);c.height=Math.min(c.height,a[1])}c.top=parseInt(Math.max(a[3]-20,a[3]+(a[1]-c.height-40)*0.5),10);c.left=parseInt(Math.max(a[2]-20,a[2]+(a[0]-c.width-40)*0.5),10);return c},ca=function(a){var c=a.offset();
|
||||||
|
c.top+=parseInt(a.css("paddingTop"),10)||0;c.left+=parseInt(a.css("paddingLeft"),10)||0;c.top+=parseInt(a.css("border-top-width"),10)||0;c.left+=parseInt(a.css("border-left-width"),10)||0;c.width=a.width();c.height=a.height();return c},V=function(){var a=e.orig?b(e.orig):false,c={};if(a&&a.length){a=ca(a);c={width:a.width+d.padding*2,height:a.height+d.padding*2,top:a.top-d.padding-20,left:a.left-d.padding-20}}else{a=U();c={width:d.padding*2,height:d.padding*2,top:parseInt(a[3]+a[1]*0.5,10),left:parseInt(a[2]+
|
||||||
|
a[0]*0.5,10)}}return c},da=function(){if(i.is(":visible")){b("div",i).css("top",L*-40+"px");L=(L+1)%12}else clearInterval(K)};b.fn.fancybox=function(a){if(!b(this).length)return this;b(this).data("fancybox",b.extend({},a,b.metadata?b(this).metadata():{})).unbind("click.fb").bind("click.fb",function(c){c.preventDefault();if(!j){j=true;b(this).blur();p=[];r=0;c=b(this).attr("rel")||"";if(!c||c==""||c==="nofollow")p.push(this);else{p=b("a[rel="+c+"], area[rel="+c+"]");r=p.index(this)}I()}});return this};
|
||||||
|
b.fancybox=function(a,c){if(!j){j=true;c=typeof c!=="undefined"?c:{};p=[];r=parseInt(c.index,10)||0;if(b.isArray(a)){for(var h=0,t=a.length;h<t;h++)if(typeof a[h]=="object")b(a[h]).data("fancybox",b.extend({},c,a[h]));else a[h]=b({}).data("fancybox",b.extend({content:a[h]},c));p=jQuery.merge(p,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},c,a));else a=b({}).data("fancybox",b.extend({content:a},c));p.push(a)}if(r>p.length||r<0)r=0;I()}};b.fancybox.showActivity=function(){clearInterval(K);
|
||||||
|
i.show();K=setInterval(da,66)};b.fancybox.hideActivity=function(){i.hide()};b.fancybox.next=function(){return b.fancybox.pos(q+1)};b.fancybox.prev=function(){return b.fancybox.pos(q-1)};b.fancybox.pos=function(a){if(!j){a=parseInt(a);p=n;if(a>-1&&a<n.length){r=a;I()}else if(d.cyclic&&n.length>1){r=a>=n.length?0:n.length-1;I()}}};b.fancybox.cancel=function(){if(!j){j=true;b.event.trigger("fancybox-cancel");N();e.onCancel(p,r,e);j=false}};b.fancybox.close=function(){function a(){l.fadeOut("fast");o.empty().hide();
|
||||||
|
f.hide();b.event.trigger("fancybox-cleanup");m.empty();d.onClosed(n,q,d);n=e=[];q=r=0;d=e={};j=false}if(!(j||f.is(":hidden"))){j=true;if(d&&false===d.onCleanup(n,q,d))j=false;else{N();b(D.add(A).add(B)).hide();b(m.add(l)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");m.find("iframe").attr("src",M&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");d.titlePosition!=="inside"&&o.empty();f.stop();if(d.transitionOut=="elastic"){s=V();var c=
|
||||||
|
f.position();k={top:c.top,left:c.left,width:f.width(),height:f.height()};if(d.opacity)k.opacity=1;o.empty().hide();C.prop=1;b(C).animate({prop:0},{duration:d.speedOut,easing:d.easingOut,step:T,complete:a})}else f.fadeOut(d.transitionOut=="none"?0:d.speedOut,a)}}};b.fancybox.resize=function(){l.is(":visible")&&l.css("height",b(document).height());b.fancybox.center(true)};b.fancybox.center=function(a){var c,h;if(!j){h=a===true?1:0;c=U();!h&&(f.width()>c[0]||f.height()>c[1])||f.stop().animate({top:parseInt(Math.max(c[3]-
|
||||||
|
20,c[3]+(c[1]-m.height()-40)*0.5-d.padding)),left:parseInt(Math.max(c[2]-20,c[2]+(c[0]-m.width()-40)*0.5-d.padding))},typeof a=="number"?a:200)}};b.fancybox.init=function(){if(!b("#fancybox-wrap").length){b("body").append(g=b('<div id="fancybox-tmp"></div>'),i=b('<div id="fancybox-loading"><div></div></div>'),l=b('<div id="fancybox-overlay"></div>'),f=b('<div id="fancybox-wrap"></div>'));x=b('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(f);
|
||||||
|
x.append(m=b('<div id="fancybox-content"></div>'),D=b('<a id="fancybox-close"></a>'),o=b('<div id="fancybox-title"></div>'),A=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),B=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));D.click(b.fancybox.close);i.click(b.fancybox.cancel);A.click(function(a){a.preventDefault();b.fancybox.prev()});B.click(function(a){a.preventDefault();b.fancybox.next()});
|
||||||
|
b.fn.mousewheel&&f.bind("mousewheel.fb",function(a,c){if(j)a.preventDefault();else if(b(a.target).get(0).clientHeight==0||b(a.target).get(0).scrollHeight===b(a.target).get(0).clientHeight){a.preventDefault();b.fancybox[c>0?"prev":"next"]()}});b.support.opacity||f.addClass("fancybox-ie");if(M){i.addClass("fancybox-ie6");f.addClass("fancybox-ie6");b('<iframe id="fancybox-hide-sel-frame" src="'+(/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank")+'" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(x)}}};
|
||||||
|
b.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",
|
||||||
|
easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};b(document).ready(function(){b.fancybox.init()})})(jQuery);define("jquery.fancybox-1.3.4",function(){});
|
||||||
|
define("index",["require","jquery","hashDispatch","jquery.fancybox-1.3.4"],function(b,g){g(function(){var i=!!navigator.buildID,l=i&&navigator.userAgent.match(/Firefox\/([^\s]+)/);if(i&&l){l=parseFloat(l[1]);i=l>3.99}if(!i){g("#downloadFF4").hide();g("#no36").show();g("#info36").show();g("#firefox").show()}g(".fancybox").fancybox({type:"iframe",href:"http://player.vimeo.com/video/21374067?title=0&byline=0&portrait=0&autoplay=true",width:700,height:468,autoScale:false,autoDimensions:false});
|
||||||
|
g("body").delegate("#firefox","click",function(){location="http://www.mozilla.com/en-US/firefox/beta/"}).delegate(".downloadXpi","click",function(f){var x=location.href;location=x.indexOf("staging")!==-1||x.indexOf("linkdrop")!==-1?"/ffshare.xpi":"https://addons.mozilla.org/services/install.php?addon_id=252539&addon_name=F1%20by%20Mozilla%20Labs&src=external-f1home";f.preventDefault()})})});
|
|
@ -0,0 +1,359 @@
|
||||||
|
/*
|
||||||
|
* FancyBox - jQuery Plugin
|
||||||
|
* Simple and fancy lightbox alternative
|
||||||
|
*
|
||||||
|
* Examples and documentation at: http://fancybox.net
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 - 2010 Janis Skarnelis
|
||||||
|
* That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
|
||||||
|
*
|
||||||
|
* Version: 1.3.4 (11/11/2010)
|
||||||
|
* Requires: jQuery v1.3+
|
||||||
|
*
|
||||||
|
* Dual licensed under the MIT and GPL licenses:
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#fancybox-loading {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: -20px;
|
||||||
|
margin-left: -20px;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 1104;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-loading div {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 40px;
|
||||||
|
height: 480px;
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-overlay {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1100;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-tmp {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
overflow: auto;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20px 10px 10px 20px;
|
||||||
|
z-index: 1101;
|
||||||
|
outline: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-outer {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-content {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
padding: 0;
|
||||||
|
outline: none;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 1102;
|
||||||
|
border: 0px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-hide-sel-frame {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: transparent;
|
||||||
|
z-index: 1101;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-close {
|
||||||
|
position: absolute;
|
||||||
|
top: -15px;
|
||||||
|
right: -25px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
background: transparent url('i/fancybox/fancybox.png') -40px 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 1103;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-error {
|
||||||
|
color: #444;
|
||||||
|
font: normal 12px/20px Arial;
|
||||||
|
padding: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
line-height: 0;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-frame {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left, #fancybox-right {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
height: 100%;
|
||||||
|
width: 35%;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
background: transparent url('i/fancybox/blank.gif');
|
||||||
|
z-index: 1102;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left {
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-right {
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left-ico, #fancybox-right-ico {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: -9999px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
margin-top: -15px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 1102;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left-ico {
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-right-ico {
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left:hover, #fancybox-right:hover {
|
||||||
|
visibility: visible; /* IE6 */
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-left:hover span {
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-right:hover span {
|
||||||
|
left: auto;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybox-bg {
|
||||||
|
position: absolute;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-n {
|
||||||
|
top: -20px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-image: url('i/fancybox/fancybox-x.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-ne {
|
||||||
|
top: -20px;
|
||||||
|
right: -20px;
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -162px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-e {
|
||||||
|
top: 0;
|
||||||
|
right: -20px;
|
||||||
|
height: 100%;
|
||||||
|
background-image: url('i/fancybox/fancybox-y.png');
|
||||||
|
background-position: -20px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-se {
|
||||||
|
bottom: -20px;
|
||||||
|
right: -20px;
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -182px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-s {
|
||||||
|
bottom: -20px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-image: url('i/fancybox/fancybox-x.png');
|
||||||
|
background-position: 0px -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-sw {
|
||||||
|
bottom: -20px;
|
||||||
|
left: -20px;
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -142px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-w {
|
||||||
|
top: 0;
|
||||||
|
left: -20px;
|
||||||
|
height: 100%;
|
||||||
|
background-image: url('i/fancybox/fancybox-y.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-bg-nw {
|
||||||
|
top: -20px;
|
||||||
|
left: -20px;
|
||||||
|
background-image: url('i/fancybox/fancybox.png');
|
||||||
|
background-position: -40px -122px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title {
|
||||||
|
font-family: Helvetica;
|
||||||
|
font-size: 12px;
|
||||||
|
z-index: 1102;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybox-title-inside {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
background: #fff;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybox-title-outside {
|
||||||
|
padding-top: 10px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybox-title-over {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
color: #FFF;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-over {
|
||||||
|
padding: 10px;
|
||||||
|
background-image: url('i/fancybox/fancy_title_over.png');
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fancybox-title-float {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: -20px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-float-wrap {
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-float-wrap td {
|
||||||
|
border: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-float-left {
|
||||||
|
padding: 0 0 0 15px;
|
||||||
|
background: url('i/fancybox/fancybox.png') -40px -90px no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-float-main {
|
||||||
|
color: #FFF;
|
||||||
|
line-height: 29px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 0 0 3px 0;
|
||||||
|
background: url('i/fancybox/fancybox-x.png') 0px -40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-title-float-right {
|
||||||
|
padding: 0 0 0 15px;
|
||||||
|
background: url('i/fancybox/fancybox.png') -55px -90px no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IE6 */
|
||||||
|
|
||||||
|
.fancybox-ie6 #fancybox-close { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_close.png', sizingMethod='scale'); }
|
||||||
|
|
||||||
|
.fancybox-ie6 #fancybox-left-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_nav_left.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie6 #fancybox-right-ico { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_nav_right.png', sizingMethod='scale'); }
|
||||||
|
|
||||||
|
.fancybox-ie6 #fancybox-title-over { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_title_over.png', sizingMethod='scale'); zoom: 1; }
|
||||||
|
.fancybox-ie6 #fancybox-title-float-left { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_title_left.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie6 #fancybox-title-float-main { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_title_main.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie6 #fancybox-title-float-right { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_title_right.png', sizingMethod='scale'); }
|
||||||
|
|
||||||
|
.fancybox-ie6 #fancybox-bg-w, .fancybox-ie6 #fancybox-bg-e, .fancybox-ie6 #fancybox-left, .fancybox-ie6 #fancybox-right, #fancybox-hide-sel-frame {
|
||||||
|
height: expression(this.parentNode.clientHeight + "px");
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-loading.fancybox-ie6 {
|
||||||
|
position: absolute; margin-top: 0;
|
||||||
|
top: expression( (-20 + (document.documentElement.clientHeight ? document.documentElement.clientHeight/2 : document.body.clientHeight/2 ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop )) + 'px');
|
||||||
|
}
|
||||||
|
|
||||||
|
#fancybox-loading.fancybox-ie6 div { background: transparent; filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_loading.png', sizingMethod='scale'); }
|
||||||
|
|
||||||
|
/* IE6, IE7, IE8 */
|
||||||
|
|
||||||
|
.fancybox-ie .fancybox-bg { background: transparent !important; }
|
||||||
|
|
||||||
|
.fancybox-ie #fancybox-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_n.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_ne.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_e.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_se.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_s.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_sw.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_w.png', sizingMethod='scale'); }
|
||||||
|
.fancybox-ie #fancybox-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='i/fancybox/fancy_shadow_nw.png', sizingMethod='scale'); }
|
|
@ -0,0 +1,57 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Autocomplete test</title>
|
||||||
|
<script src="../scripts/requireplugins-jquery.js"></script>
|
||||||
|
<script src="../scripts/jquery-ui-1.8.7.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var options = {
|
||||||
|
a: [
|
||||||
|
'alpha',
|
||||||
|
'amature'
|
||||||
|
],
|
||||||
|
b: [
|
||||||
|
'bass',
|
||||||
|
'bicycle'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options2 = [
|
||||||
|
'alpha',
|
||||||
|
'amature',
|
||||||
|
'bass',
|
||||||
|
'bicycle'
|
||||||
|
];
|
||||||
|
|
||||||
|
//HTML5-style autocomplete, does not do want is desired though.
|
||||||
|
$(function () {
|
||||||
|
var ac = $('.ac')[0],
|
||||||
|
dynamic = $('#dynamic')[0];
|
||||||
|
|
||||||
|
$('body').delegate('.ac', 'input', function (evt) {
|
||||||
|
var value = ac.value,
|
||||||
|
args = value.split(','),
|
||||||
|
others = args.slice(0, args.length - 1).join(',') || '',
|
||||||
|
last = args[args.length - 1],
|
||||||
|
list = options[last.charAt(0)],
|
||||||
|
html = '';
|
||||||
|
|
||||||
|
if (list) {
|
||||||
|
list.forEach(function (item) {
|
||||||
|
html += '<option value="' + (others ? others + ',' : '') + item + '">' + (others ? others + ',' : '') + item + '</option>';
|
||||||
|
})
|
||||||
|
dynamic.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("INPUT: ", evt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form>
|
||||||
|
<input class="ac" list="dynamic" name="dynamicAc">
|
||||||
|
<datalist id="dynamic">
|
||||||
|
</datalist>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
После Ширина: | Высота: | Размер: 17 KiB |
После Ширина: | Высота: | Размер: 607 B |
После Ширина: | Высота: | Размер: 302 B |
После Ширина: | Высота: | Размер: 235 B |
|
@ -0,0 +1,581 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
position: relative;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
font-size: 100%;
|
||||||
|
vertical-align: top;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: "lucida grande";
|
||||||
|
max-height: 128px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #fff;
|
||||||
|
background-position: bottom center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs {
|
||||||
|
overflow: hidden;
|
||||||
|
border-bottom: 1px solid #515151;
|
||||||
|
}
|
||||||
|
|
||||||
|
#twitter, #facebook, #gmail, #settings {
|
||||||
|
/* background-image: -moz-linear-gradient(top, #d0d0d0 0%, #a8a8a8 100%); */
|
||||||
|
background-color: #a7a7a7;
|
||||||
|
/*
|
||||||
|
border-top: 1px solid #515151;
|
||||||
|
-moz-box-shadow: 0 2px 0 -1px #e3e3e3 inset;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav {
|
||||||
|
-moz-box-shadow:0 2px 0 -1px #CDCDCD inset;
|
||||||
|
background-color:#A7A7A7;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username {
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 4px 10px;
|
||||||
|
border-left: 1px dotted #888;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username img {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
-moz-box-shadow: 0 1px 1px rgba(0,0,0,0.25);
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username .userId {
|
||||||
|
color: #000;
|
||||||
|
font-weight: bold;
|
||||||
|
text-shadow: 1px 1px 0 #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .navWrap {
|
||||||
|
width: 960px;
|
||||||
|
/*
|
||||||
|
background-image: url("i/logo.gif");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: right center;
|
||||||
|
*/
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li {
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 3px 0;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 24px;
|
||||||
|
background-image: -moz-linear-gradient(center top , #FDFDFD 0%, #AAAAAA 100%);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #666;
|
||||||
|
-moz-box-shadow: 0 1px 0 #CDCDCD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:hover {
|
||||||
|
background-color: rgba(255,255,255,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected {
|
||||||
|
background-image: -moz-linear-gradient(center top , #bbb 0%, #aaa 100%);
|
||||||
|
-moz-box-shadow: 0 0 3px #666 inset,0 1px 0 #CDCDCD;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:first-child {
|
||||||
|
z-index: 1;
|
||||||
|
-moz-border-radius: 3px 0 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(2) {
|
||||||
|
z-index: 2;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(3) {
|
||||||
|
z-index: 1;
|
||||||
|
-moz-border-radius: 0 3px 3px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 24px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.twitter {
|
||||||
|
background-image: url("../share/i/twitterIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.facebook {
|
||||||
|
background-image: url("../share/i/facebookIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.gmail {
|
||||||
|
background-image: url("../share/i/gmailIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.settings {
|
||||||
|
background-image: url("../share/i/settingsIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug {
|
||||||
|
position: absolute;
|
||||||
|
right: 46px;
|
||||||
|
top: 0;
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug span.name {
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug a.icon {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.nav li.settings,
|
||||||
|
ul.nav li.settings.ui-tabs-selected {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
text-align: center;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings:hover span.name,
|
||||||
|
ul.nav li.settings.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.icon,
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav span.name {
|
||||||
|
display: block;
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.twitter,
|
||||||
|
ul.nav li:hover a.twitter {
|
||||||
|
background-image: url("../share/i/twitterIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.facebook,
|
||||||
|
ul.nav li:hover a.facebook {
|
||||||
|
background-image: url("../share/i/facebookIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.gmail,
|
||||||
|
ul.nav li:hover a.gmail {
|
||||||
|
background-image: url(".../share/i/gmailIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user {
|
||||||
|
font-size: small;
|
||||||
|
width: 140px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user.inactive {
|
||||||
|
opacity: 0.5;
|
||||||
|
background: -moz-repeating-linear-gradient(top left -45deg, #aaa, #aaa 5px, #fff 5px, #fff 10px) #aaa no-repeat fixed;
|
||||||
|
-moz-border-radius: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user .username {
|
||||||
|
color: #444;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.image {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
height: 71px;
|
||||||
|
padding: 4px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.thumb {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background-color: #fff;
|
||||||
|
height: 61px;
|
||||||
|
width: 90px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.info {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150px;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0 5px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info .description {
|
||||||
|
color: #000;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .title {
|
||||||
|
color: #3B5998;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-size: small;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .description {
|
||||||
|
color: #808080;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 2px 15px;
|
||||||
|
font-family: "helvetica neue", helvetica, arial, sans-serif;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height:24px;
|
||||||
|
background-image: -moz-linear-gradient(top,#fdfdfd 0%,#aaa 100%);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #5C5C5C #888 #666;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
margin-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.share {
|
||||||
|
-moz-border-radius: 0 3px 3px 0;
|
||||||
|
-moz-box-shadow: 0 1px 0 #cdcdcd;
|
||||||
|
border-left: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
button:hover, button:active {
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
-moz-box-shadow: 0 0 0 1px rgba(255,255,255,0.35) inset, 0 0 3px rgba(0,0,0,0.75) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea, input[type="text"] {
|
||||||
|
-moz-box-shadow: 0 2px 2px -2px #555 inset, 0 1px 0 #cdcdcd;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #5c5c5c #929292 #929292;
|
||||||
|
font-family: "lucida grande"
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
-moz-border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.message {
|
||||||
|
min-height: 71px;
|
||||||
|
-moz-border-radius: 3px 0 0 3px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus, input[type="text"]:focus {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
height: 26px;
|
||||||
|
width: 238px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]#to {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
padding: 5px 0;
|
||||||
|
width: 960px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -480px;
|
||||||
|
position: relative;
|
||||||
|
min-height: 71px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation {
|
||||||
|
padding: 1px 5px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
background-image: -moz-linear-gradient(top, #fafafa 0%, #e6e6e6 100%);
|
||||||
|
border: 1px solid #bebebe;
|
||||||
|
color: green;
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
color: green;
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation span {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li button {
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h1 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* START hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
/* hbox and vbox classes */
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
/* END hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
|
||||||
|
/* clearfix */
|
||||||
|
|
||||||
|
.clearfix:after {
|
||||||
|
content: ".";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
visibility: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[xmlns] .clearfix {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
* html .clearfix {
|
||||||
|
height: 1%;
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="nativeShare.css">
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#tabs").tabs(/* { fx: { opacity: 'toggle', duration: 0 } } */);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ui-tabs .ui-tabs-hide { display: none; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="tabs" class="tabs-left">
|
||||||
|
|
||||||
|
<ul class="nav clearfix">
|
||||||
|
<div class="navWrap clearfix">
|
||||||
|
<li><a class="icon twitter" title="share on twitter" href="#twitter"><span class="name">Twitter</span></a></li>
|
||||||
|
<li><a class="icon facebook" title="share on facebook" href="#facebook"><span class="name">Facebook</span></a></li>
|
||||||
|
<li><a class="icon gmail" title="share on Gmail" href="#gmail"><span class="name">Gmail</span></a></li>
|
||||||
|
<li class="settings"><a class="icon settings" href="#settings"><span class="name"><img src="i/settings.png"></span></a></li>
|
||||||
|
<div class="username"><img src="i/bryanAvatar.jpg"><span class="userId">@clarkbw</span></div>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="twitter">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="facebook">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="thumbnail">
|
||||||
|
<div class="thumb"></div>
|
||||||
|
<ul class="info">
|
||||||
|
<li class="title">Title</li>
|
||||||
|
<li class="description">Description</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<textarea class="message boxFlex"></textarea>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="gmail">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="inputs">
|
||||||
|
<input id="to" type="text" value="to"/>
|
||||||
|
<input id="subject" type="text" value="subject"/>
|
||||||
|
</div>
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="settings">
|
||||||
|
<div class="entry">
|
||||||
|
<h1>Settings</h1>
|
||||||
|
<ul>
|
||||||
|
<li><button>Add Twitter</button></li>
|
||||||
|
<li><button>Add Facebook</button></li>
|
||||||
|
<li><button>Add GMail</button></li>
|
||||||
|
<li><button>Add FFFFound</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,630 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
position: relative;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
font-size: 100%;
|
||||||
|
vertical-align: top;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 11px;
|
||||||
|
font-family: "lucida grande";
|
||||||
|
max-height: 128px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #fff;
|
||||||
|
background-position: bottom center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
color: #00A0FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs {
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid #777;
|
||||||
|
background-color: #ddd;
|
||||||
|
-moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
|
||||||
|
background-image:-moz-linear-gradient(center top , #EEEEEE 0%, #DDDDDD 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#twitter, #facebook, #gmail, #settings {
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username {
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 4px 10px;
|
||||||
|
border-left: 1px dotted #888;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username img {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
-moz-box-shadow: 0 1px 1px rgba(0,0,0,0.25);
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username .userId {
|
||||||
|
color: #000;
|
||||||
|
font-weight: bold;
|
||||||
|
/* text-shadow: 1px 1px 0 #bbb; */
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .navWrap {
|
||||||
|
position: relative;
|
||||||
|
/*
|
||||||
|
width: 960px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -480px;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li {
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 3px 0;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 24px;
|
||||||
|
background-image: -moz-linear-gradient(center top , #fafafa 0%, #ddd 100%);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #888;
|
||||||
|
-moz-box-shadow: 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:hover {
|
||||||
|
background-color: rgba(255,255,255,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected {
|
||||||
|
-moz-box-shadow:0 0 1px #666666 inset, 0 1px 0 #FFFFFF;
|
||||||
|
background-image:-moz-linear-gradient(center top , #EEEEEE 0%, #CCCCCC 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:first-child {
|
||||||
|
z-index: 1;
|
||||||
|
-moz-border-radius: 2px 0 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(2) {
|
||||||
|
z-index: 2;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(3) {
|
||||||
|
z-index: 1;
|
||||||
|
-moz-border-radius: 0 2px 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 24px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.twitter {
|
||||||
|
background-image: url("../share/i/twitterIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.facebook {
|
||||||
|
background-image: url("../share/i/facebookIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.gmail {
|
||||||
|
background-image: url("../share/i/gmailIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.settings {
|
||||||
|
background-image: url("../share/i/settingsIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug {
|
||||||
|
position: absolute;
|
||||||
|
right: 46px;
|
||||||
|
top: 0;
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug span.name {
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug a.icon {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.nav li.settings,
|
||||||
|
ul.nav li.settings.ui-tabs-selected {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
text-align: center;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings:hover span.name,
|
||||||
|
ul.nav li.settings.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.icon,
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav span.name {
|
||||||
|
display: block;
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.twitter,
|
||||||
|
ul.nav li:hover a.twitter {
|
||||||
|
background-image: url("../share/i/twitterIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.facebook,
|
||||||
|
ul.nav li:hover a.facebook {
|
||||||
|
background-image: url("../share/i/facebookIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.gmail,
|
||||||
|
ul.nav li:hover a.gmail {
|
||||||
|
background-image: url("../share/i/gmailIconColor.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user {
|
||||||
|
font-size: small;
|
||||||
|
width: 140px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user.inactive {
|
||||||
|
opacity: 0.5;
|
||||||
|
background: -moz-repeating-linear-gradient(top left -45deg, #aaa, #aaa 5px, #fff 5px, #fff 10px) #aaa no-repeat fixed;
|
||||||
|
-moz-border-radius: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user .username {
|
||||||
|
color: #444;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.image {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
height: 71px;
|
||||||
|
padding: 4px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
background-image: -moz-linear-gradient(center top , #EEEEEE 0%, #DDDDDD 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
div.thumb {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background-color: #fff;
|
||||||
|
height: 61px;
|
||||||
|
width: 90px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.info {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150px;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 0 5px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info .description {
|
||||||
|
color: #444;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .title {
|
||||||
|
color: #3B5998;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-size: small;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .description {
|
||||||
|
color: #808080;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 2px 15px;
|
||||||
|
background-image: -moz-linear-gradient(center top , #FAFAFA 0%, #DDDDDD 100%);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #888;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
margin-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-box-shadow: 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.share {
|
||||||
|
-moz-border-radius: 0 2px 2px 0;
|
||||||
|
border-left: none;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background-image: -moz-linear-gradient(center top , #EEEEEE 0%, #CCCCCC 100%);
|
||||||
|
-moz-box-shadow:0 0 1px #666666 inset, 0 1px 0 #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea, input[type="text"] {
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #888;
|
||||||
|
font-family: "lucida grande"
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
-moz-box-shadow:0 3px 3px -3px rgba(0, 0, 0, 0.25) inset, 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea.message {
|
||||||
|
min-height: 71px;
|
||||||
|
-moz-border-radius: 2px 0 0 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus, input[type="text"]:focus {
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
height: 26px;
|
||||||
|
width: 238px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]#to {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
padding: 5px 10px;
|
||||||
|
width: 100%;
|
||||||
|
/*
|
||||||
|
width: 960px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -480px;
|
||||||
|
*/
|
||||||
|
position: relative;
|
||||||
|
min-height: 71px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation {
|
||||||
|
padding: 1px 5px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
background-image: -moz-linear-gradient(top, #fafafa 0%, #e6e6e6 100%);
|
||||||
|
border: 1px solid #bebebe;
|
||||||
|
color: green;
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
color: green;
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation span {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul {
|
||||||
|
min-width: 660px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
width: 220px;
|
||||||
|
min-height: 71px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li:nth-child(1) {
|
||||||
|
padding: 0 10px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li:nth-child(2) {
|
||||||
|
padding: 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li:nth-child(3) {
|
||||||
|
padding: 0 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li button {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li h1 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
color: #0a0a0a;
|
||||||
|
padding: 5px 0 0 0;
|
||||||
|
/* border-top: 1px dotted #888; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h1 a {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h1 img {
|
||||||
|
margin-top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry .settings {
|
||||||
|
width: 253px;
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
padding: 0 0 0 10px;
|
||||||
|
border-left: 1px dotted #888;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry .success {
|
||||||
|
width: 100%;
|
||||||
|
line-height: 24px;
|
||||||
|
color: #54B851;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry .success span.check {
|
||||||
|
width: 24px;
|
||||||
|
background-color: #54B851;
|
||||||
|
color: #fff;
|
||||||
|
-moz-border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* START hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
/* hbox and vbox classes */
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
/* END hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
|
||||||
|
/* clearfix */
|
||||||
|
|
||||||
|
.clearfix:after {
|
||||||
|
content: ".";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
visibility: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[xmlns] .clearfix {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
* html .clearfix {
|
||||||
|
height: 1%;
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>F1</title>
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="neutralShare.css">
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#tabs").tabs({ fx: { opacity: 'toggle', duration: 200 } });
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.ui-tabs .ui-tabs-hide { display: none; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="tabs" class="tabs-left">
|
||||||
|
|
||||||
|
<ul class="nav clearfix">
|
||||||
|
<div class="navWrap clearfix">
|
||||||
|
<li><a class="icon twitter" title="share on twitter" href="#twitter"><span class="name">Twitter</span></a></li>
|
||||||
|
<li><a class="icon facebook" title="share on facebook" href="#facebook"><span class="name">Facebook</span></a></li>
|
||||||
|
<li><a class="icon gmail" title="share on Gmail" href="#gmail"><span class="name">Gmail</span></a></li>
|
||||||
|
<li class="settings"><a class="icon settings" href="#settings"><span class="name"><img src="i/settings.png"></span></a></li>
|
||||||
|
<div class="username"><img src="i/bryanAvatar.jpg"><span class="userId">@clarkbw</span></div>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="twitter">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="facebook">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="thumbnail">
|
||||||
|
<div class="thumb"></div>
|
||||||
|
<ul class="info">
|
||||||
|
<li class="title">Title</li>
|
||||||
|
<li class="description">Description</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<textarea class="message boxFlex"></textarea>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="gmail">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="inputs">
|
||||||
|
<input id="to" type="text" value="to"/>
|
||||||
|
<input id="subject" type="text" value="subject"/>
|
||||||
|
</div>
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button class="share">share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="settings">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<ul class="boxFlex">
|
||||||
|
<li>
|
||||||
|
<h1><img src="../share/i/twitterIcon.png"> Twitter</h1>
|
||||||
|
<button>Add Twitter</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h1><img src="../share/i/facebookIcon.png"> Facebook</h1>
|
||||||
|
<button>Add Facebook</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h1><img src="../share/i/gmailIcon.png"> Gmail - <a href="#">manage</a> | <a href="#">add account</a></h1>
|
||||||
|
<div class="success">
|
||||||
|
<span title="gmail is properly configured!" class="check">✔</span> 3 accounts configured
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="settings">
|
||||||
|
<h1>Advanced settings</h1>
|
||||||
|
Don't see what you need? Try the <a href="#">account manager</a> to get into the nitty gritty.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -0,0 +1,568 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-collapse: collapse;
|
||||||
|
position: relative;
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: inherit;
|
||||||
|
font-style: inherit;
|
||||||
|
font-size: 100%;
|
||||||
|
vertical-align: top;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: "helvetica neue", helvetica, arial, sans-serif;
|
||||||
|
max-height: 128px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #fff;
|
||||||
|
background-position: bottom center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tabs {
|
||||||
|
-moz-box-shadow: 0 -5px 2px -4px #DDDDDD inset;
|
||||||
|
height: 125px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav {
|
||||||
|
background-image: url("i/background.gif");
|
||||||
|
-moz-box-shadow: 0 -2px 3px rgba(0,0,0,0.5) inset;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username {
|
||||||
|
height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 24px;
|
||||||
|
position: absolute;
|
||||||
|
right: 35px;
|
||||||
|
top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .username img {
|
||||||
|
border: 1px solid #fff;
|
||||||
|
width: 23px;
|
||||||
|
height: 23px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav .navWrap {
|
||||||
|
width: 962px;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
margin-left:-481px;
|
||||||
|
border-left: 1px solid #222;
|
||||||
|
border-right: 1px solid #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li {
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
list-style-type: none;
|
||||||
|
background-color: #444;
|
||||||
|
margin: 10px 0 0 0px;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 24px;
|
||||||
|
-moz-border-radius: 5px 5px 0 0;
|
||||||
|
-moz-box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:hover {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(n+2) {
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(1) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(2) {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li:nth-child(3) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 0 5px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.twitter {
|
||||||
|
background-image: url("../share/i/twitter_w.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.facebook {
|
||||||
|
background-image: url("../share/i/facebook_w.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.gmail {
|
||||||
|
background-image: url("../share/i/gmail_w.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon.settings {
|
||||||
|
background-image: url("i/settings.png");
|
||||||
|
background-position: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug {
|
||||||
|
position: absolute;
|
||||||
|
right: 46px;
|
||||||
|
top: 0;
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug span.name {
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.debug a.icon {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul.nav li.settings,
|
||||||
|
ul.nav li.settings.ui-tabs-selected {
|
||||||
|
position: absolute;
|
||||||
|
background-color: transparent;
|
||||||
|
background-image: none;
|
||||||
|
-moz-box-shadow: none;
|
||||||
|
right: 15px;
|
||||||
|
top: 0;
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings:hover span.name,
|
||||||
|
ul.nav li.settings.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected {
|
||||||
|
background-color: #fff;
|
||||||
|
background-image: -moz-linear-gradient(top, #fff 0%, #f2f2f2 100%);
|
||||||
|
width: 128px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li a.icon,
|
||||||
|
ul.nav li span.name {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.icon,
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li span.name {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected span.name {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav span.name {
|
||||||
|
display: block;
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected.settings {
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected.settings span.name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.twitter {
|
||||||
|
background-image: url(".../share/i/twitter_b.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.facebook {
|
||||||
|
background-image: url("../share/i/facebook_b.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a.gmail {
|
||||||
|
background-image: url("../share/i/gmail_b.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.nav li.ui-tabs-selected a {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.user {
|
||||||
|
width: 140px;
|
||||||
|
padding-right: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.thumb {
|
||||||
|
width: 220px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.message {
|
||||||
|
width: 300px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.button {
|
||||||
|
padding: 1px 20px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user {
|
||||||
|
font-size: small;
|
||||||
|
width: 140px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user.inactive {
|
||||||
|
opacity: 0.5;
|
||||||
|
background: -moz-repeating-linear-gradient(top left -45deg, #aaa, #aaa 5px, #fff 5px, #fff 10px) #aaa no-repeat fixed;
|
||||||
|
-moz-border-radius: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.user .username {
|
||||||
|
color: #444;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
td.image {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.thumb {
|
||||||
|
border: 1px solid #aaa;
|
||||||
|
background-color: #fff;
|
||||||
|
height: 71px;
|
||||||
|
width: 90px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.info {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info .description {
|
||||||
|
color: #666;
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .title {
|
||||||
|
color: #3B5998;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-size: small;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb .description {
|
||||||
|
color: #808080;
|
||||||
|
font-size: x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 2px 15px;
|
||||||
|
font-family: "helvetica neue", helvetica, arial, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height:24px;
|
||||||
|
background-image: -moz-linear-gradient(top,#fafafa 0%,#e6e6e6 100%);
|
||||||
|
border: 1px solid #bebebe;
|
||||||
|
-moz-box-shadow: 0 0 0 1px #fff inset;
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover, button:active {
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
-moz-box-shadow: 0 0 0 1px rgba(255,255,255,0.35) inset, 0 0 3px rgba(0,0,0,0.75) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea, input[type="text"] {
|
||||||
|
-moz-box-shadow: 0 0 2px #CCCCCC inset;
|
||||||
|
/* background-image: -moz-linear-gradient(center top , #FFFFFF 0%, #F2F2F2 100%); */
|
||||||
|
border: 1px solid #BEBEBE;
|
||||||
|
font-family: "helvetica neue",helvetica,arial,sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 3px;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus, input[type="text"]:focus {
|
||||||
|
border: 1px solid #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
height: 30px;
|
||||||
|
width: 234px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"]#to {
|
||||||
|
margin-bottom: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
padding: 10px;
|
||||||
|
width: 962px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -481px;
|
||||||
|
position: relative;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
min-height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation {
|
||||||
|
padding: 1px 5px;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
background-image: -moz-linear-gradient(top, #fafafa 0%, #e6e6e6 100%);
|
||||||
|
border: 1px solid #bebebe;
|
||||||
|
color: green;
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
z-index: 1;
|
||||||
|
color: green;
|
||||||
|
font-size: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry .urlConfirmation span {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li {
|
||||||
|
display: inline-block;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#settings .entry ul li button {
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
width: 128px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h1 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* START hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
/* hbox and vbox classes */
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
/* END hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
|
||||||
|
/* clearfix */
|
||||||
|
|
||||||
|
.clearfix:after {
|
||||||
|
content: ".";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
visibility: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[xmlns] .clearfix {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
* html .clearfix {
|
||||||
|
height: 1%;
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="share.css">
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
$("#tabs").tabs({ fx: { opacity: 'toggle', duration: 200 } });
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.ui-tabs .ui-tabs-hide { display: none; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="tabs" class="tabs-left">
|
||||||
|
|
||||||
|
<ul class="nav clearfix">
|
||||||
|
<div class="navWrap clearfix">
|
||||||
|
<li><a class="icon twitter" href="#twitter"><span class="name">Twitter</span></a></li>
|
||||||
|
<li><a class="icon facebook" href="#facebook"><span class="name">Facebook</span></a></li>
|
||||||
|
<li><a class="icon gmail" href="#gmail"><span class="name">Gmail</span></a></li>
|
||||||
|
<li class="settings"><a class="icon settings" href="#settings"><span class="name"><img src="i/settings.png"></span></a></li>
|
||||||
|
<div class="username">@clarkbw <img src="i/bryanAvatar.jpg"></div>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="twitter">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="facebook">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="thumbnail">
|
||||||
|
<div class="thumb"></div>
|
||||||
|
<ul class="info">
|
||||||
|
<li class="title">Title</li>
|
||||||
|
<li class="description">Description</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<textarea class="message boxFlex"></textarea>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="gmail">
|
||||||
|
<div class="entry hbox">
|
||||||
|
<div class="inputs">
|
||||||
|
<input id="to" type="text" value="to"/>
|
||||||
|
<input id="subject" type="text" value="subject"/>
|
||||||
|
</div>
|
||||||
|
<div class="boxFlex">
|
||||||
|
<textarea class="message"></textarea>
|
||||||
|
<span class="urlConfirmation"><span>re-insert link</span></span>
|
||||||
|
</div>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="settings">
|
||||||
|
<div class="entry">
|
||||||
|
<h1>Settings</h1>
|
||||||
|
<ul>
|
||||||
|
<li><button>Add Twitter</button></li>
|
||||||
|
<li><button>Add Facebook</button></li>
|
||||||
|
<li><button>Add GMail</button></li>
|
||||||
|
<li><button>Add FFFFound</button></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
После Ширина: | Высота: | Размер: 3.3 KiB |
После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -0,0 +1,231 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>F1: Sidebar</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="style.css">
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jquery.textOverflow.js"></script>
|
||||||
|
<script type="text/javascript" src="js/init.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="wrapper">
|
||||||
|
|
||||||
|
<div id="panel1" class="flip">
|
||||||
|
|
||||||
|
<header class="hbox">
|
||||||
|
<h1 class="boxFlex">Share</h1>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li class="settings"><a class="configureToggle" href="#">configure</a></li>
|
||||||
|
<li><span class="close"></span></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section id="pageInfo" class="hbox">
|
||||||
|
<div class="thumbnail"><img src="i/thumb.jpg"></div>
|
||||||
|
<h2 class="boxFlex overflow pageTitle">F1 by Mozilla Labs</h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="twitter" class="account selected">
|
||||||
|
<div class="accountToggle hbox open">
|
||||||
|
<span class="arrow"></span>
|
||||||
|
<span class="icon twitter"></span>
|
||||||
|
<h3 class="boxFlex overflow">Twitter</h3>
|
||||||
|
<span class="username">_andychung</span>
|
||||||
|
</div>
|
||||||
|
<div class="accountPanel">
|
||||||
|
<div class="padding">
|
||||||
|
<label>type your message:</label>
|
||||||
|
<textarea class="compose"></textarea>
|
||||||
|
<div class="accountActions hbox">
|
||||||
|
<span class="count boxFlex">140</span>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="facebook" class="account">
|
||||||
|
<div class="accountToggle hbox">
|
||||||
|
<span class="arrow"></span>
|
||||||
|
<span class="icon facebook"></span>
|
||||||
|
<h3 class="boxFlex overflow">Facebook</h3>
|
||||||
|
<span class="username">Andy Chung</span>
|
||||||
|
</div>
|
||||||
|
<div class="accountPanel">
|
||||||
|
<div class="padding">
|
||||||
|
<div class="facebookActions hbox">
|
||||||
|
<div class="to">
|
||||||
|
<label>send to:</label>
|
||||||
|
<div class="dropdownContainer">
|
||||||
|
<select class="facebookDropdown">
|
||||||
|
<option selected value="1">my wall</option>
|
||||||
|
<option value="2">group wall</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="group boxFlex">
|
||||||
|
<label>type in the name of group:</label>
|
||||||
|
<input type="text">
|
||||||
|
</div>
|
||||||
|
<div class="list">
|
||||||
|
<label>list</label>
|
||||||
|
<button></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<label>type your message:</label>
|
||||||
|
<textarea class="compose"></textarea>
|
||||||
|
<div class="accountActions hbox">
|
||||||
|
<span class="count boxFlex">420</span>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="google" class="account">
|
||||||
|
<div class="accountToggle hbox">
|
||||||
|
<span class="arrow"></span>
|
||||||
|
<span class="icon google"></span>
|
||||||
|
<h3 class="boxFlex overflow">Google Mail</h3>
|
||||||
|
<span class="username">animalyouth@gmail.com</span>
|
||||||
|
</div>
|
||||||
|
<div class="accountPanel">
|
||||||
|
<div class="padding">
|
||||||
|
<div class="to">
|
||||||
|
<label>to: <em>(enter emails separated by comma)</em></label>
|
||||||
|
<input type="text">
|
||||||
|
</div>
|
||||||
|
<div class="subject">
|
||||||
|
<label>subject:</label>
|
||||||
|
<input type="text">
|
||||||
|
</div>
|
||||||
|
<label>type your message:</label>
|
||||||
|
<textarea class="compose"></textarea>
|
||||||
|
<div class="accountActions hbox">
|
||||||
|
<span class="count boxFlex"></span>
|
||||||
|
<button>share</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div style="position:absolute;bottom:0;">
|
||||||
|
<section id="news" class="hbox">
|
||||||
|
<div>
|
||||||
|
<span class="icon rss"></span>
|
||||||
|
</div>
|
||||||
|
<div class="boxFlex">
|
||||||
|
<h3>Latest from the F1 team</h3>
|
||||||
|
<div class="story">"F1 goes live!"</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- begin settings panel -->
|
||||||
|
<div id="panel2" class="flip">
|
||||||
|
|
||||||
|
<header class="hbox">
|
||||||
|
<h1 class="boxFlex">Share configuration</h1>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li class="settings"><a class="configureToggle" href="#">return to sharing</a></li>
|
||||||
|
<li><span class="close"></span></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<ul id="tabs" class="clearfix">
|
||||||
|
<li class="manage selected">manage</li>
|
||||||
|
<li class="add">add account</li>
|
||||||
|
<li class="settings">settings</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div id="accountPanels">
|
||||||
|
|
||||||
|
<section id="manageAccounts" class="configuration">
|
||||||
|
<h2>manage your accounts</h2>
|
||||||
|
<ul class="accountList">
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon twitter"></span>
|
||||||
|
<span class="username">_andychung</span>
|
||||||
|
</h3>
|
||||||
|
<button>remove</button>
|
||||||
|
</li>
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon facebook"></span>
|
||||||
|
<span class="username">Andy Chung</span>
|
||||||
|
</h3>
|
||||||
|
<button>remove</button>
|
||||||
|
</li>
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon google"></span>
|
||||||
|
<span class="username">animalyouth@gmail.com</span>
|
||||||
|
</h3>
|
||||||
|
<button>remove</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="addAccounts" class="configuration">
|
||||||
|
<h2>add more accounts</h2>
|
||||||
|
<ul class="accountList">
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon twitter"></span>
|
||||||
|
Twitter
|
||||||
|
</h3>
|
||||||
|
<button>add</button>
|
||||||
|
</li>
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon facebook"></span>
|
||||||
|
Facebook
|
||||||
|
</h3>
|
||||||
|
<button>add</button>
|
||||||
|
</li>
|
||||||
|
<li class="accountType hbox">
|
||||||
|
<h3 class="accountName boxFlex overflow">
|
||||||
|
<span class="icon google"></span>
|
||||||
|
Google Mail
|
||||||
|
</h3>
|
||||||
|
<button>add</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="accountSettings" class="configuration">
|
||||||
|
<h2>F1 settings</h2>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="pref"><input id="bookmark" type="checkbox"> <label for="bookmark">Always bookmark the links I share</label></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="pref"><input id="signature" type="checkbox"> <label for="signature">Include F1 email signature</label></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section id="save" class="configuration">
|
||||||
|
<div class="done hbox">
|
||||||
|
<span class="boxFlex"></span>
|
||||||
|
<button class="save">done</button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,103 @@
|
||||||
|
$(document).ready(function($) {
|
||||||
|
|
||||||
|
// set panel min-height to full browser height
|
||||||
|
$(window).bind("load resize", function(){
|
||||||
|
var h = $(window).height();
|
||||||
|
$("#wrapper, #panel1, #panel2").css({ "min-height" : (h) });
|
||||||
|
});
|
||||||
|
|
||||||
|
// create ellipsis for gecko
|
||||||
|
$(function() {
|
||||||
|
$(".overflow").textOverflow(null,true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// simple accordian menu
|
||||||
|
$(".accountToggle").click(function() {
|
||||||
|
$(".accountPanel:visible").slideUp(200);
|
||||||
|
if ($(this).next().is(":hidden")) {
|
||||||
|
$(this).next().slideDown(200);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".accountPanel").hide();
|
||||||
|
$(".open").trigger("click");
|
||||||
|
|
||||||
|
$(".accountToggle").click(function() {
|
||||||
|
$(this).parent().toggleClass("selected");
|
||||||
|
$(this).parent().siblings().removeClass("selected");
|
||||||
|
});
|
||||||
|
|
||||||
|
// hide and display facebook form
|
||||||
|
$(".group, .list").hide();
|
||||||
|
|
||||||
|
$("select.facebookDropdown").change(function () {
|
||||||
|
if ($(".group, .list").is(":hidden")) {
|
||||||
|
$(".group, .list").css({ "display" : "block" });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".group, .list").css({ "display" : "none" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// account manager simple tabs
|
||||||
|
$("ul#tabs li").click(function() {
|
||||||
|
$(this).addClass("selected");
|
||||||
|
$(this).siblings().removeClass("selected");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("ul#tabs li.manage").click(function() {
|
||||||
|
if ($("section#manageAccounts").is(":hidden")) {
|
||||||
|
$("section#manageAccounts").fadeIn(200);
|
||||||
|
$("section#manageAccounts").siblings().fadeOut(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("section#manageAccounts").noop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("ul#tabs li.add").click(function() {
|
||||||
|
if ($("section#addAccounts").is(":hidden")) {
|
||||||
|
$("section#addAccounts").fadeIn(200);
|
||||||
|
$("section#addAccounts").siblings().fadeOut(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("section#addAccounts").noop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("ul#tabs li.settings").click(function() {
|
||||||
|
if ($("section#accountSettings").is(":hidden")) {
|
||||||
|
$("section#accountSettings").fadeIn(200);
|
||||||
|
$("section#accountSettings").siblings().fadeOut(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("section#manageAccounts").noop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("section#addAccounts, section#accountSettings").hide();
|
||||||
|
|
||||||
|
// 3d flip with fade fallback
|
||||||
|
$(function() {
|
||||||
|
if (jQuery.browser.webkit) {
|
||||||
|
$("a.configureToggle").bind("click", function() {
|
||||||
|
$("#panel1").toggleClass("front_flip");
|
||||||
|
$("#panel2").toggleClass("back_flip");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("a.configureToggle").bind("click", function() {
|
||||||
|
if ($("#panel1").is(":visible")) {
|
||||||
|
$("#panel1").fadeOut(100);
|
||||||
|
$("#panel2").fadeIn(100);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#panel1").fadeIn(100);
|
||||||
|
$("#panel2").fadeOut(100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// done!
|
||||||
|
});
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*!
|
||||||
|
* jQuery Text Overflow v0.7
|
||||||
|
*
|
||||||
|
* Licensed under the new BSD License.
|
||||||
|
* Copyright 2009-2010, Bram Stein
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
/*global jQuery, document, setInterval*/
|
||||||
|
(function ($) {
|
||||||
|
var style = document.documentElement.style,
|
||||||
|
hasTextOverflow = ('textOverflow' in style || 'OTextOverflow' in style),
|
||||||
|
|
||||||
|
domSplit = function (root, maxIndex) {
|
||||||
|
var index = 0, result = [],
|
||||||
|
domSplitAux = function (nodes) {
|
||||||
|
var i = 0, tmp;
|
||||||
|
|
||||||
|
if (index > maxIndex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nodes.length; i += 1) {
|
||||||
|
if (nodes[i].nodeType === 1) {
|
||||||
|
tmp = nodes[i].cloneNode(false);
|
||||||
|
result[result.length - 1].appendChild(tmp);
|
||||||
|
result.push(tmp);
|
||||||
|
domSplitAux(nodes[i].childNodes);
|
||||||
|
result.pop();
|
||||||
|
} else if (nodes[i].nodeType === 3) {
|
||||||
|
if (index + nodes[i].length < maxIndex) {
|
||||||
|
result[result.length - 1].appendChild(nodes[i].cloneNode(false));
|
||||||
|
} else {
|
||||||
|
tmp = nodes[i].cloneNode(false);
|
||||||
|
tmp.textContent = $.trim(tmp.textContent.substring(0, maxIndex - index));
|
||||||
|
result[result.length - 1].appendChild(tmp);
|
||||||
|
}
|
||||||
|
index += nodes[i].length;
|
||||||
|
} else {
|
||||||
|
result.appendChild(nodes[i].cloneNode(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
result.push(root.cloneNode(false));
|
||||||
|
domSplitAux(root.childNodes);
|
||||||
|
return $(result.pop().childNodes);
|
||||||
|
};
|
||||||
|
|
||||||
|
$.extend($.fn, {
|
||||||
|
textOverflow: function (str, autoUpdate) {
|
||||||
|
var more = str || '…';
|
||||||
|
|
||||||
|
if (!hasTextOverflow) {
|
||||||
|
return this.each(function () {
|
||||||
|
var element = $(this),
|
||||||
|
|
||||||
|
// the clone element we modify to measure the width
|
||||||
|
clone = element.clone(),
|
||||||
|
|
||||||
|
// we save a copy so we can restore it if necessary
|
||||||
|
originalElement = element.clone(),
|
||||||
|
originalText = element.text(),
|
||||||
|
originalWidth = element.width(),
|
||||||
|
low = 0, mid = 0,
|
||||||
|
high = originalText.length,
|
||||||
|
reflow = function () {
|
||||||
|
if (originalWidth !== element.width()) {
|
||||||
|
element.replaceWith(originalElement);
|
||||||
|
element = originalElement;
|
||||||
|
originalElement = element.clone();
|
||||||
|
element.textOverflow(str, false);
|
||||||
|
originalWidth = element.width();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
element.after(clone.hide().css({
|
||||||
|
'position': 'absolute',
|
||||||
|
'width': 'auto',
|
||||||
|
'overflow': 'visible',
|
||||||
|
'max-width': 'inherit'
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (clone.width() > originalWidth) {
|
||||||
|
while (low < high) {
|
||||||
|
mid = Math.floor(low + ((high - low) / 2));
|
||||||
|
clone.empty().append(domSplit(originalElement.get(0), mid)).append(more);
|
||||||
|
if (clone.width() < originalWidth) {
|
||||||
|
low = mid + 1;
|
||||||
|
} else {
|
||||||
|
high = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (low < originalText.length) {
|
||||||
|
element.empty().append(domSplit(originalElement.get(0), low - 1)).append(more);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clone.remove();
|
||||||
|
|
||||||
|
if (autoUpdate) {
|
||||||
|
setInterval(reflow, 200);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})(jQuery);
|
|
@ -0,0 +1,625 @@
|
||||||
|
* {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Lucida Grande", Verdana, Sans-serif;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper {
|
||||||
|
max-width: 400px;
|
||||||
|
min-width: 200px;
|
||||||
|
position: relative;
|
||||||
|
border-right: 1px solid #404040;
|
||||||
|
-webkit-perspective: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
button::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
height: 24px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #aaa;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
-moz-border-radius: 2px;
|
||||||
|
-webkit-border-radius: 2px;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
background-image: -moz-linear-gradient(center top , #fafafa 0%, #ddd 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fafafa), color-stop(100%, #ddd));
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
-moz-box-shadow: 0 0 1px #666666 inset;
|
||||||
|
-webkit-box-shadow: 0 0 1px #666666 inset;
|
||||||
|
box-shadow: 0 0 1px #666666 inset;
|
||||||
|
|
||||||
|
background-image: -moz-linear-gradient(center top , #eee 0%, #ccc 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eee), color-stop(100%, #ccc));
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #535f6d;
|
||||||
|
text-shadow: 1px 1px 0 rgba(255,255,255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: #535f6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
panel settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
#panel1,
|
||||||
|
#panel2 {
|
||||||
|
width: 100%;
|
||||||
|
color: #535f6d;
|
||||||
|
overflow: auto;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panel1 {
|
||||||
|
background-color: #d4dde5;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panel1 a,
|
||||||
|
#panel2 a {
|
||||||
|
color: #535f6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panel2 {
|
||||||
|
background-color: #E9EEF2;
|
||||||
|
z-index: 1;
|
||||||
|
-webkit-transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
header section
|
||||||
|
*/
|
||||||
|
|
||||||
|
header {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 5px 10px 10px;
|
||||||
|
background-color: #d4dde5;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a {
|
||||||
|
text-decoration: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav ul li {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 5px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
header nav ul li.settings {
|
||||||
|
border-width: 0 1px 0 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #535f6d;
|
||||||
|
}
|
||||||
|
|
||||||
|
header span.close {
|
||||||
|
width: 12px;
|
||||||
|
height: 13px;
|
||||||
|
background-image: url("i/sprite.png");
|
||||||
|
background-position: center 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
header span.close:active {
|
||||||
|
background-position: center -13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
page info
|
||||||
|
*/
|
||||||
|
section#pageInfo {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#pageInfo .thumbnail {
|
||||||
|
border: 1px solid #a6afb6;
|
||||||
|
-moz-box-shadow: 1px 1px 0 rgba(255,255,255, 0.5);
|
||||||
|
-webkit-box-shadow: 1px 1px 0 rgba(255,255,255, 0.5);
|
||||||
|
box-shadow: 1px 1px 0 rgba(255,255,255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
section#pageInfo .thumbnail img {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#pageInfo h2 {
|
||||||
|
line-height: 60px;
|
||||||
|
margin: 0 0 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
generic styles for account panels
|
||||||
|
*/
|
||||||
|
section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account {
|
||||||
|
color: #535F6D;
|
||||||
|
display: block;
|
||||||
|
border-width: 1px 0;
|
||||||
|
border-color: #a6afb6;
|
||||||
|
border-style: solid;
|
||||||
|
margin-top: -1px;
|
||||||
|
background-image: -moz-linear-gradient(top, #d4dde5 0%, #c6d1da 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #d4dde5), color-stop(100%, #c6d1da));
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account:hover,
|
||||||
|
section.account.selected {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account.selected {
|
||||||
|
background-color: #e9eef2;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .username {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account.selected .username {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .accountToggle {
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.arrow,
|
||||||
|
span.icon {
|
||||||
|
display: inline-block;
|
||||||
|
background-image: url("i/sprite.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
span.arrow {
|
||||||
|
width: 12px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 14px;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .accountToggle span.arrow {
|
||||||
|
background-position: center -102px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account.selected .accountToggle span.arrow {
|
||||||
|
background-position: center -120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .accountPanel {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .accountPanel .padding {
|
||||||
|
padding: 0 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account textarea,
|
||||||
|
section.account input[type="text"] {
|
||||||
|
width: 100%;
|
||||||
|
font-family: "Lucida Grande", Verdana, Sans-serif;
|
||||||
|
font-size: 11px;
|
||||||
|
padding: 5px;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #A6AFB6;
|
||||||
|
-moz-box-shadow: 0 1px 1px rgba(0,0,0,0.15) inset;
|
||||||
|
-webkit-box-shadow: 0 1px 1px rgba(0,0,0,0.15) inset;
|
||||||
|
box-shadow: 0 1px 1px rgba(0,0,0,0.15) inset;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account textarea:focus,
|
||||||
|
section.account input[type="text"]:focus {
|
||||||
|
-moz-box-shadow: 0 0 0 2px #C2ECFF inset;
|
||||||
|
-webkit-box-shadow: 0 0 0 2px #C2ECFF inset;
|
||||||
|
box-shadow: 0 0 0 2px #C2ECFF inset;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:focus {
|
||||||
|
outline: none;
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account input[type="text"] {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account .accountActions {
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account span.count {
|
||||||
|
line-height: 24px;
|
||||||
|
color: #535F6D;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.account label {
|
||||||
|
display: block;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
twitter styles
|
||||||
|
*/
|
||||||
|
span.icon.twitter {
|
||||||
|
background-position: center -35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
facebook styles
|
||||||
|
*/
|
||||||
|
section#facebook.account .facebookActions {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .to {
|
||||||
|
width: 100px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .to .dropdownContainer {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .to select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .list label {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .list button {
|
||||||
|
border-left: none;
|
||||||
|
width: 24px;
|
||||||
|
background-image: url("i/sprite.png"), -moz-linear-gradient(center top , #fafafa 0%, #ddd 100%);
|
||||||
|
background-image: url("i/sprite.png"), -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fafafa), color-stop(100%, #ddd));
|
||||||
|
background-position: center -157px, center top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
-moz-border-radius: 0 2px 2px 0;
|
||||||
|
-webkit-border-radius: 0 2px 2px 0;
|
||||||
|
border-radius: 0 2px 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#facebook.account .facebookActions .list button:active {
|
||||||
|
background-image: url("i/sprite.png"), -moz-linear-gradient(center top , #eee 0%, #ccc 100%);
|
||||||
|
background-image: url("i/sprite.png"), -webkit-gradient(linear, left top, left bottom, color-stop(0%, #eee), color-stop(100%, #ccc));
|
||||||
|
}
|
||||||
|
|
||||||
|
span.icon.facebook {
|
||||||
|
background-position: center -59px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
google styles
|
||||||
|
*/
|
||||||
|
section#google.account .subject {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.icon.google {
|
||||||
|
background-position: center -82px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
account configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
ul#tabs {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 10px 0 10px;
|
||||||
|
list-style-type: none;
|
||||||
|
background-color: #D4DDE5;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tabs li {
|
||||||
|
padding: 7px 20px;
|
||||||
|
margin: 0 3px 0 0;
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #E9EEF2;
|
||||||
|
border-width: 1px 1px 0 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #A6AFB6;
|
||||||
|
-moz-border-radius: 3px 3px 0 0;
|
||||||
|
-webkit-border-radius: 3px 3px 0 0;
|
||||||
|
border-radius: 3px 3px 0 0;
|
||||||
|
float: left;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#tabs li.selected {
|
||||||
|
position: relative;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#accountPanels {
|
||||||
|
padding: 10px 0 0;
|
||||||
|
border-top: 1px solid #a6afb6;
|
||||||
|
position: relative;
|
||||||
|
z-index: 90;
|
||||||
|
margin-top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration {
|
||||||
|
padding: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration h2 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration ul {
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #A6AFB6;
|
||||||
|
-moz-border-radius: 5px;
|
||||||
|
-webkit-border-radius: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration ul li {
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid #A6AFB6;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration ul li:last-child {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration h3 {
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration h3 .username {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration input[type="checkbox"] {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.configuration .done {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#news {
|
||||||
|
padding: 10px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#news span.icon.rss {
|
||||||
|
background-position: center -183px;
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
section#news .story {
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
hbox & vbox
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
clearfix
|
||||||
|
*/
|
||||||
|
|
||||||
|
.clearfix:after {
|
||||||
|
content: ".";
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
visibility: hidden;
|
||||||
|
line-height: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[xmlns] .clearfix {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
* html .clearfix {
|
||||||
|
height: 1%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
webkit specific styles
|
||||||
|
*/
|
||||||
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
|
|
||||||
|
#wrapper {
|
||||||
|
background-color: #404040;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overflow {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow-x: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flip {
|
||||||
|
-webkit-transform-style: preserve-3d;
|
||||||
|
-webkit-backface-visibility: hidden;
|
||||||
|
-webkit-transition: -webkit-transform 0.7s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.front_flip {
|
||||||
|
-webkit-transform: rotateY(-180deg);
|
||||||
|
z-index: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back_flip {
|
||||||
|
-webkit-transform: rotateY(0deg) !important;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
|
||||||
|
<!-- A hacky sample to attempt a send and handle auth failure automatically
|
||||||
|
then attempt a resend
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Send a message</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
|
|
||||||
|
<script src="../../scripts/requireplugins-jquery.js" charset="utf-8"></script>
|
||||||
|
<script>require(["index.js"]);</script>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invisible {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="settings">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="c4 logo">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- send form -->
|
||||||
|
<div class="section send">
|
||||||
|
<form name="messageForm" id="messageForm" action="#">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<input name="message">
|
||||||
|
Send via
|
||||||
|
<input type="radio" name="domain" value="twitter.com">Twitter
|
||||||
|
<input type="radio" name="domain" value="facebook.com">Facebook
|
||||||
|
<input type="radio" name="domain" value="noservice.com">No Service
|
||||||
|
|
||||||
|
<input type="hidden" name="end_point_success" value="/scratch/send/#success">
|
||||||
|
<input type="hidden" name="end_point_failure" value="/scratch/send/#failure">
|
||||||
|
<input type="hidden" name="end_point_auth_failure" value="/scratch/send/#auth_failure">
|
||||||
|
<button>send</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="c1">
|
||||||
|
<div class="usernameError error invisible">Please enter your Twitter name</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- send success section -->
|
||||||
|
<div class="section success hidden">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<h4 class="success">Success!</h4>
|
||||||
|
<p>Your message was sent</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- auth failure section
|
||||||
|
|
||||||
|
This is the end_point for when the *send* request fails auth (but not
|
||||||
|
when the explicit auth request fails) - when this happens we do the
|
||||||
|
explicit auth.
|
||||||
|
-->
|
||||||
|
<div class="section auth_failure hidden">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<p>Authorizing...</p>
|
||||||
|
<!-- the js code arranges to submit the auth form below... -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section auth_form hidden"> <!-- this is never made visible -->
|
||||||
|
<form name="authForm" id="authForm" action="/api/account/authorize" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<input type="hidden" name="domain">
|
||||||
|
<input type="hidden" name="end_point_success" value="/scratch/send/#auth_success">
|
||||||
|
<input type="hidden" name="end_point_auth_failure" value="/scratch/send/#final_auth_failure">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- final auth failure section
|
||||||
|
This is the end_point for when the explicit auth request fails - we have
|
||||||
|
given up here...
|
||||||
|
-->
|
||||||
|
<div class="section final_auth_failure hidden">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<p>Failed to authorize...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- auth success section
|
||||||
|
This is the end_point for when the explicit auth request succeeds - we
|
||||||
|
then attempt to retry the send.
|
||||||
|
-->
|
||||||
|
<div class="section auth_success hidden">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<p>Sending...</p>
|
||||||
|
<!-- the JS code re-submits the send form -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- general failure section - an error other than auth failure...-->
|
||||||
|
<div id="resultMsg" class="section failure hidden">
|
||||||
|
<div class="row">
|
||||||
|
<div class="c1">
|
||||||
|
<p id="resultReason">Sorry - we failed for obscure reasons...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,481 @@
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
[This is the first released version of the library GPL. It is
|
||||||
|
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
Licenses are intended to guarantee your freedom to share and change
|
||||||
|
free software--to make sure the software is free for all its users.
|
||||||
|
|
||||||
|
This license, the Library General Public License, applies to some
|
||||||
|
specially designated Free Software Foundation software, and to any
|
||||||
|
other libraries whose authors decide to use it. You can use it for
|
||||||
|
your libraries, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if
|
||||||
|
you distribute copies of the library, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of the library, whether gratis
|
||||||
|
or for a fee, you must give the recipients all the rights that we gave
|
||||||
|
you. You must make sure that they, too, receive or can get the source
|
||||||
|
code. If you link a program with the library, you must provide
|
||||||
|
complete object files to the recipients so that they can relink them
|
||||||
|
with the library, after making changes to the library and recompiling
|
||||||
|
it. And you must show them these terms so they know their rights.
|
||||||
|
|
||||||
|
Our method of protecting your rights has two steps: (1) copyright
|
||||||
|
the library, and (2) offer you this license which gives you legal
|
||||||
|
permission to copy, distribute and/or modify the library.
|
||||||
|
|
||||||
|
Also, for each distributor's protection, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
library. If the library is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original
|
||||||
|
version, so that any problems introduced by others will not reflect on
|
||||||
|
the original authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that companies distributing free
|
||||||
|
software will individually obtain patent licenses, thus in effect
|
||||||
|
transforming the program into proprietary software. To prevent this,
|
||||||
|
we have made it clear that any patent must be licensed for everyone's
|
||||||
|
free use or not licensed at all.
|
||||||
|
|
||||||
|
Most GNU software, including some libraries, is covered by the ordinary
|
||||||
|
GNU General Public License, which was designed for utility programs. This
|
||||||
|
license, the GNU Library General Public License, applies to certain
|
||||||
|
designated libraries. This license is quite different from the ordinary
|
||||||
|
one; be sure to read it in full, and don't assume that anything in it is
|
||||||
|
the same as in the ordinary license.
|
||||||
|
|
||||||
|
The reason we have a separate public license for some libraries is that
|
||||||
|
they blur the distinction we usually make between modifying or adding to a
|
||||||
|
program and simply using it. Linking a program with a library, without
|
||||||
|
changing the library, is in some sense simply using the library, and is
|
||||||
|
analogous to running a utility program or application program. However, in
|
||||||
|
a textual and legal sense, the linked executable is a combined work, a
|
||||||
|
derivative of the original library, and the ordinary General Public License
|
||||||
|
treats it as such.
|
||||||
|
|
||||||
|
Because of this blurred distinction, using the ordinary General
|
||||||
|
Public License for libraries did not effectively promote software
|
||||||
|
sharing, because most developers did not use the libraries. We
|
||||||
|
concluded that weaker conditions might promote sharing better.
|
||||||
|
|
||||||
|
However, unrestricted linking of non-free programs would deprive the
|
||||||
|
users of those programs of all benefit from the free status of the
|
||||||
|
libraries themselves. This Library General Public License is intended to
|
||||||
|
permit developers of non-free programs to use free libraries, while
|
||||||
|
preserving your freedom as a user of such programs to change the free
|
||||||
|
libraries that are incorporated in them. (We have not seen how to achieve
|
||||||
|
this as regards changes in header files, but we have achieved it as regards
|
||||||
|
changes in the actual functions of the Library.) The hope is that this
|
||||||
|
will lead to faster development of free libraries.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow. Pay close attention to the difference between a
|
||||||
|
"work based on the library" and a "work that uses the library". The
|
||||||
|
former contains code derived from the library, while the latter only
|
||||||
|
works together with the library.
|
||||||
|
|
||||||
|
Note that it is possible for a library to be covered by the ordinary
|
||||||
|
General Public License rather than by this special one.
|
||||||
|
|
||||||
|
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License Agreement applies to any software library which
|
||||||
|
contains a notice placed by the copyright holder or other authorized
|
||||||
|
party saying it may be distributed under the terms of this Library
|
||||||
|
General Public License (also called "this License"). Each licensee is
|
||||||
|
addressed as "you".
|
||||||
|
|
||||||
|
A "library" means a collection of software functions and/or data
|
||||||
|
prepared so as to be conveniently linked with application programs
|
||||||
|
(which use some of those functions and data) to form executables.
|
||||||
|
|
||||||
|
The "Library", below, refers to any such software library or work
|
||||||
|
which has been distributed under these terms. A "work based on the
|
||||||
|
Library" means either the Library or any derivative work under
|
||||||
|
copyright law: that is to say, a work containing the Library or a
|
||||||
|
portion of it, either verbatim or with modifications and/or translated
|
||||||
|
straightforwardly into another language. (Hereinafter, translation is
|
||||||
|
included without limitation in the term "modification".)
|
||||||
|
|
||||||
|
"Source code" for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For a library, complete source code means
|
||||||
|
all the source code for all modules it contains, plus any associated
|
||||||
|
interface definition files, plus the scripts used to control compilation
|
||||||
|
and installation of the library.
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running a program using the Library is not restricted, and output from
|
||||||
|
such a program is covered only if its contents constitute a work based
|
||||||
|
on the Library (independent of the use of the Library in a tool for
|
||||||
|
writing it). Whether that is true depends on what the Library does
|
||||||
|
and what the program that uses the Library does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Library's
|
||||||
|
complete source code as you receive it, in any medium, provided that
|
||||||
|
you conspicuously and appropriately publish on each copy an
|
||||||
|
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||||
|
all the notices that refer to this License and to the absence of any
|
||||||
|
warranty; and distribute a copy of this License along with the
|
||||||
|
Library.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
|
and you may at your option offer warranty protection in exchange for a
|
||||||
|
fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
|
of it, thus forming a work based on the Library, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The modified work must itself be a software library.
|
||||||
|
|
||||||
|
b) You must cause the files modified to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
c) You must cause the whole of the work to be licensed at no
|
||||||
|
charge to all third parties under the terms of this License.
|
||||||
|
|
||||||
|
d) If a facility in the modified Library refers to a function or a
|
||||||
|
table of data to be supplied by an application program that uses
|
||||||
|
the facility, other than as an argument passed when the facility
|
||||||
|
is invoked, then you must make a good faith effort to ensure that,
|
||||||
|
in the event an application does not supply such function or
|
||||||
|
table, the facility still operates, and performs whatever part of
|
||||||
|
its purpose remains meaningful.
|
||||||
|
|
||||||
|
(For example, a function in a library to compute square roots has
|
||||||
|
a purpose that is entirely well-defined independent of the
|
||||||
|
application. Therefore, Subsection 2d requires that any
|
||||||
|
application-supplied function or table used by this function must
|
||||||
|
be optional: if the application does not supply it, the square
|
||||||
|
root function must still compute square roots.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Library,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Library, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote
|
||||||
|
it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Library.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Library
|
||||||
|
with the Library (or with a work based on the Library) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||||
|
License instead of this License to a given copy of the Library. To do
|
||||||
|
this, you must alter all the notices that refer to this License, so
|
||||||
|
that they refer to the ordinary GNU General Public License, version 2,
|
||||||
|
instead of to this License. (If a newer version than version 2 of the
|
||||||
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
|
that version instead if you wish.) Do not make any other change in
|
||||||
|
these notices.
|
||||||
|
|
||||||
|
Once this change is made in a given copy, it is irreversible for
|
||||||
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
|
subsequent copies and derivative works made from that copy.
|
||||||
|
|
||||||
|
This option is useful when you wish to copy part of the code of
|
||||||
|
the Library into a program that is not a library.
|
||||||
|
|
||||||
|
4. You may copy and distribute the Library (or a portion or
|
||||||
|
derivative of it, under Section 2) in object code or executable form
|
||||||
|
under the terms of Sections 1 and 2 above provided that you accompany
|
||||||
|
it with the complete corresponding machine-readable source code, which
|
||||||
|
must be distributed under the terms of Sections 1 and 2 above on a
|
||||||
|
medium customarily used for software interchange.
|
||||||
|
|
||||||
|
If distribution of object code is made by offering access to copy
|
||||||
|
from a designated place, then offering equivalent access to copy the
|
||||||
|
source code from the same place satisfies the requirement to
|
||||||
|
distribute the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
5. A program that contains no derivative of any portion of the
|
||||||
|
Library, but is designed to work with the Library by being compiled or
|
||||||
|
linked with it, is called a "work that uses the Library". Such a
|
||||||
|
work, in isolation, is not a derivative work of the Library, and
|
||||||
|
therefore falls outside the scope of this License.
|
||||||
|
|
||||||
|
However, linking a "work that uses the Library" with the Library
|
||||||
|
creates an executable that is a derivative of the Library (because it
|
||||||
|
contains portions of the Library), rather than a "work that uses the
|
||||||
|
library". The executable is therefore covered by this License.
|
||||||
|
Section 6 states terms for distribution of such executables.
|
||||||
|
|
||||||
|
When a "work that uses the Library" uses material from a header file
|
||||||
|
that is part of the Library, the object code for the work may be a
|
||||||
|
derivative work of the Library even though the source code is not.
|
||||||
|
Whether this is true is especially significant if the work can be
|
||||||
|
linked without the Library, or if the work is itself a library. The
|
||||||
|
threshold for this to be true is not precisely defined by law.
|
||||||
|
|
||||||
|
If such an object file uses only numerical parameters, data
|
||||||
|
structure layouts and accessors, and small macros and small inline
|
||||||
|
functions (ten lines or less in length), then the use of the object
|
||||||
|
file is unrestricted, regardless of whether it is legally a derivative
|
||||||
|
work. (Executables containing this object code plus portions of the
|
||||||
|
Library will still fall under Section 6.)
|
||||||
|
|
||||||
|
Otherwise, if the work is a derivative of the Library, you may
|
||||||
|
distribute the object code for the work under the terms of Section 6.
|
||||||
|
Any executables containing that work also fall under Section 6,
|
||||||
|
whether or not they are linked directly with the Library itself.
|
||||||
|
|
||||||
|
6. As an exception to the Sections above, you may also compile or
|
||||||
|
link a "work that uses the Library" with the Library to produce a
|
||||||
|
work containing portions of the Library, and distribute that work
|
||||||
|
under terms of your choice, provided that the terms permit
|
||||||
|
modification of the work for the customer's own use and reverse
|
||||||
|
engineering for debugging such modifications.
|
||||||
|
|
||||||
|
You must give prominent notice with each copy of the work that the
|
||||||
|
Library is used in it and that the Library and its use are covered by
|
||||||
|
this License. You must supply a copy of this License. If the work
|
||||||
|
during execution displays copyright notices, you must include the
|
||||||
|
copyright notice for the Library among them, as well as a reference
|
||||||
|
directing the user to the copy of this License. Also, you must do one
|
||||||
|
of these things:
|
||||||
|
|
||||||
|
a) Accompany the work with the complete corresponding
|
||||||
|
machine-readable source code for the Library including whatever
|
||||||
|
changes were used in the work (which must be distributed under
|
||||||
|
Sections 1 and 2 above); and, if the work is an executable linked
|
||||||
|
with the Library, with the complete machine-readable "work that
|
||||||
|
uses the Library", as object code and/or source code, so that the
|
||||||
|
user can modify the Library and then relink to produce a modified
|
||||||
|
executable containing the modified Library. (It is understood
|
||||||
|
that the user who changes the contents of definitions files in the
|
||||||
|
Library will not necessarily be able to recompile the application
|
||||||
|
to use the modified definitions.)
|
||||||
|
|
||||||
|
b) Accompany the work with a written offer, valid for at
|
||||||
|
least three years, to give the same user the materials
|
||||||
|
specified in Subsection 6a, above, for a charge no more
|
||||||
|
than the cost of performing this distribution.
|
||||||
|
|
||||||
|
c) If distribution of the work is made by offering access to copy
|
||||||
|
from a designated place, offer equivalent access to copy the above
|
||||||
|
specified materials from the same place.
|
||||||
|
|
||||||
|
d) Verify that the user has already received a copy of these
|
||||||
|
materials or that you have already sent this user a copy.
|
||||||
|
|
||||||
|
For an executable, the required form of the "work that uses the
|
||||||
|
Library" must include any data and utility programs needed for
|
||||||
|
reproducing the executable from it. However, as a special exception,
|
||||||
|
the source code distributed need not include anything that is normally
|
||||||
|
distributed (in either source or binary form) with the major
|
||||||
|
components (compiler, kernel, and so on) of the operating system on
|
||||||
|
which the executable runs, unless that component itself accompanies
|
||||||
|
the executable.
|
||||||
|
|
||||||
|
It may happen that this requirement contradicts the license
|
||||||
|
restrictions of other proprietary libraries that do not normally
|
||||||
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
|
use both them and the Library together in an executable that you
|
||||||
|
distribute.
|
||||||
|
|
||||||
|
7. You may place library facilities that are a work based on the
|
||||||
|
Library side-by-side in a single library together with other library
|
||||||
|
facilities not covered by this License, and distribute such a combined
|
||||||
|
library, provided that the separate distribution of the work based on
|
||||||
|
the Library and of the other library facilities is otherwise
|
||||||
|
permitted, and provided that you do these two things:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work
|
||||||
|
based on the Library, uncombined with any other library
|
||||||
|
facilities. This must be distributed under the terms of the
|
||||||
|
Sections above.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library of the fact
|
||||||
|
that part of it is a work based on the Library, and explaining
|
||||||
|
where to find the accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
8. You may not copy, modify, sublicense, link with, or distribute
|
||||||
|
the Library except as expressly provided under this License. Any
|
||||||
|
attempt otherwise to copy, modify, sublicense, link with, or
|
||||||
|
distribute the Library is void, and will automatically terminate your
|
||||||
|
rights under this License. However, parties who have received copies,
|
||||||
|
or rights, from you under this License will not have their licenses
|
||||||
|
terminated so long as such parties remain in full compliance.
|
||||||
|
|
||||||
|
9. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Library or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Library (or any work based on the
|
||||||
|
Library), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Library or works based on it.
|
||||||
|
|
||||||
|
10. Each time you redistribute the Library (or any work based on the
|
||||||
|
Library), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute, link with or modify the Library
|
||||||
|
subject to these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Library at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Library by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Library.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under any
|
||||||
|
particular circumstance, the balance of the section is intended to apply,
|
||||||
|
and the section as a whole is intended to apply in other circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
12. If the distribution and/or use of the Library is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Library under this License may add
|
||||||
|
an explicit geographical distribution limitation excluding those countries,
|
||||||
|
so that distribution is permitted only in or among countries not thus
|
||||||
|
excluded. In such case, this License incorporates the limitation as if
|
||||||
|
written in the body of this License.
|
||||||
|
|
||||||
|
13. The Free Software Foundation may publish revised and/or new
|
||||||
|
versions of the Library General Public License from time to time.
|
||||||
|
Such new versions will be similar in spirit to the present version,
|
||||||
|
but may differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Library
|
||||||
|
specifies a version number of this License which applies to it and
|
||||||
|
"any later version", you have the option of following the terms and
|
||||||
|
conditions either of that version or of any later version published by
|
||||||
|
the Free Software Foundation. If the Library does not specify a
|
||||||
|
license version number, you may choose any version ever published by
|
||||||
|
the Free Software Foundation.
|
||||||
|
|
||||||
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
|
programs whose distribution conditions are incompatible with these,
|
||||||
|
write to the author to ask for permission. For software which is
|
||||||
|
copyrighted by the Free Software Foundation, write to the Free
|
||||||
|
Software Foundation; we sometimes make exceptions for this. Our
|
||||||
|
decision will be guided by the two goals of preserving the free status
|
||||||
|
of all derivatives of our free software and of promoting the sharing
|
||||||
|
and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||||
|
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||||
|
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||||
|
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||||
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||||
|
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||||
|
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||||
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||||
|
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||||
|
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||||
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||||
|
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||||
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||||
|
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||||
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
possible use to the public, we recommend making it free software that
|
||||||
|
everyone can redistribute and change. You can do so by permitting
|
||||||
|
redistribution under these terms (or, alternatively, under the terms of the
|
||||||
|
ordinary General Public License).
|
||||||
|
|
||||||
|
To apply these terms, attach the following notices to the library. It is
|
||||||
|
safest to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least the
|
||||||
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the library's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
|
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1990
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
That's all there is to it!
|
|
@ -0,0 +1,35 @@
|
||||||
|
The Stay-Puft Marshmallow Font
|
||||||
|
|
||||||
|
Copyright (c) 2003 by John Stracke
|
||||||
|
|
||||||
|
Not a very impressive piece of work, but fun. I sat down to fiddle
|
||||||
|
with pfaedit, and started seeing what I could do freehand, with
|
||||||
|
minimal splines. The result was all rounded (not surprising), sort of
|
||||||
|
marshmallowy, and I started thinking of it as the Stay-Puft
|
||||||
|
Marshmallow Font (see Ghostbusters if you don't get it). Once I had a
|
||||||
|
name, I felt compelled to round out the font (ISO 8859-1, at least).
|
||||||
|
The outcome looks sort of like Comic Sans MS. It's kind of cute, and
|
||||||
|
might be good for frivolous stuff such as birthday cards. I've used
|
||||||
|
it on my National Academy of Silly Walks merchandise
|
||||||
|
(http://www.cafepress.com/sillywalks/).
|
||||||
|
|
||||||
|
It is released under the terms of the GNU Lesser General Public
|
||||||
|
License (see COPYING.LIB). Where the LGPL refers to "source code", I
|
||||||
|
take that to refer to the file called StayPuft.sfd, which is a file
|
||||||
|
for editing with pfaedit (http://pfaedit.sourceforge.net/), an outline
|
||||||
|
font editor program. Thus, according to the LGPL, if you distribute
|
||||||
|
this font, you must make StayPuft.sfd available to the recipient(s)
|
||||||
|
under the terms the LGPL specifies for source availability. Each of
|
||||||
|
the download links below is an archive (tarfile or zipfile) which
|
||||||
|
includes StayPuft.sfd, the LGPL, a readme, and at least one font file
|
||||||
|
(e.g., Isabella.ttf for TrueType files). I chose the LGPL instead of
|
||||||
|
the GPL because, arguably, using the GPL might mean that PostScript
|
||||||
|
and PDF files with this font embedded would be GPLed (they're like
|
||||||
|
programs that link to a static library).
|
||||||
|
|
||||||
|
The font has ASCII, Latin-1, and a few other useful characters: left
|
||||||
|
and right quotation marks (single and double), ellipsis, long dash,
|
||||||
|
and Euro. I don't intend to round it out as much as I did with
|
||||||
|
Isabella (http://www.thibault.org/fonts/isabella/); this is a much
|
||||||
|
less interesting project. Anyone who wants to donate extra
|
||||||
|
letterforms is welcome, of course.
|
После Ширина: | Высота: | Размер: 285 KiB |
|
@ -0,0 +1,402 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/* @font-face typography */
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: StayPuft;
|
||||||
|
src: url("f/StayPuft/StayPuft.ttf");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, Sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
position: relative;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #0a0a0a;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #006FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 21px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px 10px;
|
||||||
|
/* border: 1px solid #884D51; */
|
||||||
|
background-image: -moz-linear-gradient(center top , #FF7A7A 0%, #FF5C5C 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FF7A7A), color-stop(100%, #FF5C5C));
|
||||||
|
border: 1px solid #D94C4C;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 a {
|
||||||
|
color: #0a0a0a;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a:hover,
|
||||||
|
h2 a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a:visited {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 a:visited {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 .type {
|
||||||
|
font-size: smaller;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc {
|
||||||
|
-moz-column-count: 3;
|
||||||
|
-webkit-column-count: 3;
|
||||||
|
column-count: 3;
|
||||||
|
-moz-column-gap: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc a.sectionToc {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc a.methodToc {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc a.methodToc:before {
|
||||||
|
content: "- ";
|
||||||
|
}
|
||||||
|
|
||||||
|
#toc .tocItem {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#listing,
|
||||||
|
#play {
|
||||||
|
float: left;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#play {
|
||||||
|
overflow-x: auto;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
border-left: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#playInstructions {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method {
|
||||||
|
position: relative;
|
||||||
|
border-top: 1px solid #C6ADFF;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .try {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 5px 0px;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
-moz-border-radius: 0 40px 40px 0;
|
||||||
|
-webkit-border-radius: 0 40px 40px 0;
|
||||||
|
border-radius: 0 40px 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.method h2 {
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px 10px;
|
||||||
|
/* border: 1px solid #884D51; */
|
||||||
|
background-image: -moz-linear-gradient(center top , #EDE6FF 0%, #DAC9FF 100%);
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #EDE6FF), color-stop(100%, #DAC9FF));
|
||||||
|
border: 1px solid #C6ADFF;
|
||||||
|
border-top: none;
|
||||||
|
-moz-border-radius: 0 0 10px 10px;
|
||||||
|
-webkit-border-radius: 0 0 10px 10px;
|
||||||
|
border-radius: 0 0 10px 10px;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .section {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .section h3 {
|
||||||
|
margin-left: -20px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .section > ul {
|
||||||
|
padding-left: 20px;
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .section p {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method .required {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall {
|
||||||
|
padding: 10px ;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall:nth-child(odd) {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCallClose {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 0px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #0a0a0a;
|
||||||
|
border: 0;
|
||||||
|
font-family: "helvetica neue", helvetica, arial, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall .apiUrlExpand {
|
||||||
|
position: absolute;
|
||||||
|
top: 15px;
|
||||||
|
right: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall h3 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall h4 {
|
||||||
|
margin: 10px 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall .editApiUrl {
|
||||||
|
width: 50%;
|
||||||
|
margin-top: 4px;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall .requestBody {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall .output {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.apiCall button[name=submit] {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsonResult .expander {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: xx-small;
|
||||||
|
background-color: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.jsonResult ol.array,
|
||||||
|
.jsonResult ul.object {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jsonResult .prop,
|
||||||
|
.jsonResult .brace,
|
||||||
|
.jsonResult .bracket {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* START hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
||||||
|
/* hbox and vbox classes */
|
||||||
|
|
||||||
|
.hbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: horizontal;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: horizontal;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-align: stretch;
|
||||||
|
|
||||||
|
display: -moz-box;
|
||||||
|
-moz-box-orient: vertical;
|
||||||
|
-moz-box-align: stretch;
|
||||||
|
|
||||||
|
display: box;
|
||||||
|
box-orient: vertical;
|
||||||
|
box-align: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox > * {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reverse {
|
||||||
|
-webkit-box-direction: reverse;
|
||||||
|
-moz-box-direction: reverse;
|
||||||
|
box-direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex0 {
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
-moz-box-flex: 0;
|
||||||
|
box-flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex1, .boxFlex {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-moz-box-flex: 1;
|
||||||
|
box-flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxFlex2 {
|
||||||
|
-webkit-box-flex: 2;
|
||||||
|
-moz-box-flex: 2;
|
||||||
|
box-flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup1 {
|
||||||
|
-webkit-box-flex-group: 1;
|
||||||
|
-moz-box-flex-group: 1;
|
||||||
|
box-flex-group: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxGroup2 {
|
||||||
|
-webkit-box-flex-group: 2;
|
||||||
|
-moz-box-flex-group: 2;
|
||||||
|
box-flex-group: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
-moz-box-pack: start;
|
||||||
|
box-pack: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
-moz-box-pack: end;
|
||||||
|
box-pack: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-moz-box-pack: center;
|
||||||
|
box-pack: center;
|
||||||
|
}
|
||||||
|
/* END hbox/vbox normalization from http://alex.dojotoolkit.org/2009/08/css-3-progress/ */
|
|
@ -0,0 +1,240 @@
|
||||||
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||||
|
- Version: MPL 1.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 Raindrop.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- Mozilla Messaging, Inc..
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Raindrop API</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="/0.3.4/rdapi/index.css">
|
||||||
|
<script src="/0.3.4/scripts/requireplugins-jquery.js" charset="utf-8"></script>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
/*global require: false */
|
||||||
|
require({
|
||||||
|
paths: {
|
||||||
|
'index': '/0.3.4/rdapi/scripts/index',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['index']
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="listing">
|
||||||
|
|
||||||
|
<div class="header">
|
||||||
|
<h1 id="topHeading">Raindrop API</h1>
|
||||||
|
<p>This is the Raindrop API explorer. Read the important <a href="#Notes">Notes</a> first.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="toc">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<div class="sectionContent">
|
||||||
|
<!-- The name attribute for Notes is added after we fill in the content,
|
||||||
|
otherwise Firefox has a weird box calculation problem. -->
|
||||||
|
<h1 class="section"><a id="NotesTitle" href="#Notes">Notes</a></h1>
|
||||||
|
|
||||||
|
<p><a href="http://en.wikipedia.org/wiki/JSON">JSON</a> is used for all API responses.
|
||||||
|
The request arguments are normally <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1">form-urlencoded</a>
|
||||||
|
arguments (<b>Content-Type: application/x-www-form-urlencoded; charset=UTF-8</b>), except
|
||||||
|
for APIs that only accept a request body. In those cases, the request body should be JSON,
|
||||||
|
and the Content-Type for the request should be <b>application/json; charset=UTF-8</b>. Note that UTF-8
|
||||||
|
should be used as the charset.</p>
|
||||||
|
|
||||||
|
<div class="method">
|
||||||
|
<h2><a id="StandardResponseTitle" href="#StandardResponse">Notes: Standard Response</a></h2>
|
||||||
|
<p>The success version of the Standard Response is used by a few APIs for success responses. Other APIs use
|
||||||
|
a specific success object that relates to the API. See the specific API call for more information.</p>
|
||||||
|
|
||||||
|
<p>The error version of the Standard Response is used by <b>all APIs</b> to indicate error responses.</p>
|
||||||
|
|
||||||
|
<p>A <b>success response</b> will be an object with the following properties (only used by some APIs):</p>
|
||||||
|
<ul>
|
||||||
|
<li><b>ids</b> (array): Any IDs affected by the API call. May be empty</li>
|
||||||
|
<li><b>result</b> (boolean): Value of true</li>
|
||||||
|
<li><b>error</b> (object): null</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>An <b>error response</b> will be an object with the following properties (this is the error response
|
||||||
|
returned from all APIs):</p>
|
||||||
|
<ul>
|
||||||
|
<li><b>ids</b> (array): Any IDs affected by the API call. May be empty</li>
|
||||||
|
<li><b>result</b> (object): null if the API call has an error</li>
|
||||||
|
<li><b>error</b> (object): An object with the following properties:
|
||||||
|
<ul>
|
||||||
|
<li><b>name</b> (string): an error type name</li>
|
||||||
|
<li><b>message</b> (string): An English description of the error</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="method">
|
||||||
|
<h2><a id="ConversationTitle" href="#Conversation">Notes: Conversation Object</a></h2>
|
||||||
|
<p class="required">TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="method">
|
||||||
|
<h2><a id="MessageTitle" href="#Message">Notes: Message Object</a></h2>
|
||||||
|
<p class="required">TODO</p>
|
||||||
|
</div>
|
||||||
|
<div class="method">
|
||||||
|
<h2><a id="AttachmentTitle" href="#Attachment">Notes: Attachment Object</a></h2>
|
||||||
|
<p class="required">TODO</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="play">
|
||||||
|
<p id="playInstructions">Use a "Try It" link to try an API in this area.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="apiCall" action="#">
|
||||||
|
<h3 class="apiUrl"></h3>
|
||||||
|
<select class="apiUrlExpand hidden">
|
||||||
|
<option value=''>Change URL</option>
|
||||||
|
<ul class="apiUrlChoices hidden">
|
||||||
|
</ul>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<div class="parameterUrl hidden">
|
||||||
|
<h4>URL Parameters</h4>
|
||||||
|
<table>
|
||||||
|
<tbody class="urlParams"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="request">
|
||||||
|
<h4>Request Parameters</h4>
|
||||||
|
<table>
|
||||||
|
<tbody class="requestParams"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="body">
|
||||||
|
<h4>Request Body</h4>
|
||||||
|
<textarea class="requestBody"></textarea>
|
||||||
|
</div>
|
||||||
|
<button name="submit">Submit</button>
|
||||||
|
<button class="apiCallClose">close</button>
|
||||||
|
<div class="output"></div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="methodContent template" id="methodContent">
|
||||||
|
<p>{^doc}</p>
|
||||||
|
|
||||||
|
{is(routes.length) [}
|
||||||
|
<div class="section">
|
||||||
|
<h3>URL</h3>
|
||||||
|
<ul>
|
||||||
|
{routes [}
|
||||||
|
<li>{}</li>
|
||||||
|
{]}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
|
||||||
|
{and(urlargs, urlargs.length) [}
|
||||||
|
<div class="section">
|
||||||
|
<h3>URL Arguments</h3>
|
||||||
|
<ul>
|
||||||
|
{urlargs[}
|
||||||
|
<li><b class="{required [}required{]}">{name}</b> ({type}): {doc}</li>
|
||||||
|
{]}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
|
||||||
|
{and(queryargs, queryargs.length) [}
|
||||||
|
<div class="section">
|
||||||
|
<h3>Parameters</h3>
|
||||||
|
<ul>
|
||||||
|
{queryargs[}
|
||||||
|
<li><b class="{required [}required{]}">{name}</b> ({type}): {doc}</li>
|
||||||
|
{]}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
|
||||||
|
{is(body) [}
|
||||||
|
<div class="section">
|
||||||
|
{body [}
|
||||||
|
<h3>Request Body <span class="type">({type})</span></h3>
|
||||||
|
<p>{doc}</p>
|
||||||
|
{]}
|
||||||
|
|
||||||
|
{examplebody [}
|
||||||
|
<b>Example</b>:
|
||||||
|
<pre class="sampleBodyPre">{prettyJson(_)}</pre>
|
||||||
|
{]}
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
|
||||||
|
{response [}
|
||||||
|
<div class="section">
|
||||||
|
<h3>Response <span class="type">({type})</span></h3>
|
||||||
|
<p>{^addApiHyperlinks(doc)}</p>
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tocItem template" id="sectionToc">
|
||||||
|
<a class="sectionToc" href="#{section}">{section}</a>
|
||||||
|
{methods [}
|
||||||
|
<a class="methodToc" href="#{link}">{name}</a>
|
||||||
|
{]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sectionContent template" id="sectionContent">
|
||||||
|
<h1 class="section"><a href="#{section}" name="{section}">{section}</a></h1>
|
||||||
|
<p>{^doc}</p>
|
||||||
|
{methods [}
|
||||||
|
<div class="method">
|
||||||
|
<a class="try" href="#try:{link}">Try It!</a>
|
||||||
|
<h2><a href="#{link}" name="{link}">{section}: {name}</a></h2>
|
||||||
|
{^content}
|
||||||
|
</div>
|
||||||
|
{]}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="jsonResult template" id="jsonResult">
|
||||||
|
{#jsonBranch}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script class="template" id="jsonBranch" type="text/template">
|
||||||
|
{. _rdApiType getType(_)}
|
||||||
|
{eq(_rdApiType, 'object') [}
|
||||||
|
<span class="brace">{</span> <button class="expander">▼</button> <ul class="object">
|
||||||
|
{eachProp(_) [}
|
||||||
|
<li><span class="prop">{prop}</span> : {#jsonBranch value}</li>
|
||||||
|
{]}
|
||||||
|
</ul> <span class="brace">}</span>
|
||||||
|
{] eq(_rdApiType, 'array') [}
|
||||||
|
<span class="bracket">[</span> <button class="expander">▼</button> <ol class="array">
|
||||||
|
{_ [}
|
||||||
|
<li>{#jsonBranch}</li>
|
||||||
|
{]}
|
||||||
|
</ol> <span class="bracket">]</span>
|
||||||
|
{] [}
|
||||||
|
<span class="value">{formatSimpleType(_)}</span>
|
||||||
|
{]}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,504 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
'use strict';
|
||||||
|
/*jslint plusplus: false, regexp: false */
|
||||||
|
/*global require: false, define: false, location: true, setTimeout: false,
|
||||||
|
alert: false, window: false, document: false */
|
||||||
|
|
||||||
|
define([ 'jquery', 'rdapi', 'blade/object', 'blade/jig'],
|
||||||
|
function ($, rdapi, object, jig) {
|
||||||
|
|
||||||
|
var docs, urlSection, toc = [],
|
||||||
|
urlParamRegExp = /\{([^\}]+)\}/g,
|
||||||
|
fragLinkRegExp = /#StandardResponse|#Attachment|#Message|#Conversation/g,
|
||||||
|
apiLinks = {
|
||||||
|
'#StandardResponse': 'Standard Response',
|
||||||
|
'#Attachment': 'Attachment',
|
||||||
|
'#Message': 'Message',
|
||||||
|
'#Conversation': 'Conversation'
|
||||||
|
};
|
||||||
|
|
||||||
|
//Add a pretty JSON method for use in templates
|
||||||
|
jig.addFn({
|
||||||
|
prettyJson: function (text) {
|
||||||
|
return JSON.stringify(JSON.parse(text), null, " ");
|
||||||
|
},
|
||||||
|
addApiHyperlinks: function (text) {
|
||||||
|
var output = '', startIndex = 0, match;
|
||||||
|
fragLinkRegExp.lastIndex = 0;
|
||||||
|
while ((match = fragLinkRegExp.exec(text))) {
|
||||||
|
match = match[0];
|
||||||
|
output += jig.htmlEscape(text.substring(startIndex, fragLinkRegExp.lastIndex - match.length));
|
||||||
|
output += '<a href="' + match + '">' + apiLinks[match] + '</a>';
|
||||||
|
startIndex = fragLinkRegExp.lastIndex;
|
||||||
|
}
|
||||||
|
if (startIndex < text.length - 1) {
|
||||||
|
output += jig.htmlEscape(text.substring(startIndex, text.length));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
getType: function (it) {
|
||||||
|
if (require.isArray(it)) {
|
||||||
|
return 'array';
|
||||||
|
} else if (typeof it === "object" && it !== undefined && it !== null) {
|
||||||
|
return 'object';
|
||||||
|
} else {
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatSimpleType: function (it) {
|
||||||
|
if (it === null) {
|
||||||
|
return 'null';
|
||||||
|
} else if (it === 0) {
|
||||||
|
return '0';
|
||||||
|
} else if (it === undefined) {
|
||||||
|
return 'undefined';
|
||||||
|
} else if (it === true) {
|
||||||
|
return 'true';
|
||||||
|
} else if (it === false) {
|
||||||
|
return 'false';
|
||||||
|
} else {
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Array sorting method for method entries. Separated as a distinct
|
||||||
|
//function to make JSLint happy.
|
||||||
|
function methodSort(a, b) {
|
||||||
|
return a.name > b.name ? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashUpdated() {
|
||||||
|
//Hmm, an overflow div does not jump if the hash is changed, as in
|
||||||
|
//a back/forward button press, so force it.
|
||||||
|
var hash = location.href.split('#')[1] || '',
|
||||||
|
listingNode = $('#listing')[0],
|
||||||
|
targetNode;
|
||||||
|
|
||||||
|
if (hash) {
|
||||||
|
targetNode = $('[name="' + hash + '"]')[0];
|
||||||
|
if (!targetNode) {
|
||||||
|
if (hash.indexOf('%') !== -1) {
|
||||||
|
//Try unescaping the URL.
|
||||||
|
hash = decodeURIComponent(hash);
|
||||||
|
targetNode = $('[name="' + hash + '"]')[0];
|
||||||
|
} else {
|
||||||
|
//Try escaping it
|
||||||
|
hash = encodeURIComponent(hash);
|
||||||
|
targetNode = $('[name="' + hash + '"]')[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
if (targetNode) {
|
||||||
|
listingNode.scrollTop = listingNode.scrollTop + targetNode.getBoundingClientRect().top;
|
||||||
|
} else {
|
||||||
|
listingNode.scrollTop = 0;
|
||||||
|
}
|
||||||
|
}, 15);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateApiUrl(form, url) {
|
||||||
|
var apiUrl = form.find('.apiUrl'),
|
||||||
|
parameterUrl = form.find('.parameterUrl'),
|
||||||
|
match, urlParam, urlParams = '', urlParamObj;
|
||||||
|
|
||||||
|
//Show the API URL
|
||||||
|
apiUrl.html(url).removeClass('hidden');
|
||||||
|
parameterUrl.addClass('hidden');
|
||||||
|
|
||||||
|
//If the URL has arguments in its path, show options for it.
|
||||||
|
if (url.indexOf('{') !== -1) {
|
||||||
|
//Put in the parameterized URL and attach the source
|
||||||
|
//URL as a property on the DOM node for better perf
|
||||||
|
parameterUrl
|
||||||
|
.removeClass('hidden')
|
||||||
|
.find('.editApiUrl')
|
||||||
|
.remove()
|
||||||
|
.end()
|
||||||
|
.prepend('<input type="text" class="editApiUrl" value="' + url + '">')[0]
|
||||||
|
.apiUrl = url;
|
||||||
|
|
||||||
|
//Hide the normal h2 title
|
||||||
|
apiUrl.addClass('hidden');
|
||||||
|
|
||||||
|
//Parse out the fields in play
|
||||||
|
urlParamRegExp.lastIndex = 0;
|
||||||
|
while ((match = urlParamRegExp.exec(url))) {
|
||||||
|
urlParam = match[1];
|
||||||
|
urlParamObj = form[0].raindropApiMethod.urlargs && form[0].raindropApiMethod.urlargs[urlParam];
|
||||||
|
|
||||||
|
urlParams += '<tr><td class="urlParamName">' + urlParam + '</td><td class="urlParamValue">';
|
||||||
|
|
||||||
|
if (urlParamObj && urlParamObj.allowed) {
|
||||||
|
urlParams += '<select class="urlParamSelect" name="' + urlParam + '">' +
|
||||||
|
'<option value=""></option>';
|
||||||
|
urlParamObj.allowed.forEach(function (value) {
|
||||||
|
urlParams += '<option value="' + value + '">' + value + '</option>';
|
||||||
|
});
|
||||||
|
urlParams += '</select>';
|
||||||
|
} else {
|
||||||
|
urlParams += '<input type="text" class="urlParam" name="' + urlParam + '">';
|
||||||
|
}
|
||||||
|
|
||||||
|
urlParams += '</td></tr>';
|
||||||
|
}
|
||||||
|
form.find('.urlParams').html(urlParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delegated event handler that handles changes to URL arg fields, both input text ones,
|
||||||
|
//and select elements.
|
||||||
|
function changeApiUrl(evt) {
|
||||||
|
//Handle key ups for modifying URL parameters
|
||||||
|
//Only do an update on a timed delay, so that
|
||||||
|
//the DOM is not beaten up for each key stroke.
|
||||||
|
if (!urlSection) {
|
||||||
|
urlSection = $(evt.target).parents('.parameterUrl');
|
||||||
|
setTimeout(function () {
|
||||||
|
var apiUrl = urlSection[0].apiUrl;
|
||||||
|
|
||||||
|
urlSection.find('.urlParam, .urlParamSelect').each(function (i, node) {
|
||||||
|
var value = node.value.trim();
|
||||||
|
if (value) {
|
||||||
|
apiUrl = apiUrl.replace('{' + node.name + '}', value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Update the final URL
|
||||||
|
urlSection.find('.editApiUrl').val(apiUrl);
|
||||||
|
|
||||||
|
urlSection = null;
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCsrfToken() {
|
||||||
|
var token = /csrf=([^\; ]+)/.exec(document.cookie);
|
||||||
|
return token && token[1] ? token[1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdapi('docs', {
|
||||||
|
success: function (json) {
|
||||||
|
var prop, methodName, apiSection, methods, method, tocItem, obj,
|
||||||
|
i, route, parts, urlParam;
|
||||||
|
|
||||||
|
docs = json;
|
||||||
|
|
||||||
|
//TOC is by API section and method name, build it up,
|
||||||
|
//as well as the content that goes for each section.
|
||||||
|
for (prop in docs) {
|
||||||
|
if (docs.hasOwnProperty(prop)) {
|
||||||
|
apiSection = docs[prop];
|
||||||
|
methods = apiSection.methods;
|
||||||
|
|
||||||
|
//Create the TOC item for this API section.
|
||||||
|
tocItem = {
|
||||||
|
section: prop,
|
||||||
|
doc: apiSection.doc.replace(/<h1[^<]*<\/h1>/g, ''),
|
||||||
|
value: apiSection,
|
||||||
|
methods: []
|
||||||
|
};
|
||||||
|
|
||||||
|
//Create a method section in the TOC as well as the content
|
||||||
|
//that shows up in the main document section.
|
||||||
|
for (methodName in methods) {
|
||||||
|
if (methods.hasOwnProperty(methodName)) {
|
||||||
|
method = methods[methodName];
|
||||||
|
|
||||||
|
//Create quick lookups for urlargs parameters
|
||||||
|
if (method.urlargs) {
|
||||||
|
method.urlargs.forEach(function (arg) {
|
||||||
|
method.urlargs[arg.name] = arg;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//Make sure the API routes are prefixed with /api
|
||||||
|
if (method.routes) {
|
||||||
|
for (i = 0; (route = method.routes[i]); i++) {
|
||||||
|
//For any URL methods, if only one valid value,
|
||||||
|
//then just fix it to that value. Thinking mostly
|
||||||
|
//of contacts API where @{user} is normally just @me
|
||||||
|
parts = route.split('/');
|
||||||
|
parts.forEach(function (part, j) {
|
||||||
|
urlParamRegExp.lastIndex = 0;
|
||||||
|
parts[j] = part.replace(urlParamRegExp, function (match, p1) {
|
||||||
|
if (method.urlargs) {
|
||||||
|
urlParam = method.urlargs[p1];
|
||||||
|
if (urlParam && urlParam.allowed && urlParam.allowed.length === 1) {
|
||||||
|
return urlParam.allowed[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return match;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
route = parts.join('/');
|
||||||
|
|
||||||
|
if (route.indexOf('/api') !== 0) {
|
||||||
|
method.routes[i] = '/api' + route;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = object.create(method, [{
|
||||||
|
name: methodName,
|
||||||
|
link: encodeURIComponent(prop) + ":" + encodeURIComponent(methodName)
|
||||||
|
}]);
|
||||||
|
|
||||||
|
//Generate the HTML content for this section.
|
||||||
|
obj.content = jig(jig.cache('methodContent'), obj, {}).replace(/<h1[^<]*<\/h1>/g, '');
|
||||||
|
|
||||||
|
tocItem.methods.push(obj);
|
||||||
|
//Store a shortcut to reference the method by name.
|
||||||
|
tocItem.methods[methodName] = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sort the methods
|
||||||
|
tocItem.methods.sort(methodSort);
|
||||||
|
|
||||||
|
//Store a shortcut to reference the section by name.
|
||||||
|
toc[prop] = tocItem;
|
||||||
|
toc.push(tocItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sort the toc contents
|
||||||
|
toc.sort(function (a, b) {
|
||||||
|
return a.section > b.section ? 1 : -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
//Wait for page load to fill in the page content
|
||||||
|
$(function () {
|
||||||
|
var tocHtml = '',
|
||||||
|
html = '',
|
||||||
|
apiCallNode = $('.apiCall')[0],
|
||||||
|
play = $('#play');
|
||||||
|
|
||||||
|
//Remove the apiCall node from the DOM, since just used for clone operations.
|
||||||
|
apiCallNode.parentNode.removeChild(apiCallNode);
|
||||||
|
|
||||||
|
toc.forEach(function (tocItem) {
|
||||||
|
//Create TOC entry
|
||||||
|
tocHtml += jig(jig.cache('sectionToc'), tocItem, {});
|
||||||
|
|
||||||
|
//Create content entry
|
||||||
|
html += jig(jig.cache('sectionContent'), tocItem, {});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#toc").append(tocHtml);
|
||||||
|
$("#content").append(html);
|
||||||
|
|
||||||
|
//Add the name attributes to static sections here instead of the HTML
|
||||||
|
//to avoid a weird box sizing issue in Firefox.
|
||||||
|
['Notes', 'Conversation', 'Message', 'Attachment'].forEach(function (name) {
|
||||||
|
document.getElementById(name + 'Title').setAttribute('name', name);
|
||||||
|
});
|
||||||
|
|
||||||
|
//If have a location hash, then navigate to it now, since the links for
|
||||||
|
//all TOC values have been inserted.
|
||||||
|
hashUpdated();
|
||||||
|
window.addEventListener('hashchange', hashUpdated, false);
|
||||||
|
|
||||||
|
$('body')
|
||||||
|
//Handle the Try links
|
||||||
|
.delegate('.try', 'click', function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
//Get the API container
|
||||||
|
var form = $(apiCallNode.cloneNode(true)).appendTo('#play'),
|
||||||
|
params = '',
|
||||||
|
linkParts = evt.target.href.split("#")[1].split(':'),
|
||||||
|
method = toc[linkParts[1]].methods[decodeURIComponent(linkParts[2])],
|
||||||
|
routes = method.routes,
|
||||||
|
apiUrl = routes && routes[0] || '',
|
||||||
|
routeChoices = '';
|
||||||
|
|
||||||
|
//Put the API data structure on the form, for ease of referencing later.
|
||||||
|
form[0].raindropApiMethod = method;
|
||||||
|
|
||||||
|
//If more than one route, give a choice
|
||||||
|
if (routes && routes.length > 1) {
|
||||||
|
routes.forEach(function (route) {
|
||||||
|
routeChoices += '<option value="' + route + '" class="apiUrlChoice">' + route + '</option>';
|
||||||
|
});
|
||||||
|
|
||||||
|
form.find('.apiUrlExpand')
|
||||||
|
.removeClass('hidden')
|
||||||
|
.append(routeChoices);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateApiUrl(form, apiUrl);
|
||||||
|
|
||||||
|
//Request options
|
||||||
|
if (!method.queryargs || !method.queryargs.length) {
|
||||||
|
form.find('.request').addClass('hidden');
|
||||||
|
} else {
|
||||||
|
method.queryargs.forEach(function (arg) {
|
||||||
|
params += '<tr><td class="paramName">' + arg.name + '</td><td class="paramValue">';
|
||||||
|
|
||||||
|
if (arg.allowed) {
|
||||||
|
params += '<select name="' + arg.name + '">' +
|
||||||
|
'<option value=""></option>';
|
||||||
|
|
||||||
|
arg.allowed.forEach(function (value) {
|
||||||
|
params += '<option value="' + value + '">' + value + '</option>';
|
||||||
|
});
|
||||||
|
params += '</select>';
|
||||||
|
} else {
|
||||||
|
params += '<input type="text" name="' + arg.name + '">';
|
||||||
|
}
|
||||||
|
|
||||||
|
params += '</td></tr>';
|
||||||
|
});
|
||||||
|
form.find('.requestParams').html(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Request Body
|
||||||
|
if (!method.body) {
|
||||||
|
form.find('.body').addClass('hidden');
|
||||||
|
} else {
|
||||||
|
if (method.examplebody) {
|
||||||
|
form.find('.requestBody').val(method.examplebody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Make sure the new form is visible.
|
||||||
|
play[0].scrollTop = play[0].scrollHeight;
|
||||||
|
|
||||||
|
})
|
||||||
|
.delegate('.apiUrlExpand', 'change', function (evt) {
|
||||||
|
//Update the API URL choice.
|
||||||
|
var item = $(evt.target),
|
||||||
|
url = item.val(),
|
||||||
|
form = item.parents('form').first();
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
updateApiUrl(form, url);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.delegate('.urlParam', 'keyup', changeApiUrl)
|
||||||
|
.delegate('.urlParamSelect', 'change', changeApiUrl)
|
||||||
|
//Handle play form submissions.
|
||||||
|
.delegate('.apiCall', 'submit', function (evt) {
|
||||||
|
var form = $(evt.target),
|
||||||
|
method = form[0].raindropApiMethod,
|
||||||
|
inputs = form.find('.requestParams input, .requestParams select'),
|
||||||
|
url = form.find('.apiUrl').html(),
|
||||||
|
editableUrl = form.find('.editApiUrl'),
|
||||||
|
requestBody = form.find('.requestBody').val().trim(),
|
||||||
|
data = {},
|
||||||
|
options, csrfToken;
|
||||||
|
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
//If there was a parameterized URL, favor that
|
||||||
|
if (!form.find('.parameterUrl').hasClass('hidden') && editableUrl.length) {
|
||||||
|
url = editableUrl.val().trim();
|
||||||
|
if (url.indexOf('{') !== -1) {
|
||||||
|
alert('Please edit URL parameters to make a valid URL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Put together the request attributes.
|
||||||
|
inputs.each(function (i, node) {
|
||||||
|
var value = $(node).val();
|
||||||
|
if (value) {
|
||||||
|
data[node.name] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//If a request body, then favor that for the data
|
||||||
|
if (method.body && requestBody) {
|
||||||
|
if (inputs.length) {
|
||||||
|
//Already have some data, need to clear
|
||||||
|
//it out, add it to the URL as query args
|
||||||
|
//to the URL. This is actually a bit goofy,
|
||||||
|
//should just have all query args or all
|
||||||
|
//body args. prefs/set is one API that goes here.
|
||||||
|
url += (url.indexOf('?') === -1 ? '?' : '&') +
|
||||||
|
$.param(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = requestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
options = {
|
||||||
|
type: 'POST',
|
||||||
|
url: url,
|
||||||
|
data: data,
|
||||||
|
processData: !method.body,
|
||||||
|
contentType: (method.body ?
|
||||||
|
'application/json; charset=UTF-8' :
|
||||||
|
'application/x-www-form-urlencoded; charset=UTF-8'),
|
||||||
|
success: function (data, textStatus, xhr) {
|
||||||
|
form.find('.output').html(jig.render(jig.cache('jsonResult'), data));
|
||||||
|
},
|
||||||
|
error: function (xhr, textStatus, errorThrown) {
|
||||||
|
form.find('.output').html(jig.render(jig.cache('jsonResult'), {
|
||||||
|
ERROR: xhr.responseText
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
csrfToken = getCsrfToken();
|
||||||
|
if (csrfToken) {
|
||||||
|
options.beforeSend = function (xhr) {
|
||||||
|
xhr.setRequestHeader('X-CSRF', csrfToken);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//Construct the data call.
|
||||||
|
$.ajax(options);
|
||||||
|
})
|
||||||
|
//Handle close action for an API Call form
|
||||||
|
.delegate('form .apiCallClose', 'click', function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
$(evt.target).parents('form').remove();
|
||||||
|
})
|
||||||
|
//Handle expanding and closing of sections in the JSON response
|
||||||
|
//for API calls
|
||||||
|
.delegate('.expander', 'click', function (evt) {
|
||||||
|
var button = $(evt.target),
|
||||||
|
listNode = button.next('ul,ol')[0];
|
||||||
|
if (button.hasClass('closed')) {
|
||||||
|
listNode.style.display = '';
|
||||||
|
button.removeClass('closed');
|
||||||
|
button.html('▼');
|
||||||
|
} else {
|
||||||
|
listNode.style.display = 'none';
|
||||||
|
button.addClass('closed');
|
||||||
|
button.html('►');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
error: function (xhr, textStatus, errorThrown) {
|
||||||
|
$('#content').html(jig.htmlEscape(xhr.responseText));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,2 @@
|
||||||
|
User-agent: *
|
||||||
|
Disallow: /api
|
|
@ -0,0 +1,241 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint plusplus: false, indent: 2 */
|
||||||
|
/*global require: false, define: false, window: false, setTimeout: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'jquery', 'blade/object', 'blade/fn', 'module', 'dispatch',
|
||||||
|
'text!AutoCompleteRefresh.html'],
|
||||||
|
function ($, object, fn, module, dispatch,
|
||||||
|
refreshHtml) {
|
||||||
|
|
||||||
|
function split(val) {
|
||||||
|
return val.split(/,\s*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractLast(term) {
|
||||||
|
return split(term).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return object(null, null, {
|
||||||
|
className: module.id.replace('/', '-'),
|
||||||
|
|
||||||
|
refreshShowing: false,
|
||||||
|
askRefresh: true,
|
||||||
|
|
||||||
|
init: function (node, contactService) {
|
||||||
|
this.dom = $(node);
|
||||||
|
this.attachedWidget = false;
|
||||||
|
this.acOptions = [];
|
||||||
|
|
||||||
|
// Listen for changes to the contacts.
|
||||||
|
contactService.notify(fn.bind(this, this.attachAutoComplete));
|
||||||
|
|
||||||
|
this.contactService = contactService;
|
||||||
|
|
||||||
|
dispatch.sub('optionsChanged', fn.bind(this, function (data) {
|
||||||
|
// allow refetching contacts when a new page is shared.
|
||||||
|
this.askRefresh = true;
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the formatted autocomplete options and binds the
|
||||||
|
* autocomplete widget, but only on the first call.
|
||||||
|
*/
|
||||||
|
attachAutoComplete: function (contactService, contactList) {
|
||||||
|
contactList = contactList || [];
|
||||||
|
this.acOptions = [];
|
||||||
|
|
||||||
|
// Update the acOptions with formatted contact values.
|
||||||
|
contactList.forEach(fn.bind(this, function (contact) {
|
||||||
|
this.acOptions.push(contactService.formatContact(contact));
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (!this.attachedWidget) {
|
||||||
|
|
||||||
|
this.attachedWidget = true;
|
||||||
|
|
||||||
|
// jQuery UI autocomplete setup from the jQuery UI demo page
|
||||||
|
this.dom
|
||||||
|
// don't navigate away from the field on tab when selecting an item,
|
||||||
|
// or when tabbing to the refresh contacts button.
|
||||||
|
.bind("keydown", fn.bind(this, function (event) {
|
||||||
|
if (event.keyCode === $.ui.keyCode.ENTER) {
|
||||||
|
// Do not submit the form on enter in the autocomplete field.
|
||||||
|
event.preventDefault();
|
||||||
|
} else if (event.keyCode === $.ui.keyCode.TAB) {
|
||||||
|
if (this.dom.data("autocomplete").menu.active) {
|
||||||
|
//autocomplete is up.
|
||||||
|
event.preventDefault();
|
||||||
|
this.dom.autocomplete().select();
|
||||||
|
} else if (this.open) {
|
||||||
|
// select the first item in the autocomplete.
|
||||||
|
var item = this.dom.autocomplete('widget').find('li');
|
||||||
|
this.dom.data("autocomplete").menu.active = item;
|
||||||
|
|
||||||
|
this.dom.autocomplete().select();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// close out the refresh UI immediately so user can see the
|
||||||
|
// rest of the input form.
|
||||||
|
if (this.refreshShowing) {
|
||||||
|
this.hideRefresh();
|
||||||
|
}
|
||||||
|
} else if (event.keyCode === $.ui.keyCode.DOWN && this.refreshShowing) {
|
||||||
|
// refresh contacts showing so focus on the refresh button.
|
||||||
|
event.preventDefault();
|
||||||
|
this.focusingOnRefresh = true;
|
||||||
|
this.refreshDom.find('button').focus();
|
||||||
|
} else if (event.keyCode === $.ui.keyCode.ESCAPE && this.refreshShowing) {
|
||||||
|
this.askRefresh = false;
|
||||||
|
this.hideRefresh();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.bind('blur', fn.bind(this, function (event) {
|
||||||
|
// be sure to close down the refresh UI if open, but do it
|
||||||
|
// on a timeout to allow button clicks in the UI. A bit hacky
|
||||||
|
// since it is a timing related thing.
|
||||||
|
if (this.refreshShowing && !this.focusingOnRefresh) {
|
||||||
|
setTimeout(fn.bind(this, function () {
|
||||||
|
this.hideRefresh();
|
||||||
|
this.focusingOnRefresh = false;
|
||||||
|
}), 500);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.autocomplete({
|
||||||
|
minLength: 0,
|
||||||
|
source: fn.bind(this, function (request, response) {
|
||||||
|
// delegate back to autocomplete, but extract the last term
|
||||||
|
this.filtered = $.ui.autocomplete.filter(this.acOptions, extractLast(request.term));
|
||||||
|
|
||||||
|
// give the user the option to refresh the contacts
|
||||||
|
// if no matches.
|
||||||
|
if (!this.filtered.length && this.askRefresh) {
|
||||||
|
setTimeout(fn.bind(this, this.showRefresh), 0);
|
||||||
|
} else if (this.refreshShowing) {
|
||||||
|
this.hideRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
response(this.filtered);
|
||||||
|
}),
|
||||||
|
focus: function () {
|
||||||
|
// prevent value inserted on focus
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
select: function (event, ui) {
|
||||||
|
var terms = split(this.value);
|
||||||
|
// remove the current input
|
||||||
|
terms.pop();
|
||||||
|
// add the selected item
|
||||||
|
terms.push(ui.item.value);
|
||||||
|
// add placeholder to get the comma-and-space at the end
|
||||||
|
terms.push("");
|
||||||
|
this.value = terms.join(", ");
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
open: fn.bind(this, function (event, ui) {
|
||||||
|
// Set the width of the autocomplete once shown.
|
||||||
|
if (!this.relatedWidth) {
|
||||||
|
this.determineRelatedWidth();
|
||||||
|
}
|
||||||
|
this.open = true;
|
||||||
|
this.dom.autocomplete('widget').width(this.relatedWidth);
|
||||||
|
}),
|
||||||
|
close: fn.bind(this, function (event, ui) {
|
||||||
|
this.open = false;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// account for a previous search waiting on a refresh.
|
||||||
|
if (this.waitingSearch) {
|
||||||
|
this.dom.autocomplete('search', this.waitingSearch);
|
||||||
|
this.dom.focus();
|
||||||
|
delete this.waitingSearch;
|
||||||
|
this.hideSpinner();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
determineRelatedWidth: function () {
|
||||||
|
// Make sure to set the size of the autocomplete to not be bigger
|
||||||
|
// than the input area it is bound to.
|
||||||
|
var widthNode = this.dom[0];
|
||||||
|
while (widthNode && (this.relatedWidth = widthNode.getBoundingClientRect().width) <= 0) {
|
||||||
|
widthNode = widthNode.parentNode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hideRefresh: function () {
|
||||||
|
this.refreshDom.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows UI to allow refreshing the contacts list.
|
||||||
|
*/
|
||||||
|
showRefresh: function () {
|
||||||
|
if (!this.relatedWidth) {
|
||||||
|
this.determineRelatedWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.refreshDom) {
|
||||||
|
this.refreshDom = $(refreshHtml)
|
||||||
|
.css({
|
||||||
|
width: this.relatedWidth + 'px'
|
||||||
|
})
|
||||||
|
.insertAfter(this.dom[0])
|
||||||
|
.find('button')
|
||||||
|
.bind('click', fn.bind(this, function (evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
this.waitingSearch = this.dom.val().trim();
|
||||||
|
this.showSpinner();
|
||||||
|
this.askRefresh = false;
|
||||||
|
this.contactService.fetch();
|
||||||
|
this.hideRefresh();
|
||||||
|
}))
|
||||||
|
.bind('blur', fn.bind(this, function (evt) {
|
||||||
|
this.hideRefresh();
|
||||||
|
}))
|
||||||
|
.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.refreshDom.show();
|
||||||
|
|
||||||
|
this.refreshShowing = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
hideSpinner: function () {
|
||||||
|
this.spinnerDom.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
showSpinner: function () {
|
||||||
|
if (!this.spinnerDom) {
|
||||||
|
this.spinnerDom = $('<div class="AutoCompleteSpinner"></div>')
|
||||||
|
.appendTo(this.dom[0].parentNode);
|
||||||
|
}
|
||||||
|
this.spinnerDom.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
<div class="AutoCompleteRefresh">No matches. <button tabindex="-1" class="refresh">Refresh Contacts</button></div>
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint plusplus: false, indent: 2 */
|
||||||
|
/*global require: false, define: false, window: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'jquery', 'blade/object', 'blade/fn', 'dispatch', 'rdapi', 'accounts'],
|
||||||
|
function ($, object, fn, dispatch, rdapi, accounts) {
|
||||||
|
|
||||||
|
var Contacts;
|
||||||
|
|
||||||
|
Contacts = object(null, null, {
|
||||||
|
init: function (svc, svcAccount) {
|
||||||
|
this.svc = svc;
|
||||||
|
this.svcAccount = svcAccount;
|
||||||
|
|
||||||
|
this.callbacks = [];
|
||||||
|
this.lastUpdated = this.fromStore().lastUpdated;
|
||||||
|
// Time check is one day.
|
||||||
|
this.timeCheck = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// listen for changes in the options, and if a greater than a day,
|
||||||
|
// refresh the contacts.
|
||||||
|
this.optionsChangeSub = dispatch.sub('optionsChanged', fn.bind(this, function (options) {
|
||||||
|
if (this.needFetch()) {
|
||||||
|
this.fetch();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys this instance, not necessarily the data. For that, use
|
||||||
|
* clear().
|
||||||
|
* Used as an opportunity to unbind event listeners.
|
||||||
|
*/
|
||||||
|
destroy: function () {
|
||||||
|
dispatch.unsub('optionsChanged', this.optionsChangeSub);
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function () {
|
||||||
|
var acct = this.svcAccount;
|
||||||
|
accounts.setData(acct.domain, acct.userid, acct.username, 'contacts');
|
||||||
|
},
|
||||||
|
|
||||||
|
needFetch: function () {
|
||||||
|
return !this.lastUpdated || (new Date()).getTime() - this.lastUpdated > this.timeCheck;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves stored contacts. Should only be used internally or by subclasses.
|
||||||
|
*/
|
||||||
|
fromStore: function () {
|
||||||
|
var acct = this.svcAccount;
|
||||||
|
return accounts.getData(acct.domain, acct.userid, acct.username, 'contacts') || {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves contacts to storage. Should only be used internally or by
|
||||||
|
* subclasses.
|
||||||
|
*
|
||||||
|
* @param {Object} data an object with a "list" property which is this
|
||||||
|
* list of contacts to store.
|
||||||
|
*/
|
||||||
|
toStore: function (data) {
|
||||||
|
var acct = this.svcAccount;
|
||||||
|
|
||||||
|
if (!data.lastUpdated) {
|
||||||
|
data.lastUpdated = this.lastUpdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
accounts.setData(acct.domain, acct.userid, acct.username, 'contacts', data);
|
||||||
|
|
||||||
|
this.notifyCallbacks();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes any new names from a successful share into the autocomplete.
|
||||||
|
* By default, it does nothing, but subclasses may do something with it.
|
||||||
|
* @param {String} contactsText a comma-separated string of contacts that
|
||||||
|
* follow the format returned from findContact().
|
||||||
|
*/
|
||||||
|
incorporate: function (contactsText) {
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify about changes to the autocomplete list. Can be async, so callback is needed.
|
||||||
|
* @param {Function} callback called when contacts are available.
|
||||||
|
* It will receive an array of contacts.
|
||||||
|
*/
|
||||||
|
notify: function (callback) {
|
||||||
|
this.callbacks.push(callback);
|
||||||
|
this.contacts = this.fromStore().list;
|
||||||
|
|
||||||
|
if (!this.contacts || this.needFetch()) {
|
||||||
|
this.fetch();
|
||||||
|
} else {
|
||||||
|
this.notifyCallbacks();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fetch: function () {
|
||||||
|
var acct = this.svcAccount,
|
||||||
|
svcData = accounts.getService(acct.domain, acct.userid, acct.username);
|
||||||
|
|
||||||
|
rdapi('contacts/' + acct.domain, {
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
username: acct.username,
|
||||||
|
userid: acct.userid,
|
||||||
|
startindex: 0,
|
||||||
|
maxresults: 500,
|
||||||
|
account: JSON.stringify(svcData)
|
||||||
|
},
|
||||||
|
//Only wait for 10 seconds, then give up.
|
||||||
|
timeout: 10000,
|
||||||
|
success: fn.bind(this, function (json) {
|
||||||
|
//Transform data to a form usable by the front end.
|
||||||
|
if (json && !json.error) {
|
||||||
|
var entries = json.result.entry;
|
||||||
|
|
||||||
|
this.contacts = this.getFormattedContacts(entries);
|
||||||
|
this.lastUpdated = (new Date()).getTime();
|
||||||
|
|
||||||
|
this.toStore({
|
||||||
|
list: this.contacts
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
error: fn.bind(this, function (xhr, textStatus, errorThrown) {
|
||||||
|
// does not matter what the error is, just eat it and hide
|
||||||
|
// the UI showing a wait.
|
||||||
|
this.notifyCallbacks();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
notifyCallbacks: function () {
|
||||||
|
this.callbacks.forEach(fn.bind(this, function (callback) {
|
||||||
|
callback(this, this.contacts);
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
findContact: function (to) {
|
||||||
|
var contactId = to;
|
||||||
|
|
||||||
|
(this.contacts || []).some(function (contact) {
|
||||||
|
if (contact.displayName === to) {
|
||||||
|
contactId = contact.email || contact.userid || contact.username;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return contactId;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates contact data from server into a format used on the client.
|
||||||
|
* @param {Array} entries
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
getFormattedContacts: function (entries) {
|
||||||
|
var data = [];
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (entry.accounts && entry.accounts.length) {
|
||||||
|
entry.accounts.forEach(function (account) {
|
||||||
|
data.push({
|
||||||
|
displayName: entry.displayName,
|
||||||
|
email: '',
|
||||||
|
userid: account.userid,
|
||||||
|
username: account.username
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a string that was created by formatContact to real IDs
|
||||||
|
* understood by the back-end API calls.
|
||||||
|
*
|
||||||
|
* @param {String} toText a comma-separated list of contacts.
|
||||||
|
* @returns {String} a comma-separated list of ID-based contacts.
|
||||||
|
*/
|
||||||
|
convert: function (toText) {
|
||||||
|
var newrecip = [],
|
||||||
|
result = '',
|
||||||
|
recip;
|
||||||
|
|
||||||
|
if (this.contacts) {
|
||||||
|
recip = toText.split(',');
|
||||||
|
recip.forEach(fn.bind(this, function (to) {
|
||||||
|
var contactId = this.findContact(to.trim());
|
||||||
|
if (contactId) {
|
||||||
|
newrecip.push(contactId);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newrecip.length > 0) {
|
||||||
|
result = newrecip.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the contact for display, such as for use in an autocomplete.
|
||||||
|
* Overridden by Contact overlays.
|
||||||
|
*/
|
||||||
|
formatContact: function (contact) {
|
||||||
|
return contact.displayName;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Contacts.modelVersion = '3';
|
||||||
|
|
||||||
|
return Contacts;
|
||||||
|
});
|
|
@ -0,0 +1,133 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint indent: 2, regexp: false */
|
||||||
|
/*global define: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'blade/object', 'Contacts', 'jquery', 'accounts', 'blade/fn'],
|
||||||
|
function (object, Contacts, $, accounts, fn) {
|
||||||
|
|
||||||
|
var bracketRegExp = /<([^>])+>/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the formatting of contacts and converting
|
||||||
|
* one of those formatted contacts into a user ID.
|
||||||
|
*/
|
||||||
|
return object(Contacts, null, function (parent) {
|
||||||
|
return {
|
||||||
|
formatContact: function (contact) {
|
||||||
|
var value = contact.displayName;
|
||||||
|
if (contact.email !== value) {
|
||||||
|
value += ' <' + contact.email + '>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
findContact: function (to) {
|
||||||
|
return to;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a to string is already in the contacts array.
|
||||||
|
* @param {String} to a plain email address (no name).
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
contains: function (to) {
|
||||||
|
return this.contacts.some(function (contact) {
|
||||||
|
return contact.email === to;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
incorporate: function (contactsText) {
|
||||||
|
var acct = this.svcAccount,
|
||||||
|
newContacts = [],
|
||||||
|
storedContacts,
|
||||||
|
contacts = contactsText.split(',');
|
||||||
|
|
||||||
|
contacts.forEach(fn.bind(this, function (contact) {
|
||||||
|
contact = contact.trim();
|
||||||
|
|
||||||
|
var match = bracketRegExp.exec(contact);
|
||||||
|
|
||||||
|
contact = (match && match[1]) || contact;
|
||||||
|
|
||||||
|
if (!this.contains(contact)) {
|
||||||
|
newContacts.push({
|
||||||
|
displayName: contact,
|
||||||
|
email: contact
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (newContacts.length) {
|
||||||
|
// update storage of manually entered contacts.
|
||||||
|
storedContacts = accounts.getData(acct.domain,
|
||||||
|
acct.userid,
|
||||||
|
acct.username,
|
||||||
|
'enteredContacts') || [];
|
||||||
|
|
||||||
|
storedContacts = storedContacts.concat(newContacts);
|
||||||
|
accounts.setData(acct.domain, acct.userid, acct.username,
|
||||||
|
'enteredContacts', storedContacts);
|
||||||
|
|
||||||
|
// update the master merged list of contacts.
|
||||||
|
this.contacts = this.contacts.concat(newContacts);
|
||||||
|
this.toStore({
|
||||||
|
list: this.contacts
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getFormattedContacts: function (entries) {
|
||||||
|
var data = [],
|
||||||
|
acct = this.svcAccount,
|
||||||
|
storedContacts = accounts.getData(acct.domain,
|
||||||
|
acct.userid,
|
||||||
|
acct.username,
|
||||||
|
'enteredContacts');
|
||||||
|
|
||||||
|
// convert server data to the right format.
|
||||||
|
entries.forEach(function (entry) {
|
||||||
|
if (entry.emails && entry.emails.length) {
|
||||||
|
entry.emails.forEach(function (email) {
|
||||||
|
var displayName = entry.displayName ? entry.displayName : email.value;
|
||||||
|
data.push({
|
||||||
|
displayName: displayName,
|
||||||
|
email: email.value
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// add in any manually saved email addresses.
|
||||||
|
if (storedContacts) {
|
||||||
|
data = data.concat(storedContacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint indent: 2 */
|
||||||
|
/*global define: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'blade/object', 'Contacts', 'jquery'],
|
||||||
|
function (object, Contacts, $) {
|
||||||
|
var idRegExp = /\@(\S+)/;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the formatting of contacts and converting
|
||||||
|
* one of those formatted contacts into a user ID.
|
||||||
|
*/
|
||||||
|
return object(Contacts, null, function (parent) {
|
||||||
|
return {
|
||||||
|
formatContact: function (contact) {
|
||||||
|
var value = '@' + contact.username;
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
findContact: function (to) {
|
||||||
|
var match = idRegExp.exec(to),
|
||||||
|
value = '',
|
||||||
|
name = (match && match[1]) || to;
|
||||||
|
if (name) {
|
||||||
|
(this.contacts || []).some(function (contact) {
|
||||||
|
if (contact.username === name) {
|
||||||
|
value = contact.userid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,83 @@
|
||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/* TODO: some of these styles, like text sizing/box sizing and colors/borders
|
||||||
|
need to be set in the app that includes a Select widget. */
|
||||||
|
.Select {
|
||||||
|
position:relative;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-right: 15px;
|
||||||
|
z-index: 100;
|
||||||
|
border: 1px solid #A6AFB6;
|
||||||
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) inset;
|
||||||
|
height: 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open {
|
||||||
|
overflow: visible;
|
||||||
|
padding-right: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select ul {
|
||||||
|
list-style: none;
|
||||||
|
z-index: 100;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open ul {
|
||||||
|
position: absolute;
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select li {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
padding: 0 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select li.selected {
|
||||||
|
display: block;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open li {
|
||||||
|
display: block;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open li.selected {
|
||||||
|
/* background-color: grey; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open li.selected:hover,
|
||||||
|
.Select.open li:hover {
|
||||||
|
color:white;
|
||||||
|
background-color: #535F6D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select .triangle {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 18px;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 2px;
|
||||||
|
z-index: 101;
|
||||||
|
color: #A6AFB6;
|
||||||
|
background-color: white;
|
||||||
|
background-image: url("/share/i/sprite.png");
|
||||||
|
background-position: center -362px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Select.open .triangle {
|
||||||
|
display: none;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<div class="{className}">
|
||||||
|
<input type="hidden" name="{name}" value="{value}">
|
||||||
|
<ul>
|
||||||
|
{options [}
|
||||||
|
<li data-value="{value}">{name}</li>
|
||||||
|
{]}
|
||||||
|
</ul>
|
||||||
|
<div class="triangle"></div>
|
||||||
|
</div>
|
|
@ -0,0 +1,206 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint indent: 2, */
|
||||||
|
/*global define: false, document: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'blade/object', 'blade/Widget', 'blade/array', 'jquery', 'module',
|
||||||
|
'text!./Select.html', 'text!./Select.css'],
|
||||||
|
function (object, Widget, array, $, module,
|
||||||
|
template, css) {
|
||||||
|
|
||||||
|
var className = module.id.replace(/\//g, '-'),
|
||||||
|
style = document.createElement('style'),
|
||||||
|
openSelect;
|
||||||
|
|
||||||
|
//Add the css to that page.
|
||||||
|
style.type = 'text/css';
|
||||||
|
//If class name is changed since this is an anonymous module, update the
|
||||||
|
//CSS classes.
|
||||||
|
if (className !== 'Select') {
|
||||||
|
css = css.replace(/\.Select/g, '.' + className);
|
||||||
|
}
|
||||||
|
style.textContent = css;
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(style);
|
||||||
|
|
||||||
|
//Set up event handlers.
|
||||||
|
$(function () {
|
||||||
|
$('body')
|
||||||
|
.delegate('.' + className + ' .triangle', 'click', function (evt) {
|
||||||
|
Widget.closest(module.id, evt, 'onTriangleClick');
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
})
|
||||||
|
.delegate('.' + className + ' li', 'click', function (evt) {
|
||||||
|
Widget.closest(module.id, evt, 'onOptionClick');
|
||||||
|
evt.preventDefault();
|
||||||
|
evt.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).bind('click', function (evt) {
|
||||||
|
if (openSelect) {
|
||||||
|
openSelect.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the widget.
|
||||||
|
* This widget assumes its member variables include the following
|
||||||
|
* properties (passed in on create of the widget)
|
||||||
|
*
|
||||||
|
* @param {Array} options: the options to show, with each option being
|
||||||
|
* an object with "name" and "value" properties.
|
||||||
|
* @param {String} name: the name to use for the form field.
|
||||||
|
* @param {Number} selectedIndex: the index of the options that should
|
||||||
|
* be selected.
|
||||||
|
*/
|
||||||
|
return object(Widget, null, function (parent) {
|
||||||
|
return {
|
||||||
|
moduleId: module.id,
|
||||||
|
className: className,
|
||||||
|
|
||||||
|
template: template,
|
||||||
|
|
||||||
|
onCreate: function () {
|
||||||
|
if (this.value) {
|
||||||
|
var index, value = this.value;
|
||||||
|
// Find the matching index for the value.
|
||||||
|
this.options.some(function (item, i) {
|
||||||
|
if (item.value === value) {
|
||||||
|
index = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
this.selectedIndex = index;
|
||||||
|
} else {
|
||||||
|
// No default value, work it out via selectedIndex if available.
|
||||||
|
this.selectedIndex = this.selectedIndex || 0;
|
||||||
|
this.value = this.options[this.selectedIndex].value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onRender: function () {
|
||||||
|
this.dom = $(this.node);
|
||||||
|
|
||||||
|
//Apply selected style.
|
||||||
|
$('li', this.node).eq(this.selectedIndex).addClass('selected');
|
||||||
|
},
|
||||||
|
|
||||||
|
destroy: function () {
|
||||||
|
delete this.dom;
|
||||||
|
parent(this, "destroy", arguments);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects an item based on its index.
|
||||||
|
*/
|
||||||
|
selectIndex: function (index) {
|
||||||
|
return this.val(this.options[index].value);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or set the value for the select. Uses the value for the option.
|
||||||
|
*/
|
||||||
|
val: function (newValue) {
|
||||||
|
if (newValue === undefined) {
|
||||||
|
// Get
|
||||||
|
return $('li.selected', this.node)[0].getAttribute('data-value');
|
||||||
|
} else {
|
||||||
|
// Set the value.
|
||||||
|
var liNode, ulNode, index;
|
||||||
|
|
||||||
|
// Find the li node that corresponds with the value.
|
||||||
|
array.to.apply(null, $('li', this.dom)).some(function (node, i) {
|
||||||
|
if (node.getAttribute('data-value') === newValue) {
|
||||||
|
liNode = node;
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectedIndex = index;
|
||||||
|
|
||||||
|
ulNode = liNode.parentNode;
|
||||||
|
|
||||||
|
// Find the index.
|
||||||
|
this.selectedIndex = array.to.apply(null, $('li', ulNode)).indexOf(liNode);
|
||||||
|
|
||||||
|
// Make sure the right node has the selected class
|
||||||
|
$('li', ulNode).removeClass('selected');
|
||||||
|
$(liNode).addClass('selected');
|
||||||
|
|
||||||
|
this.close();
|
||||||
|
|
||||||
|
this.dom.trigger('change');
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function () {
|
||||||
|
var liNode = $('li.selected', this.node)[0];
|
||||||
|
|
||||||
|
// Put the value in the hidden input
|
||||||
|
$('input', this.node).val(liNode.getAttribute('data-value'));
|
||||||
|
|
||||||
|
// Remove the open class.
|
||||||
|
this.dom.removeClass('open');
|
||||||
|
|
||||||
|
// Remove the artificial width
|
||||||
|
this.node.style.width = '';
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function () {
|
||||||
|
if (openSelect) {
|
||||||
|
openSelect.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the options will position absolute, give the Select
|
||||||
|
// width so that surrounding content does not collapse around it.
|
||||||
|
this.node.style.width = this.node.getBoundingClientRect().width + 'px';
|
||||||
|
|
||||||
|
this.dom.addClass('open');
|
||||||
|
openSelect = this;
|
||||||
|
},
|
||||||
|
|
||||||
|
onTriangleClick: function (evt) {
|
||||||
|
this.open();
|
||||||
|
},
|
||||||
|
|
||||||
|
onOptionClick: function (evt) {
|
||||||
|
// Open the options if not already open.
|
||||||
|
if (!this.dom.hasClass('open')) {
|
||||||
|
this.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.val(evt.target.getAttribute('data-value'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint plusplus: false */
|
||||||
|
/*global require: false, define: false */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
define([ 'jquery', 'blade/object', 'blade/fn'],
|
||||||
|
function ($, object, fn) {
|
||||||
|
|
||||||
|
return object(null, null, {
|
||||||
|
init: function (node, countNode, limit) {
|
||||||
|
this.dom = $(node);
|
||||||
|
this.domPlaceholderText = this.dom[0].getAttribute('placeholder') || '';
|
||||||
|
this.countDom = $(countNode);
|
||||||
|
this.limit = limit;
|
||||||
|
this.dom.bind('keyup', fn.bind(this, 'checkCount'));
|
||||||
|
this.checkCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
checkCount: function () {
|
||||||
|
var value = this.dom[0].value,
|
||||||
|
count;
|
||||||
|
|
||||||
|
if (value.trim() === this.domPlaceholderText) {
|
||||||
|
value = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
count = this.limit - value.length;
|
||||||
|
if (count < 0) {
|
||||||
|
this.countDom.addClass("TextCountOver");
|
||||||
|
} else {
|
||||||
|
this.countDom.removeClass("TextCountOver");
|
||||||
|
}
|
||||||
|
this.countDom.text(count === this.limit ? '' : count);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateLimit: function (limit) {
|
||||||
|
this.limit = limit;
|
||||||
|
this.checkCount();
|
||||||
|
},
|
||||||
|
|
||||||
|
isOver: function () {
|
||||||
|
return this.dom[0].value.length > this.limit;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,404 @@
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.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 Raindrop.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Messaging, Inc..
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*jslint indent: 2, plusplus: false */
|
||||||
|
/*global require: false, define: false, window: false, location: true,
|
||||||
|
localStorage: false, opener: false, setTimeout: false */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define([ 'storage', 'dispatch', 'rdapi', 'services'],
|
||||||
|
function (storage, dispatch, rdapi, services) {
|
||||||
|
|
||||||
|
function isCacheMatch(cache, domain, userid, username) {
|
||||||
|
return cache.domain === domain &&
|
||||||
|
((userid && cache.userid === userid) ||
|
||||||
|
(username && cache.username === username));
|
||||||
|
}
|
||||||
|
|
||||||
|
function fromJson(value) {
|
||||||
|
if (value) {
|
||||||
|
value = JSON.parse(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var store = storage(), impl,
|
||||||
|
changeTypes = {
|
||||||
|
//localStorage is the most robust, since the change in localStorage
|
||||||
|
//can be listened to across windows.
|
||||||
|
|
||||||
|
'localStorage': {
|
||||||
|
|
||||||
|
accounts: function (ok, error) {
|
||||||
|
// accounts now simply provides existing accounts retreived during
|
||||||
|
// the oauth dances
|
||||||
|
var accountCache = fromJson(store.accountCache) || [],
|
||||||
|
serviceCache = fromJson(store.serviceCache);
|
||||||
|
|
||||||
|
if (!serviceCache) {
|
||||||
|
// fetch now, let the response call ok
|
||||||
|
// Set up serviceCache. This should only ever happen
|
||||||
|
// if the local store is cleared (e.g. first run, cleared cookies)
|
||||||
|
impl.fetch(ok, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceCache = serviceCache || [];
|
||||||
|
|
||||||
|
//Call ok callback with current knowledge. If there is a change in the
|
||||||
|
//account info, then the fetch will trigger changed event later.
|
||||||
|
if (ok) {
|
||||||
|
ok(accountCache, serviceCache);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function (account_data) {
|
||||||
|
// XXX TODO
|
||||||
|
// get the account and push it into localstore, don't overwrite, we
|
||||||
|
// get one account at a time here
|
||||||
|
// We write into accountCache to have account.fetch continue to work.
|
||||||
|
// We also write into serviceCache which will be used by api calls
|
||||||
|
// to send the auth keys
|
||||||
|
var accountCache = fromJson(store.accountCache) || [],
|
||||||
|
serviceCache = fromJson(store.serviceCache),
|
||||||
|
existing = false,
|
||||||
|
profile, p, a, acct;
|
||||||
|
|
||||||
|
// move the profile into accountCache
|
||||||
|
profile = account_data.profile;
|
||||||
|
for (p = 0; p < accountCache.length; p++) {
|
||||||
|
acct = accountCache[p].accounts[0];
|
||||||
|
if (isCacheMatch(acct, account_data.domain, account_data.userid,
|
||||||
|
account_data.username)) {
|
||||||
|
accountCache[p] = profile;
|
||||||
|
existing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!existing) {
|
||||||
|
accountCache.push(profile);
|
||||||
|
}
|
||||||
|
store.accountCache = JSON.stringify(accountCache);
|
||||||
|
|
||||||
|
// we store the entire object in serviceCache, at some point in the
|
||||||
|
// future we will remove accountCache
|
||||||
|
if (serviceCache) {
|
||||||
|
existing = false;
|
||||||
|
for (a = 0; a < serviceCache.length; a++) {
|
||||||
|
if (isCacheMatch(serviceCache[a], account_data.domain,
|
||||||
|
account_data.userid, account_data.username)) {
|
||||||
|
serviceCache[a] = account_data;
|
||||||
|
existing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
serviceCache = [];
|
||||||
|
}
|
||||||
|
if (!existing) {
|
||||||
|
serviceCache.push(account_data);
|
||||||
|
}
|
||||||
|
store.serviceCache = JSON.stringify(serviceCache);
|
||||||
|
impl.changed();
|
||||||
|
},
|
||||||
|
|
||||||
|
// remove this once there is time enough for all users
|
||||||
|
// to have been migrated over to the new cache.
|
||||||
|
fetch: function (ok, error) {
|
||||||
|
rdapi('account/get/full', {
|
||||||
|
success: function (json) {
|
||||||
|
if (json.error) {
|
||||||
|
json = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
store.serviceCache = JSON.stringify(json);
|
||||||
|
var accountCache = [], svc, p;
|
||||||
|
for (p = 0; p < json.length; p++) {
|
||||||
|
accountCache.push(json[p].profile);
|
||||||
|
|
||||||
|
// clear the contacts cache
|
||||||
|
// remove this clearCache call when 3.6 is removed.
|
||||||
|
svc = services.domains[json[p].domain];
|
||||||
|
svc.clearCache(store);
|
||||||
|
}
|
||||||
|
store.accountCache = JSON.stringify(accountCache);
|
||||||
|
if (ok) {
|
||||||
|
ok(accountCache, json);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: error || function () {}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
remove: function (domain, userid, username) {
|
||||||
|
var accountCache = fromJson(store.accountCache),
|
||||||
|
serviceCache = fromJson(store.serviceCache),
|
||||||
|
i, cache, a, p, s, svc;
|
||||||
|
|
||||||
|
if (serviceCache) {
|
||||||
|
for (i = 0; (cache = serviceCache[i]); i++) {
|
||||||
|
if (isCacheMatch(cache, domain, userid, username)) {
|
||||||
|
serviceCache.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.serviceCache = JSON.stringify(serviceCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eventually we will deprecate accountCache
|
||||||
|
if (accountCache) {
|
||||||
|
for (p = 0; p < accountCache.length; p++) {
|
||||||
|
s = accountCache[p].accounts;
|
||||||
|
for (a = 0; a < s.length; a++) {
|
||||||
|
if (isCacheMatch(s[a], domain, userid, username)) {
|
||||||
|
accountCache.splice(p, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
store.accountCache = JSON.stringify(accountCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear the contacts cache
|
||||||
|
svc = services.domains[domain];
|
||||||
|
|
||||||
|
// remove this clearCache call when 3.6 is removed.
|
||||||
|
svc.clearCache(store);
|
||||||
|
|
||||||
|
// Delete auxillary data.
|
||||||
|
impl.clearData(domain, userid, username);
|
||||||
|
|
||||||
|
impl.changed();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set auxillary data related to an account. Deleted when the account
|
||||||
|
* is deleted.
|
||||||
|
*/
|
||||||
|
setData: function (domain, userid, username, name, value) {
|
||||||
|
var key = [domain, userid, username].join('|') + 'Data',
|
||||||
|
data = fromJson(store[key]) || {};
|
||||||
|
|
||||||
|
if (value === undefined || value === null) {
|
||||||
|
delete data[name];
|
||||||
|
} else {
|
||||||
|
data[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
store[key] = JSON.stringify(data);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get auxillary data related to an account.
|
||||||
|
*/
|
||||||
|
getData: function (domain, userid, username, name) {
|
||||||
|
var key = [domain, userid, username].join('|') + 'Data',
|
||||||
|
data = fromJson(store[key]) || {};
|
||||||
|
|
||||||
|
return data ? data[name] : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears auxillary data related to an account. Deleted when the account
|
||||||
|
* is deleted.
|
||||||
|
*/
|
||||||
|
clearData: function (domain, userid, username) {
|
||||||
|
var key = [domain, userid, username].join('|') + 'Data';
|
||||||
|
delete store[key];
|
||||||
|
},
|
||||||
|
|
||||||
|
getService: function (domain, userid, username) {
|
||||||
|
var serviceCache = fromJson(store.serviceCache),
|
||||||
|
i, cache;
|
||||||
|
|
||||||
|
if (serviceCache) {
|
||||||
|
for (i = 0; (cache = serviceCache[i]); i++) {
|
||||||
|
if (isCacheMatch(cache, domain, userid, username)) {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
changed: function () {
|
||||||
|
store.accountChanged = (new Date()).getTime();
|
||||||
|
//Force the onchange events to occur. Sometimes the storage
|
||||||
|
//events do not fire?
|
||||||
|
if (opener && !opener.closed) {
|
||||||
|
dispatch.pub('accountsChanged', null, opener);
|
||||||
|
}
|
||||||
|
dispatch.pub('accountsChanged');
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange: function (action) {
|
||||||
|
//Listen to storage changes, and if a the accountChanged key
|
||||||
|
//changes, refresh.
|
||||||
|
var lastValue = store.accountChanged;
|
||||||
|
window.addEventListener('storage', function (evt) {
|
||||||
|
//Only refresh if the accounts were changed.
|
||||||
|
if (store.accountChanged !== lastValue) {
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
//Also use direct notification in case storage events fail.
|
||||||
|
dispatch.sub('accountsChanged', action);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//Some extensions mess with localStorage, so in that case, fall back to
|
||||||
|
//using dispatching.
|
||||||
|
'memory': {
|
||||||
|
|
||||||
|
accounts: function (ok, error) {
|
||||||
|
},
|
||||||
|
|
||||||
|
changed: function () {
|
||||||
|
//Use dispatching. Dispatch to current window, but also to an opener
|
||||||
|
//if available.
|
||||||
|
store.accountChanged = (new Date()).getTime();
|
||||||
|
|
||||||
|
if (opener) {
|
||||||
|
dispatch.pub('accountsChanged', null, opener);
|
||||||
|
}
|
||||||
|
dispatch.pub('accountsChanged');
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange: function (action) {
|
||||||
|
dispatch.sub('accountsChanged', action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
impl = changeTypes[storage.type];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the accounts. Can use a cached value.
|
||||||
|
* @param {Function} ok function to receive the account info.
|
||||||
|
* @param {Function} error function to call if an error.
|
||||||
|
*/
|
||||||
|
function accounts(ok, error) {
|
||||||
|
return impl.accounts(ok, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the accounts from a json account object.
|
||||||
|
* @param {Object} cookie object to update from
|
||||||
|
*/
|
||||||
|
accounts.update = function (account_data) {
|
||||||
|
impl.update(account_data);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an accounts from storage.
|
||||||
|
* @param {string} domain
|
||||||
|
* @param {string} userid
|
||||||
|
* @param {string} username
|
||||||
|
*/
|
||||||
|
accounts.remove = function (account, userid, username) {
|
||||||
|
impl.remove(account, userid, username);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch accounts stored on server.
|
||||||
|
* DEPRECATED, interim use for auto-adding accounts that
|
||||||
|
* users have already configured
|
||||||
|
*/
|
||||||
|
accounts.fetch = function (ok, error) {
|
||||||
|
impl.fetch(ok, error);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a full service account record
|
||||||
|
* @param {string} domain
|
||||||
|
* @param {string} userid
|
||||||
|
* @param {string} username
|
||||||
|
*/
|
||||||
|
accounts.getService = function (account, userid, username) {
|
||||||
|
return impl.getService(account, userid, username);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the account data. Use this when it is known that the server
|
||||||
|
* info is no longer valid/expired.
|
||||||
|
*/
|
||||||
|
accounts.clear = function () {
|
||||||
|
delete store.accountCache;
|
||||||
|
delete store.serviceCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets auxillary data associated with an account.
|
||||||
|
* @param {string} domain
|
||||||
|
* @param {string} userid
|
||||||
|
* @param {string} username
|
||||||
|
*/
|
||||||
|
accounts.setData = function (account, userid, username, name, value) {
|
||||||
|
return impl.setData(account, userid, username, name, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets auxillary data associated with an account.
|
||||||
|
* @param {string} domain
|
||||||
|
* @param {string} userid
|
||||||
|
* @param {string} username
|
||||||
|
*/
|
||||||
|
accounts.getData = function (account, userid, username, name) {
|
||||||
|
return impl.getData(account, userid, username, name);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets auxillary data associated with an account.
|
||||||
|
* @param {string} domain
|
||||||
|
* @param {string} userid
|
||||||
|
* @param {string} username
|
||||||
|
*/
|
||||||
|
accounts.clearData = function (account, userid, username) {
|
||||||
|
return impl.clearData(account, userid, username);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the cache of accounts has changed.
|
||||||
|
*/
|
||||||
|
accounts.changed = function () {
|
||||||
|
return impl.changed();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default action is to just reload.
|
||||||
|
*/
|
||||||
|
function defaultAction() {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to set up the action when accounts change.
|
||||||
|
* Call it with no args to get the default behavior, page reload.
|
||||||
|
*/
|
||||||
|
accounts.onChange = function (action) {
|
||||||
|
return impl.onChange(action || defaultAction);
|
||||||
|
};
|
||||||
|
|
||||||
|
return accounts;
|
||||||
|
});
|
|
@ -0,0 +1,147 @@
|
||||||
|
/**
|
||||||
|
* @license blade/Widget Copyright (c) 2010, The Dojo Foundation All Rights Reserved.
|
||||||
|
* Available via the MIT, GPL or new BSD license.
|
||||||
|
* see: http://github.com/jrburke/blade for details
|
||||||
|
*/
|
||||||
|
/*jslint plusplus: false, nomen: false */
|
||||||
|
/*global define: false, document */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parts of this taken from Dojo, in particular DOM work related to
|
||||||
|
* dojo._toDom()
|
||||||
|
*/
|
||||||
|
|
||||||
|
define([ 'require', './object', './jig', 'module'],
|
||||||
|
function (require, object, jig, module) {
|
||||||
|
|
||||||
|
var tempNode,
|
||||||
|
baseAttrName = 'data-' + module.id.replace(/\//g, '-') + '-' +
|
||||||
|
(Math.random() + '').replace(/\d\./, ''),
|
||||||
|
typeAttr = baseAttrName + '-wtype',
|
||||||
|
idAttr = baseAttrName + '-wid',
|
||||||
|
idCounter = 0,
|
||||||
|
registry = {},
|
||||||
|
|
||||||
|
Widget = object(null, null, {
|
||||||
|
template: null,
|
||||||
|
/**
|
||||||
|
* Creates a new instance. Should be called by any derived objects.
|
||||||
|
* data can have some special properties:
|
||||||
|
* parent: the parent node to
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
init: function (data, relNode, position) {
|
||||||
|
object.mixin(this, data, true);
|
||||||
|
|
||||||
|
//Start widget lifecycle
|
||||||
|
if (this.onCreate) {
|
||||||
|
this.onCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.template) {
|
||||||
|
this.node = this.render();
|
||||||
|
if (this.onRender) {
|
||||||
|
this.onRender(relNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relNode && this.node) {
|
||||||
|
if (position === 'before') {
|
||||||
|
relNode.parentNode.insertBefore(this.node, relNode);
|
||||||
|
} else if (position === 'after') {
|
||||||
|
relNode.parentNode.insertBefore(this.node, relNode.nextSibling);
|
||||||
|
} else if (position === 'prepend' && relNode.firstChild) {
|
||||||
|
relNode.insertBefore(this.node, relNode.firstChild);
|
||||||
|
} else {
|
||||||
|
relNode.appendChild(this.node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function (relativeNode) {
|
||||||
|
var doc, child, renderedNode, id;
|
||||||
|
if (this.template) {
|
||||||
|
//Normalize template by trimming whitespace.
|
||||||
|
this.template = this.template.trim();
|
||||||
|
|
||||||
|
doc = relativeNode && relativeNode.ownerDocument || document;
|
||||||
|
id = 'id' + idCounter++;
|
||||||
|
|
||||||
|
//Set up a temp node to hold template
|
||||||
|
if (!tempNode || tempNode.ownerDocument !== doc) {
|
||||||
|
tempNode = doc.createElement('div');
|
||||||
|
}
|
||||||
|
|
||||||
|
tempNode.innerHTML = this.templatize();
|
||||||
|
|
||||||
|
// one node shortcut => return the node itself
|
||||||
|
if (tempNode.childNodes.length === 1) {
|
||||||
|
renderedNode = tempNode.removeChild(tempNode.firstChild);
|
||||||
|
renderedNode.setAttribute(idAttr, id);
|
||||||
|
renderedNode.setAttribute(typeAttr, this.moduleId);
|
||||||
|
} else {
|
||||||
|
// return multiple nodes as a document fragment
|
||||||
|
renderedNode = doc.createDocumentFragment();
|
||||||
|
while ((child = tempNode.firstChild)) {
|
||||||
|
renderedNode.appendChild(child);
|
||||||
|
if (child.nodeType === 1) {
|
||||||
|
child.setAttribute(idAttr, id);
|
||||||
|
child.setAttribute(typeAttr, this.moduleId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._widgetId = id;
|
||||||
|
registry[id] = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderedNode;
|
||||||
|
},
|
||||||
|
|
||||||
|
templatize: function () {
|
||||||
|
var text = this.template,
|
||||||
|
cache = jig.cache(text) || jig.cache(text, text, this.jigOptions);
|
||||||
|
|
||||||
|
return jig.render(cache, this, this.jigOptions);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the widget. Derived objects should call this method
|
||||||
|
* after they do their destroy work. destroy is a nice time to
|
||||||
|
* clean up event handlers.
|
||||||
|
*/
|
||||||
|
destroy: function () {
|
||||||
|
if (this.node && this.node.parentNode) {
|
||||||
|
this.node.parentNode.removeChild(this.node);
|
||||||
|
}
|
||||||
|
delete this.node;
|
||||||
|
delete registry[this._widgetId];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Widget.closest = function (widgetType, evt, funcName) {
|
||||||
|
var refNode = evt.target,
|
||||||
|
widget;
|
||||||
|
|
||||||
|
//Walk up the list of nodes until a match with the type is found.
|
||||||
|
while (refNode) {
|
||||||
|
if (refNode.getAttribute(typeAttr) === widgetType) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
refNode = refNode.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refNode) {
|
||||||
|
widget = registry[refNode.getAttribute(idAttr)];
|
||||||
|
if (widget) {
|
||||||
|
widget[funcName](evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Widget.registry = registry;
|
||||||
|
|
||||||
|
return Widget;
|
||||||
|
});
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* @license blade/array Copyright (c) 2010, The Dojo Foundation All Rights Reserved.
|
||||||
|
* Available via the MIT, GPL or new BSD license.
|
||||||
|
* see: http://github.com/jrburke/blade for details
|
||||||
|
*/
|
||||||
|
/*jslint nomen: false, plusplus: false */
|
||||||
|
/*global define: false */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define([], function () {
|
||||||
|
var ostring = Object.prototype.toString,
|
||||||
|
ap = Array.prototype,
|
||||||
|
aps = ap.slice,
|
||||||
|
|
||||||
|
array = {
|
||||||
|
/**
|
||||||
|
* Determines if the input a function.
|
||||||
|
* @param {Object} it whatever you want to test to see if it is a function.
|
||||||
|
* @returns Boolean
|
||||||
|
*/
|
||||||
|
is: function (it) {
|
||||||
|
return ostring.call(it) === "[object Array]";
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array-like thing into a real array
|
||||||
|
* @param{ArrayLike} arrayLike something that looks like an array,
|
||||||
|
* has a length and can access members via indices.
|
||||||
|
* @returns {Array}
|
||||||
|
*/
|
||||||
|
to: function (arrayLike) {
|
||||||
|
return [].concat(aps.call(arguments, 0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return array;
|
||||||
|
});
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* @license blade/defer Copyright (c) 2010, The Dojo Foundation All Rights Reserved.
|
||||||
|
* Available via the MIT, GPL or new BSD license.
|
||||||
|
* see: http://github.com/jrburke/blade for details
|
||||||
|
*/
|
||||||
|
/*jslint nomen: false, plusplus: false */
|
||||||
|
/*global define: false */
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
define(['./fn', './dispatch'], function (fn, bladeDispatch) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an object representing a deferred action.
|
||||||
|
* @param {Function} [onCancel] optional function to call if the deferred
|
||||||
|
* action is canceled
|
||||||
|
* @param {Array} otherEventNames an array of event names to also allow
|
||||||
|
* sending and notifying on this type of deferred action. This allows you
|
||||||
|
* to express more complex interactions besides something that just indicates
|
||||||
|
* "ok", "error" or "cancel".
|
||||||
|
* @returns {Object} object representing the deferred action. It contains
|
||||||
|
* two properties:
|
||||||
|
* send: a function to send events. It takes a string name for the event,
|
||||||
|
* "ok", "error" or "cancel", and a value.
|
||||||
|
* listener: an object that only exposes an "ok", "error" and "cancel"
|
||||||
|
* functions that allow listening to those respective events. If otherEventNames
|
||||||
|
* specified other events, then there are listener registration functions
|
||||||
|
* for those event names too.
|
||||||
|
*/
|
||||||
|
function defer(onCancel, otherEventNames) {
|
||||||
|
var dfd = {},
|
||||||
|
sentName, i, evtName,
|
||||||
|
dispatch = bladeDispatch.make(),
|
||||||
|
makeCb = function (name) {
|
||||||
|
return function (obj, f) {
|
||||||
|
var cb = fn.bind(obj, f);
|
||||||
|
dispatch.onAfter(name, function (evt) {
|
||||||
|
return cb(evt.returnValue);
|
||||||
|
}, true);
|
||||||
|
return dfd.listener;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
//Set up the cancellation action if desired.
|
||||||
|
if (onCancel) {
|
||||||
|
dispatch.onAfter('cancel', function (evt) {
|
||||||
|
return onCancel();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dfd.send = function (name, value) {
|
||||||
|
//Do not allow sending more than one message for the deferred.
|
||||||
|
if (sentName) {
|
||||||
|
throw new Error('blade/defer object already sent event: ' + sentName);
|
||||||
|
}
|
||||||
|
sentName = name;
|
||||||
|
|
||||||
|
dispatch.send({
|
||||||
|
name: name,
|
||||||
|
args: [value],
|
||||||
|
persist: true
|
||||||
|
});
|
||||||
|
|
||||||
|
//If no error handlers on this deferred, be sure to at least
|
||||||
|
//log it to allow some sort of debugging.
|
||||||
|
if (name === 'error' &&
|
||||||
|
(!dispatch._dispatchAfterQ || ! dispatch._dispatchAfterQ.error) &&
|
||||||
|
defer.onErrorDefault) {
|
||||||
|
defer.onErrorDefault(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dfd;
|
||||||
|
};
|
||||||
|
|
||||||
|
dfd.listener = {
|
||||||
|
ok: makeCb('ok'),
|
||||||
|
error: makeCb('error'),
|
||||||
|
cancel: makeCb('cancel')
|
||||||
|
};
|
||||||
|
|
||||||
|
//Allow wiring up other event names
|
||||||
|
if (otherEventNames) {
|
||||||
|
for (i = 0; (evtName = otherEventNames[i]); i++) {
|
||||||
|
dfd.listener[evtName] = makeCb[evtName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
defer.onErrorDefault = function (err) {
|
||||||
|
throw err;
|
||||||
|
};
|
||||||
|
|
||||||
|
return defer;
|
||||||
|
});
|