Merge remote branch 'origin/master' into wosch
authorWolfram Schneider <wosch@indexdata.dk>
Tue, 28 Oct 2014 08:08:15 +0000 (08:08 +0000)
committerWolfram Schneider <wosch@indexdata.dk>
Tue, 28 Oct 2014 08:08:15 +0000 (08:08 +0000)
149 files changed:
.gitignore
LICENSE
Makefile
README
doc/.gitignore [deleted file]
doc/Makefile
doc/README.markdown [deleted file]
doc/index.markdown [new file with mode: 0644]
doc/mkws-developer.markdown
doc/mkws-doc.css
doc/mkws-manual.markdown
doc/tweak-html [new file with mode: 0755]
examples/apache2/mkws-examples
examples/apache2/mkws-examples-mike
examples/apache2/mkws-examples-mike-mac [new file with mode: 0644]
examples/htdocs/Makefile
examples/htdocs/async.html
examples/htdocs/auto-paratext-minimal.html
examples/htdocs/auto-paratext.html
examples/htdocs/auto.html
examples/htdocs/auto2.html
examples/htdocs/auto3.html
examples/htdocs/choose-target.html
examples/htdocs/dict.html
examples/htdocs/heikki-motd.html
examples/htdocs/heikki.html
examples/htdocs/images.html
examples/htdocs/index.html
examples/htdocs/intro.html
examples/htdocs/jakub.html
examples/htdocs/jasmine-cors-popup.html
examples/htdocs/jasmine-local-popup.html
examples/htdocs/jasmine-popup.html
examples/htdocs/jasmine-pp2.html
examples/htdocs/jasmine.html
examples/htdocs/language.html
examples/htdocs/local-auto.html
examples/htdocs/local-auto3.html
examples/htdocs/localauth.html
examples/htdocs/lolcat.html
examples/htdocs/lowlevel.html
examples/htdocs/mike.html
examples/htdocs/mike2.html
examples/htdocs/minimal.html
examples/htdocs/mkws-widget-credo-bs.js [deleted file]
examples/htdocs/mkws-widget-credo.css
examples/htdocs/mkws-widget-reference.css
examples/htdocs/mkws-widget-ru-requirejs.html
examples/htdocs/mkws-widget-ru.css
examples/htdocs/mkws-widget-ru.html
examples/htdocs/mkws-widget-ru.js
examples/htdocs/mkws-widget-ru.readme
examples/htdocs/mkws-widget-sru.js [new file with mode: 0644]
examples/htdocs/mkws-widget-wimp.css
examples/htdocs/mkws-widget-wimp.html
examples/htdocs/mobile.html
examples/htdocs/popup-dev.html
examples/htdocs/popup.html
examples/htdocs/ref-bootstrap.html [deleted file]
examples/htdocs/ref.html
examples/htdocs/reference.html
examples/htdocs/robots.txt
examples/htdocs/simple.html
examples/htdocs/stateful.html
examples/htdocs/surlyauto.html
examples/htdocs/templates.html
examples/htdocs/topic.css [new file with mode: 0644]
examples/htdocs/topic.html [new file with mode: 0644]
examples/htdocs/tpl.html
examples/htdocs/two-teams.html
examples/htdocs/wolfram.html
examples/htdocs/wolfram2.html
notes/using-mkadmin [deleted file]
src/.gitignore [new file with mode: 0644]
src/Makefile
src/mkws-core.js
src/mkws-handlebars.js
src/mkws-popup.js
src/mkws-team.js
src/mkws-widget-authname.js
src/mkws-widget-builder.js
src/mkws-widget-categories.js
src/mkws-widget-log.js
src/mkws-widget-main.js
src/mkws-widget-record.js
src/mkws-widget-reference.js
src/mkws-widget-termlists.js
src/mkws-widget.js
src/templates/details.handlebars [new file with mode: 0644]
src/templates/done.handlebars [new file with mode: 0644]
src/templates/facet.handlebars [new file with mode: 0644]
src/templates/images.handlebars [new file with mode: 0644]
src/templates/lang.handlebars [new file with mode: 0644]
src/templates/navi.handlebars [new file with mode: 0644]
src/templates/pager.handlebars [new file with mode: 0644]
src/templates/progress.handlebars [new file with mode: 0644]
src/templates/ranking.handlebars [new file with mode: 0644]
src/templates/records.handlebars [new file with mode: 0644]
src/templates/reference.handlebars [new file with mode: 0644]
src/templates/results.handlebars [new file with mode: 0644]
src/templates/search.handlebars [new file with mode: 0644]
src/templates/stat.handlebars [new file with mode: 0644]
src/templates/summary.handlebars [new file with mode: 0644]
src/templates/switch.handlebars [new file with mode: 0644]
src/templates/targets.handlebars [new file with mode: 0644]
src/templates/termlists.handlebars [new file with mode: 0644]
test/.gitignore
test/Makefile
test/README.txt
test/bin/apache-template-update
test/bin/bomb.pl
test/bin/yui-compressor [new file with mode: 0755]
test/package.json
test/phantom/run-jasmine.js
test/phantom/screenshot.js
test/spec/async.spec.js
test/spec/jquery.spec.js
test/spec/jsdom.spec.js
test/spec/mkws-config.js
test/spec/mkws-pazpar2.js
test/spec/sample.spec.js
test/spec/true.spec.js
test/widgets/Makefile [new file with mode: 0644]
test/widgets/images/.gitkeep [new file with mode: 0644]
test/widgets/url.demos [new file with mode: 0644]
test/widgets/url.koha [new file with mode: 0644]
test/widgets/url.mike [new file with mode: 0644]
tools/apache2/jasmine-dev.template
tools/apache2/jasmine-dev.template-2.4
tools/apache2/mkws-dev
tools/apache2/mkws-live
tools/apache2/mkws-tools-mike
tools/apache2/sp-mkws-live
tools/bin/nagios-service-proxy.sh
tools/htdocs/.gitignore
tools/htdocs/Makefile [deleted file]
tools/htdocs/README
tools/htdocs/external/koha/Makefile
tools/htdocs/external/koha/koha-mkws-complete.css
tools/htdocs/external/koha/koha-mkws-widget-ru.css
tools/htdocs/external/koha/koha-mkws.css
tools/htdocs/index.html [deleted file]
tools/htdocs/mkws.css
tools/htdocs/no-service-proxy.html [new file with mode: 0644]
tools/htdocs/releases/mkws-complete-0.9.1.js
tools/htdocs/releases/mkws-complete-0.9.1.min.js
tools/htdocs/robots.txt
tools/service-proxy/service-proxy-mike-mac.properties [new file with mode: 0644]
tools/service-proxy/service-proxy.properties

index b25c15b..b72f9be 100644 (file)
@@ -1 +1,2 @@
 *~
+*.swp
diff --git a/LICENSE b/LICENSE
index 39d8b2e..65c5ca8 100644 (file)
--- a/LICENSE
+++ b/LICENSE
-LICENSE file of MKWS: the MasterKey Widget Set
-Copyright (C) 2013-2014 Index Data.
-
-
-                    GNU GENERAL PUBLIC LICENSE
+                   GNU LESSER GENERAL PUBLIC LICENSE
                        Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, 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
-them 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 prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If 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 convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU 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
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state 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 program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  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 that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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 as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
index e80e8e3..cb4d8f6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,28 +1,33 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
+#
+# You need node.js to build MKWS. On caliban, get it using:
+# export PATH=$PATH:/home/indexdata/node/node-v0.10.32-linux-x64/bin
 
-all:
-       ${MAKE} -C./tools/htdocs $@
-       ${MAKE} -C./doc install
+all: setup
+       ${MAKE} -C./src
+       ${MAKE} -C./doc
+       ${MAKE} -C./examples/htdocs
 
 clean distclean:
-       ${MAKE} -C./tools/htdocs $@
+       ${MAKE} -C./src $@
        ${MAKE} -C./doc $@
        ${MAKE} -C./examples/htdocs $@
        ${MAKE} -C./test $@
 
+check: setup check-js phantomjs
+
+setup:
+       ${MAKE} -C./test node-modules
+
 check-js:
-       ${MAKE} -C./test check
+       ${MAKE} -C./test $@
 
 phantomjs p p-all phantomjs-all jsb:
        ${MAKE} -C./test $@
 
-# must be called once after GIT checkout
-setup: 
-       ${MAKE} -C./test node-modules
-
-check: setup check-js phantomjs
-
 help:
        @echo "make [ all | setup | clean | distclean ]"
        @echo "     [ check | check-js | phantomjs ]"
+       @echo ""
+       @echo "If 'make check' timeout is too short, extend with: make check PHANTOMJS_TIMEOUT=40"
 
diff --git a/README b/README
index 5696cd1..98645e5 100644 (file)
--- a/README
+++ b/README
@@ -1,39 +1,21 @@
-OVERVIEW
-========
-
-The MasterKey Widget Set, or MKWS, is a project to create some very
-simple HTML/JS/CSS widgets that can be dropped into ANY website,
-irrespective of CMS or lack thereof, to enable MasterKey searching.
-
-
-WHAT'S WHAT
-===========
+The MasterKey Widget Set, or MKWS, provides HTML/JS/CSS widgets that
+can be dropped into ANY website, irrespective of CMS or lack thereof,
+to enable MasterKey searching.
 
 README   -- this file
+LICENSE  -- The GNU LGPL (Lesser General Public Licence)
 Makefile -- delegates to tools/htdocs/Makefile
+src      -- source-code that is compiled into the tools area
 tools   -- the tools that make up the Widget Set
 examples -- examples of applications that use MKWS
-
+doc      -- documentation (in Markdown, compiles to HTML)
+test     -- regression-testing scripts
 notes    -- internal documents, not for customers
 
+See tools/htdocs/NEWS for the change-log.
 
-Required devel tools
-====================
-
-On debian, you will need:
-$ sudo apt-get install curl git-core pandoc yui-compressor node-js libbsd-resource-perl
-
-On Debian 7 (wheezy), you do not need git-core, plain git will do, but
-you probably have that on a development box already. Unfortunately, node-js
-is not available for wheezy. Either you can get it from wheezy-backports,
-or you can download the source from http://nodejs.org/download/ and build
-it yourself. Looks like you need node and npm, make install puts them
-into /usr/local/bin.
-
-For apache setup, see tools/apache2/README
-
-NEWS
-=========
-
-see tools/htdocs/NEWS
+For more documentation:
 
+doc/index.markdown -- overview
+doc/mkws-manual.markdown -- how to use the widget set
+doc/mkws-developer.markdown -- how to develop and customise widgets
diff --git a/doc/.gitignore b/doc/.gitignore
deleted file mode 100644 (file)
index 653ed0c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-README.html
-README.odt
-README.pdf
-mkws-manual.html
-mkws-manual.odt
-mkws-manual.pdf
-mkws-developer.html
-mkws-developer.odt
-mkws-developer.pdf
index d87c1f8..1e436d4 100644 (file)
@@ -1,60 +1,66 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
+#
+# To build the PDFs, you will need these Debian packages:
+#      texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended
 
-DOCS = README.html README.odt README.pdf \
-       mkws-manual.html mkws-manual.odt mkws-manual.pdf \
-       mkws-developer.html mkws-developer.odt mkws-developer.pdf
+# Older versions of pandoc don't do PDF output, but have a companion program
+MARKDOWN2PDF = $(shell if which markdown2pdf > /dev/null; then echo markdown2pdf; else echo pandoc --standalone; fi)
+HAVE_PDFLATEX = $(shell which pdflatex 2>/dev/null)
 
-INSTALLABLE = README.html mkws-manual.html mkws-developer.html mkws-doc.css
-INSTALLED = $(INSTALLABLE:%=../tools/htdocs/%)
+DOCS = index.html \
+       mkws-manual.html \
+       mkws-developer.html \
+       mkws-doc.css
 
-install: $(INSTALLED)
+PDFS = index.pdf \
+       mkws-manual.pdf \
+       mkws-developer.pdf
 
-uninstall:
-       rm -f $(INSTALLED)
+#
+# skip PDF creation if pdflatex is not installed
+# The debian tex package may download up to 650MB
+#
+ifneq "${HAVE_PDFLATEX}" ""
+DOCS+= ${PDFS}
+endif
+
+INSTALLED = $(DOCS:%=../tools/htdocs/%)
+
+all: $(INSTALLED)
 
 ../tools/htdocs/%: %
        rm -f $@
-       cp -p $? $@
+       cp $< $@
        chmod ugo-w $@
 
-all: $(DOCS)
-
 # For a description of pandoc's markdown format, see:
-# http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html -->
+# http://johnmacfarlane.net/pandoc/demo/example9/pandocs-markdown.html
 
 # for older pandoc (<1.9) run first:
 # perl -i.bak -npe 's/"(Authors|Subjects)": "(.*?)"/"$1": "test"/' tools/htdocs/mkws-manual.markdown
 #
-%.html: %.markdown
-       rm -f $@
-       pandoc --standalone --toc -c mkws-doc.css $< | sed '/^<col width="[0-9]*%" \/>$//d' > $@
-       chmod ugo-w $@
-
-%.odt: %.markdown
+../tools/htdocs/%.html: %.markdown tweak-html
        rm -f $@
-       pandoc --standalone $< -o $@
+       pandoc --standalone --toc -c mkws-doc.css $< | ./tweak-html > $@
        chmod ugo-w $@
 
-# ### In order to compile the manual, which has tables, to PDF,
-# you will need to install the Debian package
-#      texlive-latex-recommended
-%.pdf: %.markdown
+../tools/htdocs/%.pdf: %.markdown
        rm -f $@
-       pandoc --standalone $< -o $@
+       $(MARKDOWN2PDF) $< -o $@
        chmod ugo-w $@
 
 clean:
-       rm -f $(DOCS)
+       rm -f $(INSTALLED)
        rm -f *.drupal.html
 
-distclean: clean uninstall
+distclean: clean
+       # Nothing more to remove in the doc directory
 
 push:
-       pandoc --toc README.markdown > README.drupal.html
+       pandoc --toc index.markdown > index.drupal.html
        pandoc --toc mkws-manual.markdown > mkws-manual.drupal.html
-       cat README.drupal.html | ./drupaljson.pl | curl --upload-file - http://www.indexdata.com/script/node/332?services_token=cda1e26e5733ce3f604773e94f0721df5c31a948 -v --header "Content-Type:application/json"
+       cat index.drupal.html | ./drupaljson.pl | curl --upload-file - http://www.indexdata.com/script/node/332?services_token=cda1e26e5733ce3f604773e94f0721df5c31a948 -v --header "Content-Type:application/json"
        cat mkws-manual.drupal.html | ./drupaljson.pl | curl --upload-file - http://www.indexdata.com/script/node/323?services_token=cda1e26e5733ce3f604773e94f0721df5c31a948 -v --header "Content-Type:application/json"
 
 help:
-       @echo "make [ all | install | clean | distclean | push ]"
-
+       @echo "make [ all | clean | push ]"
diff --git a/doc/README.markdown b/doc/README.markdown
deleted file mode 100644 (file)
index ff9f4bb..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-% The MasterKey Widget Set
-% Mike Taylor; Wolfram Schneider
-% 28 July 2014
-
-
-Introduction
-------------
-
-This is the MasterKey Widget Set. It provides a way to insert
-searching and other information-related functionality into existing
-web pages as small snippets of HTML.
-
-As much of the searching functionality as possible is hosted on
-       <http://mkws.indexdata.com/>
-so that very simple applications such as
-       <http://example.indexdata.com/simple.html>
-can have MasterKey searching with minimal effort.
-
-The following files are hosted on `mkws.indexdata.com`:
-
-* `mkws.js` (and its compressed version `mkws.min.js`)
-* `/pazpar2/js/pz2.js`
-* `mkws-complete.js` (and its compressed version `mkws-complete.min.js`)
-  -- a single file consisting of `mkws.js` together with the files it
-  uses: `pz2.js` jQuery, jQuery-JSON and Handlebars.
-* Local copy of `jquery-1.10.0.min.js`
-* Local copy of `jquery.json-2.4.js`
-* Local copy of `handlebars-v1.1.2.js`
-* `mkws.css`
-
-
-Supported Browsers
-------------------
-
-Any modern browser will work fine. JavaScript must be enabled.
-
-* IE8 or later
-* Firefox 17 or later
-* Google Chrome 27 or later
-* Safari 6 or later
-* Opera  12 or later
-* iOS 6.x (iPhone, iPad)
-* Android 4.x
-
-Not supported: IE6, IE7
-
-
-Configuring a client (short version)
-------------------------------------
-
-The application's HTML must contains the following elements as well as
-whatever makes up the application itself:
-
-Prerequisites:
-
-~~~
-       <link rel="stylesheet" href="http://mkws.indexdata.com/mkws.css" />
-       <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
-~~~
-
-Then the following special `<div>`s can be added (with no content), and
-will be filled in by MKWS:
-
-* `<div id="mkwsSwitch"></div>` -- switch between record and target views
-* `<div id="mkwsLang"></div>  ` -- switch between English, Danish and German
-* `<div id="mkwsSearch"></div>` -- search box and button
-* `<div id="mkwsResults"></div>` -- result list, including pager/sorting
-* `<div id="mkwsTargets"></div>` -- target list, including status
-* `<div id="mkwsStat"></div>` -- summary statistics
-
-You can configure and control the client by creating an `mkws_config`
-object before loading the widget-set. Here is an example showing how
-to use options to offer a choice between English and German UI
-languages, and to default to sorting by title ascending:
-
-~~~
-    <script type="text/javascript">
-      var mkws_config = {
-        lang_options: ["en", "de" ],
-        sort_default: "title:1"
-      };
-    </script>
-~~~
-
-For much more detail, see:
-[Embedded metasearching with the MasterKey Widget Set](mkws-manual.html)
-
-
-- - -
-
-Copyright 2014 IndexData ApS. <http://indexdata.com>
diff --git a/doc/index.markdown b/doc/index.markdown
new file mode 100644 (file)
index 0000000..6c4424a
--- /dev/null
@@ -0,0 +1,204 @@
+% MKWS: the MasterKey Widget Set
+% Mike Taylor
+% October 2014
+
+
+Add metasearching to your web-site painlessly
+---------------------------------------------
+
+The MasterKey Widget Set provides the easiest possible way to enhance
+an existing web-site with customised searching across multiple
+sources, ranking and merging the results.
+
+As much of the searching functionality as possible is hosted on
+`http://mkws.indexdata.com/` so that very simple applications such as
+<http://example.indexdata.com/simple.html> can have MasterKey
+searching with minimal effort.  All you need to do is pull in our
+JavaScript and optional stylesheet, then add `<div>`s to your page
+that have special `class` attributes. We do the rest.
+
+Supported Browsers
+------------------
+
+Any modern browser will work fine. JavaScript must be enabled.
+
+* IE8 or later
+* Firefox 17 or later
+* Google Chrome 27 or later
+* Safari 6 or later
+* Opera  12 or later
+* iOS 6.x (iPhone, iPad)
+* Android 4.x
+
+Not supported: IE6, IE7
+
+A minimal example
+-----------------
+
+Here is a completely functional (though ugly) MKWS-based
+searching application [[link]](http://example.indexdata.com/minimal.html)
+
+       <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
+       <div class="mkwsSearch"></div>
+       <div class="mkwsResults"></div>
+
+That's it. A complete metasearching application. Everything
+else is refinement.
+
+Configuring a client (short version)
+------------------------------------
+
+The application's HTML must contain the following elements as well as
+whatever makes up the application itself:
+
+       <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
+       <link rel="stylesheet" href="http://mkws.indexdata.com/mkws.css" />
+
+These lines pull in JavaScript code and the default styles. (The
+latter may be omitted or replaced with application-specific styles for
+the widgets.)
+
+Then the following special `<div>`s can be added (with no content), and
+will be filled in by MKWS:
+
+* `<div class="mkwsSearch"></div>` -- search box and button
+* `<div class="mkwsResults"></div>` -- result list, including pager/sorting
+* `<div class="mkwsStat"></div>` -- summary statistics
+* `<div class="mkwsSwitch"></div>` -- switch between record and target views
+* `<div class="mkwsTargets"></div>` -- target list, including status
+* `<div class="mkwsLang"></div>  ` -- switch between languages, e.g. English, Danish and German
+
+You can configure and control the client by creating an `mkws_config`
+object. Here is an example showing how to use options to offer a
+choice between English and German UI languages, and to default to
+sorting by title ascending:
+
+       <script type="text/javascript">
+         var mkws_config = {
+           lang_options: ["en", "de" ],
+           sort_default: "title:1"
+         };
+       </script>
+
+Detailed documentation
+----------------------
+
+Apart from [this file](index.html) and its [PDF version](index.pdf):
+
+* The [MKWS manual, including a reference section](mkws-manual.html)
+  [[PDF version]](mkws-manual.pdf)
+* The [MKWS developers' guide](mkws-developer.html)
+  [[PDF version]](mkws-developer.pdf)
+
+Widget files
+------------
+
+Here are the files that this web-site provides:
+
+* [mkws.js](mkws.js) --
+  JavaScript code that powers the MasterKey Widget Set
+* [pazpar2/js/pz2.js](pazpar2/js/pz2.js) --
+  Low-level JavaScript library for access to the MasterKey web
+  service.
+* [handlebars-v2.0.0.js](handlebars-v2.0.0.js) --
+  A local copy of
+  [the Handlebars templating library](//handlebarsjs.com/),
+  since it doesn't like to be hotlinked.
+* Local copy of [jquery-1.10.0.min.js](jquery-1.10.0.min.js)
+* Local copy of [jquery.json-2.4.js](jquery.json-2.4.js)
+* [mkws-complete.js](mkws-complete.js) --
+  A single large JavaScript file containing everything needed for
+  MKWS to work: the widget-set itself, the API library, and
+  the prerequisites jQuery and Handlebars.
+* [mkws.css](mkws.css) --
+  A stylesheet which styles only MasterKey widgets, and does not
+  otherwise interfere with application-site's styles.
+
+Minified versions of the MKWS JavaScript files are also available:
+
+* [mkws.min.js](mkws.min.js)
+* [mkws-complete.min.js](mkws-complete.min.js)
+
+### Specific versions
+
+The links above to the various forms of the widget-set JavaScript
+([mkws.js](mkws.js),
+[mkws-complete.js](mkws-complete.js),
+[mkws.min.js](mkws.min.js)
+and
+[mkws-complete.min.js](mkws-complete.min.js))
+are always to the current versions of those
+files. Applications that rely on a particular version can
+instead use the specific numbered versions in
+[the releases area](releases/),
+for example
+[releases/mkws-0.9.1.js](releases/mkws-0.9.1.js).
+
+The current version number is always in
+[the VERSION file](VERSION).
+
+Version history is in
+[the NEWS file](NEWS).
+
+Examples using the widget-set
+-----------------------------
+
+It's worth viewing the source of these to see how small they
+are and how various things are done.
+
+### Simple examples
+
+* A very simple application at <http://example.indexdata.com/simple.html>
+* [The absolutely minimal application](//example.indexdata.com/minimal.html)
+  listed above.
+* [A more detailed version](//example.indexdata.com/language.html)
+  that contains a configuration structure instead of accepting the
+  defaults. Includes a custom translation option to present the
+  application in Arabic.
+* [A version suitable for mobile devices](//example.indexdata.com/mobile.html)
+  with a responsive design that moves components around depending on
+  the screen size.
+
+### Advanced examples
+
+* An application that
+  [uses lower-level MKWS components](//example.indexdata.com/lowlevel.html)
+  rather than the all-in-one `#mkwsResults` division,
+  allowing it to use a rather different layout.
+* An application that specifies how to display brief and full records
+  [using Handlebar templates](//example.indexdata.com/templates.html).
+  (Read about
+  [the templating language](//handlebarsjs.com/).)
+* An application that
+  [displays thumbnail images](//example.indexdata.com/images.html?q=portrait).
+* An application that
+  [uses a local authentication regime](//example.indexdata.com/localauth.html)
+  and the corresponding
+  [Apache2 configuration stanza](//example.indexdata.com/apache-config.txt).
+* [A version that uses a jQuery popup](//example.indexdata.com/popup.html?q=sushi).
+
+### Non-standard interfaces
+
+* An application that uses MKWS to
+  [find dictionary definitions of words](//example.indexdata.com/dict.html)
+  when you highlight them.
+* An application that
+  [runs an automatic search on load](//example.indexdata.com/auto.html).  
+* Another existing web-site,
+  [The Zthes specifications](//zthes.z3950.org/),
+  which has been fitted with a popup MKWS search-box.
+
+Target selection
+----------------
+
+MKWS comes pre-configured to search in a set of a dozen or so
+open-access targets, as a proof of concept. But you'll want
+to use it to
+[search your own selection of targets](mkws-manual.html#mkws-target-selection)
+-- some open access, some subscription.
+
+We can set that up for you: email us on <info@indexdata.com>.
+
+- - -
+
+Copyright (C) 2013-2014 Index Data ApS. <http://indexdata.com>
index 00a5b59..3d92fc3 100644 (file)
@@ -3,6 +3,29 @@
 % 11 August 2014
 
 
+Required development tools
+==========================
+
+If you are building the widget set, as opposed to just using it, you
+will need the following Debian packages (or their equivalents on your
+operating system):
+
+       $ sudo apt-get install curl git make unzip \
+           pandoc yui-compressor libbsd-resource-perl
+
+You also need Node.js, but unfortunately the `node-js` package is not
+available for Debian wheezy. You can either get it from
+wheezy-backports or download the source from
+http://nodejs.org/download/ and build it yourself. You need both Node
+itself and its package manager NPM: `make install` puts them into
+`/usr/local/bin`.
+
+To compile the default templates you'll need to install the stable
+version of Handlebars. Currently it's at 2.0.0 and available by npm:
+
+       $ npm install handlebars@2.0.0 -g
+
+
 Overview
 ========
 
@@ -258,4 +281,4 @@ TODO: list of events that can be usefully subscribed to.
 
 - - -
 
-Copyright (C) 2013-2014 by IndexData ApS, <http://www.indexdata.com>
+Copyright (C) 2013-2014 Index Data ApS. <http://indexdata.com>
index 0eb4a34..31cb2cf 100644 (file)
@@ -1,71 +1,28 @@
 body {
-    font-family: Baskerville, "Baskervald ADF Std", "Times New Roman", "Times Roman", Times;
-}
-
-h1, h2, h3, h4 {
-    color: #68a;
-    font-weight: bold;
-    font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
-}
-
-h1 a, h2 a, h3 a, h4 a, div#TOC a {
-    color: #68a;
-    text-decoration: none;
-}
-
-h2, h3 {
-    /* Default spacing is way off in both Chrome and Firefox */
-    margin-bottom: -0.5em;
-}
-
-h1.title {
-    background: #e0e8f8;
-    padding: 0.2em;
-    font-weight: normal;
-}
-
-h2.author {
-    font-size: 120%;
-    color: black
-}
-
-h3.date {
-    font-size: 100%;
-    color: black
-}
-
-body > p, ul, ol, pre, table, h4, blockquote {
-    margin-left: 10%;
-}
-
-blockquote {
-    padding-left: 4em;
-    padding-right: 4em;
-}
-
-p, ul {
-    max-width: 40em;
-}
-
-pre {
-    background: #eee;
-}
-
-table tr th {
-    color: white;
-    background: #68a;
-    font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
-}
-
-th, td {
-    padding: 0.2em 0.5em;
-    vertical-align: top;
-}
-
-table tr:nth-child(odd) {
-    background: #a9c6e3;
-}
-
-table tr:nth-child(even) {
-    background: #bfdcf8;
+  font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Sans-Serif;
+}
+h1, h2, h3 { color: #606060 }
+h2 { margin-top: 0.5em }
+h1.title, h2.author, h3.date { font-weight: normal }
+div#header h2 { font-size: 120% }
+div#header h3 { font-size: 100% }
+.pane {
+  padding: 0em 1em; margin: 0.75em;
+  border: 0.5em solid #eee;
+  border-radius: 1em;
+  background-image: url('images/mkws-logo-48x48-light.png');
+  background-repeat: no-repeat;
+  background-position: right top;
+  background-color: #eee; 
+}
+// Somehow, "-n+3" is how you say "first three panes"
+.pane:nth-child(-n+3) {
+  background-image: none;
+}
+.pane h1 a, .pane h2 a, .pane h3 a { text-decoration: none; color: black }
+pre { background: #ddd; padding: 0.5em; }
+img:first-of-type { float: right; margin: 1.5em }
+body > p:last-of-type {
+    text-align: right;
+    font-size: small;
 }
index 79b396e..5c0916d 100644 (file)
@@ -1,6 +1,6 @@
-% Embedded metasearching with the MasterKey Widget Set
+% The MKWS manual: embedded metasearching with the MasterKey Widget Set
 % Mike Taylor
-% 30 July 2014
+% October 2014
 
 
 Introduction
@@ -19,10 +19,14 @@ Index Data provides several different toolkits for communicating with
 its metasearching middleware, trading off varying degrees of
 flexibility against convenience:
 
-* pz2.js -- a low-level JavaScript library for interrogating the
-  Service Proxy and Pazpar2. It allows the HTML/JavaScript programmer
-  to create JavaScript applications display facets, records, etc. that
-  are fetched from the metasearching middleware.
+* [pz2.js](http://www.indexdata.com/pazpar2/doc/ajaxdev.html) --
+  a low-level JavaScript library for interrogating the
+  [Service Proxy](http://www.indexdata.com/service-proxy/)
+  and
+  [Pazpar2](http://www.indexdata.com/pazpar2/).
+  It allows the HTML/JavaScript programmer
+  to create JavaScript applications to display facets, records,
+  etc. that are fetched from the metasearching middleware.
 
 * masterkey-ui-core -- a higher-level, complex JavaScript library that
   uses pz2.js to provide the pieces needed for building a
@@ -30,44 +34,46 @@ flexibility against convenience:
 
 * MasterKey Demo UI -- an example of a searching application built on
   top of masterkey-ui-core. Available as a public demo at
-  http://mk2.indexdata.com/
+  <http://mk2.indexdata.com/>
 
-* MKDru -- a toolkit for embedding MasterKey-like searching into
-  Drupal sites.
+* [MKDru](http://www.indexdata.com/masterkey-drupal) --
+  a toolkit for embedding MasterKey-like searching into
+  [Drupal](https://www.drupal.org/)
+  sites.
 
 All of these approaches require programming to a greater or lesser
-extent. Against this backdrop, we introduced MKWS (the MasterKey
-Widget Set) -- a set of simple, very high-level HTML+CSS+JavaScript
+extent. Against this backdrop, we introduced
+[MKWS (the MasterKey Widget Set)](http://mkws.indexdata.com/)
+-- a set of simple, very high-level HTML+CSS+JavaScript
 components that can be incorporated into any web-site to provide
 MasterKey searching facilities. By placing `<div>`s with well-known
-identifiers in any HTML page, the various components of an application
+MKWS classes in any HTML page, the various components of an application
 can be embedded: search-boxes, results areas, target information, etc.
 
 
-Simple Example
+Simple example
 ==============
 
-The following is a complete MKWS-based searching application:
+The following is
+[a complete MKWS-based searching application](//example.indexdata.com/simple.html):
 
     <html>
       <head>
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
         <title>MKWS demo client</title>
-        <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
-        <link rel="stylesheet" href="http://mkws.indexdata.com/mkws.css" />
+        <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+        <link rel="stylesheet" href="//mkws.indexdata.com/mkws.css" />
       </head>
       <body>
-        <div id="mkwsSearch"></div>
-        <div id="mkwsResults"></div>
+        <div class="mkws-search"></div>
+        <div class="mkws-results"></div>
       </body>
     </html>
 
-Go ahead, try it! You don't even need a web-server. Just copy and
-paste this HTML into a file on your computer -- `/tmp/magic.html`,
-say -- and point your web-browser at it:
-`file:///tmp/magic.html`. Just like that, you have working
-metasearching.
-
+Go ahead, try it! Simply put the above in a file (e.g index.html),
+drop it into a folder accessible with an ordinary web-server (e.g
+Apache) and load it in your web browser. Just like that, you have
+working metasearching.
 
 How the example works
 ---------------------
@@ -78,64 +84,121 @@ you: the `<html>` element at the top level contains a `<head>` and a
 page, you can add MKWS elements.
 
 These fall into two categories. First, the prerequisites in the HTML
-header, which are loaded from the tool site mkws.indexdata.com:
+header, which are loaded from the tool site `mkws.indexdata.com`:
 
 * `mkws-complete.js`
-  contains all the JavaScript needed by the widget-set.
+  contains all the JavaScript needed by the widget-set, including a
+  copy of the jQuery library.
 
 * `mkws.css`
   provides the default CSS styling
 
 Second, within the HTML body, `<div>` elements with special IDs that
-begin `mkws` can be provided. These are filled in by the MKWS code,
+begin `mkws-` can be provided. These are filled in by the MKWS code,
 and provide the components of the searching UI. The very simple
-application above has only two such components: a search box and a
-results area. But more are supported. The main `<div>`s are:
+application above has only two such widgets: a search box and a
+results area. But more are supported.
+
+Defining widget elements
+========================
+
+Widget type
+-----------
 
-* `mkwsSearch` -- provides the search box and button.
+An HTML element is made an MKWS widget by including an MKWS
+class-name. These names begin `mkws-`: what follows that prefix
+specifies the type of the widget. The type can be any sequence of
+alphanumeric characters and hyphens _except_ something beginning
+`team` -- see below.
 
-* `mkwsResults` -- provides the results area, including a list of
+The main widgets are:
+
+* `mkws-search` -- provides the search box and button.
+
+* `mkws-results` -- provides the results area, including a list of
    brief records (which open out into full versions when clicked),
    paging for large results sets, facets for refining a search,
    sorting facilities, etc.
 
-* `mkwsLang` -- provides links to switch between one of several
-   different UI languages. By default, English, Danish and German are
-   provided.
+* `mkws-progress` -- shows a progress bar indicating how many of the
+   targets have responded to the search request.
+
+* `mkws-stat` -- provides a status line summarising the statistics of
+   the various targets.
 
-* `mkwsSwitch` -- provides links to switch between a view of the
+* `mkws-switch` -- provides links to switch between a view of the
    result records and of the targets that provide them. Only
-   meaningful when `mkwsTargets` is also provided.
+   meaningful when `mkws-targets` is also provided.
 
-* `mkwsTargets` -- the area where per-target information will appear
-   when selected by the link in the `mkwsSwitch` area. Of interest
+* `mkws-targets` -- the area where per-target information will appear
+   when selected by the link in the `mkws-switch` area. Of interest
    mostly for fault diagnosis rather than for end-users.
 
-* `mkwsStat` --provides a status line summarising the statistics of
-   the various targets.
+* `mkws-lang` -- provides links to switch between one of several
+   different UI languages. By default, English, Danish and German are
+   provided.
 
 To see all of these working together, just put them all into the HTML
 `<body>` like so:
 
-        <div id="mkwsSwitch"></div>
-        <div id="mkwsLang"></div>
-        <div id="mkwsSearch"></div>
-        <div id="mkwsResults"></div>
-        <div id="mkwsTargets"></div>
-        <div id="mkwsStat"></div>
+        <div class="mkws-switch"></div>
+        <div class="mkws-lang"></div>
+        <div class="mkws-progress"></div>
+        <div class="mkws-search"></div>
+        <div class="mkws-results"></div>
+        <div class="mkws-targets"></div>
+        <div class="mkws-stat"></div>
 
+The full set of supported widgets is described in the
+reference guide below.
 
-Configuration
-=============
+Widget team
+-----------
+
+In general a set of widgets work together in a team: in the example
+above, the search-term that the user enters in the `mkws-search`
+widget is used to generate the set of records that are displayed in
+the `mkws-results` widget.
+
+Sometimes, it's desirable to have multiple teams in a single page. A
+widget can be placed in a named team by giving it (in addition to its
+main class) a class that begins with `mkws-team-`: what follows that
+prefix specifies the team that the widget is part of. For example,
+`<div class="mkws-search mkws-team-aux">` creates a search widget that
+is part of the `aux` team.
+
+Widgets that do not have a team specified (as in the examples above)
+are placed in the team called `AUTO`.
+
+Old and new-style class-names
+-----------------------------
+
+**NOTE.** Versions of MKWS before v1.0 used camel-case class-names:
+without hyphens and with second and subsequent words capitalised. So
+instead of `mkws-search`, it used to be `mkwsSearch`. And the classes
+used to specify team names used an `mkwsTeam_` prefix (with an
+underscore). So instead of `mkws-team-foo`, it used to be
+`mkwsTeam_foo`.
+
+The 1.x series of MKWS releases recognise these old-style class-names
+as well as the canonical ones, as a facility for backwards
+compatibility. However, **these old class-names are deprecated, and
+support will be removed in v2.0**. Existing applications that use them
+should be upgraded to the new-style class names as soon as convenient.
+
+Configuring widgets
+===================
+
+Global configuration
+--------------------
 
 Many aspects of the behaviour of MKWS can be modified by setting
-parameters into the `mkws_config` object. **This must be done *before*
-including the MKWS JavaScript** so that when that code is executed it
-can refer to the configuration values. So the HTML header looks like
-this:
+parameters into the `mkws_config` object. So the HTML header looks
+like this:
 
         <script type="text/javascript">
           var mkws_config = {
+            lang_options: [ "en", "da" ]
             lang: "da",
             sort_default: "title",
             query_width: 60
@@ -143,45 +206,84 @@ this:
         </script>
         <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
 
-This configuration sets the UI language to Danish (rather than the
-default of English), initially sorts search results by title rather
-than relevance (though as always this can be changed in the UI) and
-makes the search box a bit wider than the default.
+This configuration restricts the set of available UI languages English
+and Danish (omitting German), sets the default to Danish (rather than
+the English), initially sorts search results by title rather than
+relevance (though as always this can be changed in the UI) and makes
+the search box a bit wider than the default.
 
 The full set of supported configuration items is described in the
 reference guide below.
 
+Per-widget configuration
+------------------------
+
+In addition to the global configuration provided by the `mkws_config`
+object, individual widgets' behaviour can be configured by providing
+configuration items as attributed on their HTML elements. For example,
+a `records` widget might be restricted to displaying no more than
+three records by setting the `numrecs` parameter as follows:
+
+       <div class="mkws-records" maxrecs="3">
+
+Although this works well, HTML validators will consider this element
+acceptable, since the `maxrecs` attribute is not part of the HTML
+schema. However, attributes beginning `data-` are always accepted as
+HTML extensions, much like email headers beginning with
+`X-`. Therefore, the widget set also recognises configuration
+attributes prefixed with `data-mkws-`, so:
+
+       <div class="mkws-records" data-mkws-maxrecs="3">
+
+For first form is more convenient; the second is more correct.
+
+Because some configuration items take structured values rather than
+simple strings, they cannot be directly provided by inline
+attributes. To allow for this, the special attribute
+`data-mkws-config`, if provided, is parsed as JSON and its key-value
+pairs set as configuration items for the widget in question. For
+example, the value of `lang_options` is an array of strings specifying
+which of the supported UI languages should be made available. The
+following invocation will limit this list to only English and Danish
+(omitting German):
+
+       <div class="mkws-lang" data-mkws-config='{ "lang_options": [ "en", "da" ] }'></div>
+
+(Note that, as JSON requires double quotes around all strings, single
+quotes must be used to contain the entire attribute value.)
+
 
 Control over HTML and CSS
 =========================
 
-More sophisticated applications will not simply place the `<div>`s
+More sophisticated applications will not simply place the widgets
 together, but position them carefully within an existing page
 framework -- such as a Drupal template, an OPAC or a SharePoint page.
 
 While it's convenient for simple applications to use a monolithic
-`mkwsResults` area which contains record, facets, sorting options,
+`mkws-results` area which contains record, facets, sorting options,
 etc., customised layouts may wish to treat each of these components
-separately. In this case, `mkwsResults` can be omitted, and the
-following lower-level components provided instead:
+separately. In this case, `mkws-results` can be omitted, and the
+following lower-level widgets provided instead:
 
-* `mkwsTermlists` -- provides the facets
+* `mkws-termlists` -- provides the facets
 
-* `mkwsRanking` -- provides the options for how records are sorted and
+* `mkws-ranking` -- provides the options for how records are sorted and
    how many are included on each page of results.
 
-* `mkwsPager` -- provides the links for navigating back and forth
+* `mkws-pager` -- provides the links for navigating back and forth
    through the pages of records.
 
-* `mkwsNavi` -- when a search result has been narrowed by one or more
+* `mkws-navi` -- when a search result has been narrowed by one or more
    facets, this area shows the names of those facets, and allows the
    selected values to be clicked in order to remove them.
 
-* `mkwsRecords` -- lists the actual result records.
+* `mkws-records` -- lists the actual result records.
 
 Customisation of MKWS searching widgets can also be achieved by
 overriding the styles set in the toolkit's CSS stylesheet. The default
-styles can be inspected in `mkws.css` and overridden in any
+styles can be inspected in [mkws.css](mkws.css)
+and overridden in any
 styles that appears later in the HTML than that file. At the simplest
 level, this might just mean changing fonts, sizes and colours, but
 more fundamental changes are also possible.
@@ -192,122 +294,165 @@ containers. The structures used by the widget-set are described in the
 reference guide below.
 
 
-Refinements
-===========
-
+Customised display using Handlebars templates
+=============================================
+
+A lot can be done by styling widgets in CSS and changing basic MKWS config
+options. For further customisation, MKWS allows you to change the markup it
+outputs for any widget. This is done by overriding the
+[Handlebars](http://handlebarsjs.com/) template used to generate it. In general
+these consist of `{{things in double braces}}` that are replaced by values from
+the system. For details of Handlebars template syntax, see [the online
+documentation](http://handlebarsjs.com/).
+
+The templates used by the core widgets can be viewed in [our git
+repository](http://git.indexdata.com/?p=mkws.git;a=tree;f=src/templates;).
+Parameters are documented in a comment at the top of each template so
+you can see what's going where. If all you want to do is add a CSS class to
+something or change a `span` to a `div` it's easy to just copy the existing
+template and make your edits.
+
+Overriding templates
+--------------------
 
-Message of the day
-------------------
+To override the template for a widget, include it inline in the document
+as a `<script>` tag marked with a class of `mkws-template-foo` where foo is the
+name of the template you want to override (typically the name of the widget).
+Inline Handlebars templates are distinguished from Javascript via a
+`type="text/x-handlebars-template"` attribute. For example, to override the
+pager template you would include this in your document:
+
+    <script class="mkws-template-pager" type="text/x-handlebars-template">
+      ...new Pager template
+    </script>
+
+The Facet template has a special feature where you can override it on
+a per-facet basis by adding a dash and the facet name as a suffix eg.
+`facet-subjects`. (So `class="mkws-template-facet-subjects"`.) When
+rendering a facet for which no specific template is defined, the code
+falls back to using the generic facet template, just called `facet`.
+
+You can also explicitly specify a different template for a particular
+instance of a widget by providing the name of your alternative
+(eg. `special-pager`) as the value of the `template` key in the MKWS
+config object for that widget: for example, `<div class="mkws-pager"
+template="special-pager"/>`.
+
+Templates for MKWS can also be
+[precompiled](http://handlebarsjs.com/precompilation.html). If a precompiled
+template of the same name is found in the `Handlebars.templates` object, it
+will be used instead of the default.
+
+Inspecting metadata for templating
+----------------------------------
+
+MKWS makes requests to the Service Proxy or Pazpar2 that perform the
+actual searching. Depending on how these are configured and what is
+available from the targets you are searching there may be more data
+available than what is presented by the default templates.
+
+Handlebars offers a convenient log helper that will output the contents of a
+variable for you to inspect. This lets you look at exactly what is being
+returned by the back end without needing to use a Javascript debugger. For
+example, you might prepend `{{log hits}}` to the Records template in order to
+see what is being returned with each search result in the list. In order for
+this to work you'll need to enable verbose output from Handlebars which is done
+by including this line or similar:
+
+    <script>Handlebars.logger.level = 1;</script>
+
+Internationalisation
+--------------------
 
-Some applications might like to open with content in the area that
-will subsequently be filled with result-records -- a message of the
-day, a welcome message or a help page. This can be done by placing an
-`mkwsMOTD` division anywhere on the page. It will be moved into the
-`mkwsResults` area and initially displayed, but will be hidden when a
-search is made.
+If you would like your template to use the built in translation functionality,
+output locale specific text via the mkws-translate helper like so:
+`{{{mkws-translate "a few words"}}}`.
 
+Example
+-------
 
-Customised display using Handlebars templates
----------------------------------------------
-
-Certain aspects of the widget-set's display can be customised by
-providing Handlebars templates with well-known classes that begin with
-the string `mkwsTemplate_`. At present, the supported templates are:
-
-* `mkwsTemplate_Summary` -- used for each summary record in a list of
-  results.
-
-* `mkwsTemplate_Record` -- used when displaying a full record.
-
-For both of these the metadata record is passed in, and its fields can
-be referenced in the template. As well as the metadata fields
-(`md-*`), two special fields are provided to the `mkwsTemplate_Summary`
-template, for creating popup links for full records. These are `_id`,
-which must be provided as the `id` attribute of a link tag, and
-`_onclick`, which must be provided as the `onclick` attribute.
-
-For example, an application can install a simple author+title summary
-record in place of the usual one providing the following template:
-
-        <script class="mkwsTemplate_Summary" type="text/x-handlebars-template">
-          {{#if md-author}}
-            <span>{{md-author}}</span>
-          {{/if}}
-          <a href="#" id="{{_id}}" onclick="{{_onclick}}">
-            <b>{{md-title}}</b>
-          </a>
-        </script>
+Rather than use the toolkit's included AJAX helpers to render record
+details inline, here's a summary template that will link directly to
+the source via the address provided in the metadata as the first
+element of `md-electronic-url`:
 
-For details of Handlebars template syntax, see
-[the online documentation](http://handlebarsjs.com/).
+    <script class="mkws-template-summary" type="text/x-handlebars-template">
+      <a href="{{md-electronic-url.[0]}}">
+        <b>{{md-title}}</b>
+      </a>
+      {{#if md-title-remainder}}
+        <span>{{md-title-remainder}}</span>
+      {{/if}}
+      {{#if md-title-responsibility}}
+        <span><i>{{md-title-responsibility}}</i></span>
+      {{/if}}
+    </script>
 
+For a more involved example where markup for multiple widgets is decorated with
+[Bootstrap](http://getbootstrap.com/) classes and a custom Handlebars helper is
+employed, take a look at the source of
+[topic.html](http://example.indexdata.com/topic.html?q=water).
 
-Responsive design
------------------
 
-Metasearching applications may need to appear differently on
-small-screened mobile devices, or change their appearance when
-screen-width changes (as when a small device is rotated). To achieve
-this, MKWS supports responsive design which will move the termlists to
-the bottom on narrow screens and to the sidebar on wide screens.
+Some Refinements
+================
 
-To turn on this behaviour, set the `responsive_design_width` to the desired
-threshhold width in pixels. For example:
 
-        <script type="text/javascript">
-            var mkws_config = {
-                responsive_design_width: 990
-            };
-        </script>
+Message of the day
+------------------
 
-If individual result-related components are in use in place of the
-all-in-one mkwsResults, then the redesigned application needs to
-specify the locations where the termlists should appear in both
-cases. In this case, wrap the wide-screen `mkwsTermlists` element in a
-`mkwsTermlists-Container-wide` element; and provide an
-`mkwsTermlists-Container-narrow` element in the place where the narrow-screen
-termlists should appear.
+Some applications might like to open with content in the area that
+will subsequently be filled with result-records -- a message of the
+day, a welcome message or a help page. This can be done by placing an
+`mkws-motd` division anywhere on the page. It will initially be moved
+into the `mkws-results` area and displayed, but will be hidden as soon
+as the first search is made.
 
 
 Popup results with jQuery UI
 ----------------------------
 
 The [jQuery UI library](http://en.wikipedia.org/wiki/JQuery_UI)
-can be used to construct MKWS applications in which the only component
+can be used to construct MKWS applications in which the only widget
 generally visible on the page is a search box, and the results appear
 in a popup. The key part of such an application is this invocation of
 the MKWS jQuery plugin:
 
-        <div class="mkwsSearch"></div>
-        <div class="mkwsPopup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-          <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsResults"></div>
-          <div class="mkwsTargets"></div>
-          <div class="mkwsStat"></div>
+        <div class="mkws-search"></div>
+        <div class="mkws-popup" popup_width="1024" popup_height="650">
+          <div class="mkws-results"></div>
         </div>
 
 The necessary scaffolding can be seen in an example application,
-http://example.indexdata.com/index-popup.html
+[popup.html](http://example.indexdata.com/popup.html).
+
+The relevant properties (`popup_width`, etc.) are documented
+[below](#jquery-ui-popup-invocation)
+in the reference section.
 
 
 Authentication and target configuration
 ---------------------------------------
 
-By default, MKWS configures itself to use a demonstration account on a
-service hosted by mkws.indexdata.com. This account (username `demo`,
+MKWS configures itself to use an account on a service hosted by
+`sp-mkws.indexdata.com`. By default, it sends no authentication
+credentials, allowing the appropriate account to be selected on the
+basis of referring URL or IP address.
+
+TODO REWRITE
+This account (username `demo`,
 password `demo`) provides access to about a dozen free data
 sources. Authentication onto this service is via an authentication URL
 on the same MKWS server, so no explicit configuration is needed.
 
 In order to search in a customised set of targets, including
 subscription resources, it's necessary to create an account with
-Index Data's hosted service proxy, and protect that account with
+Index Data's hosted Service Proxy, and protect that account with
 authentication tokens (to prevent unauthorised use of subscription
 resources). For information on how to do this, see the next section.
 
 
-MKWS Target Selection
+MKWS target selection
 =====================
 
 MKWS accesses targets using the Pazpar2 metasearching engine. Although
@@ -325,7 +470,7 @@ available targets to use.
 Maintaining the library
 -----------------------
 
-The service proxy accesses sets of targets that are known as
+The Service Proxy accesses sets of targets that are known as
 "libraries". In general, each customer will have their own library,
 though some standard libraries may be shared between many customers --
 for example, a library containing all open-access academic journals.
@@ -482,7 +627,7 @@ yourname.com:
 Step 1: add a rewriting authentication alias to the configuration:
 
        RewriteEngine on
-       RewriteRule /spauth/ http://mkws.indexdata.com/service-proxy/?command=auth&action=check,login&username=U&password=PW [P]
+       RewriteRule /spauth/ http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=check,login&username=U&password=PW [P]
 
 Step 2: set the MKWS configuration item `service_proxy_auth` to
 <http://yourname.com/spauth/>
@@ -524,10 +669,10 @@ For example, a `Records` widget can be limited to searching only in
 targets that have been categorised as news sources by providing an
 attribute as follows:
 
-       <div class="mkwsRecords" targetfilter='categories=news'/>
+       <div class="mkws-records" targetfilter='categories=news'/>
 
 
-Reference Guide
+Reference guide
 ===============
 
 Configuration object
@@ -544,7 +689,7 @@ reasonably narrow.
 ----
 Element                   Type    Default   Description
 --------                  -----   --------- ------------
-debug_level               int     1         Level of debugging output to emit. 0 = none, 1 = messages, 2 = messages with
+log_level                 int     1         Level of debugging output to emit. 0 = none, 1 = messages, 2 = messages with
                                             datestamps, 3 = messages with datestamps and stack-traces.
 
 facets                    array   *Note 1*  Ordered list of names of facets to display. Supported facet names are
@@ -607,7 +752,7 @@ use_service_proxy         bool    true      If true, then a Service Proxy is use
 
 Perhaps we should get rid of the `show_lang`, `show_perpage`,
 `show_sort` and `show_switch` configuration items, and simply display the relevant menus
-only when their containers are provided -- e.g. an `mkwsLang` element
+only when their containers are provided -- e.g. an `mkws-lang` element
 for the language menu. But for now we retain these, as an easier route
 to lightly customise the display than my changing providing a full HTML
 structure.
@@ -620,9 +765,9 @@ structure.
 
 3. [10, 20, 30, 50]
 
-4. http://mkws.indexdata.com/service-proxy-auth
+4. http://sp-mkws.indexdata.com/service-proxy-auth
 
-5. http://mkws.indexdata.com/service-proxy/
+5. http://sp-mkws.indexdata.com/service-proxy/
 
 6. [["relevance"], ["title:1", "title"], ["date:0", "newest"], ["date:1", "oldest"]]
 
@@ -691,13 +836,13 @@ from that toolkit. The relevant lines are:
     <link rel="stylesheet" type="text/css"
           href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
 
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-popup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
     </div>
 
 ----
@@ -709,7 +854,8 @@ popup_width     string  880                 Width of the popup window (if used),
 popup_height    string  760                 Height of the popup window (if used), in
                                             pixels.
 
-popup_button    string  `input.mkwsButton`  (Never change this.)
+popup_button    string  `input.mkwsButton`  A click on this selector will trigger the
+                                           popup to open
 
 popup_modal     string  0                   Modal confirmation mode. Valid values are 0 or 1
 
@@ -717,15 +863,17 @@ popup_autoOpen  string  1                   Open popup window on load. Valid val
 
 ----
 
+You can have more than one mkws-popup widgets on a page. Please use a different 
+popup_button value to address the right ones.
 
 The structure of the HTML generated by the MKWS widgets
 -------------------------------------------------------
 
 In order to override the default CSS styles provided by the MasterKey Widget
 Set, it's necessary to understand that structure of the HTML elements that are
-generated within the components. This knowledge make it possible, for example,
+generated within the widgets. This knowledge make it possible, for example,
 to style each `<div>` with class `term` but only when it occurs inside an
-element with ID `#mkwsTermlists`, so as to avoid inadvertently styling other
+element with class `mkws-termlists`, so as to avoid inadvertently styling other
 elements using the same class in the non-MKWS parts of the page.
 
 The HTML structure is as follows. As in CSS, #ID indicates a unique identifier
@@ -790,4 +938,4 @@ and .CLASS indicates an instance of a class.
 
 - - -
 
-Copyright (C) 2013-2014 by IndexData ApS, <http://www.indexdata.com>
+Copyright (C) 2013-2014 Index Data ApS. <http://indexdata.com>
diff --git a/doc/tweak-html b/doc/tweak-html
new file mode 100755 (executable)
index 0000000..b12cdec
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Tweak the HTML generated by pandoc into the form we want
+
+cat ${@+"$@"} |
+    sed '/^<col width="[0-9]*%" \/>$/d' |
+    sed 's/<body>/&\
+<img src="images\/mkws-logo-300px.png" alt="MKWS logo"\/>/' | awk '
+/^<(h[12]|div) id/ {
+  if (seen) {
+    print "</div>";
+  }     
+  print "<div class='"'"pane"'"'>";
+  seen = 1;
+}
+/^<hr/ {
+  print "</div>";
+}
+{ print }
+'
index 42f0673..86f7cf2 100644 (file)
@@ -11,7 +11,7 @@
     CustomLog /var/log/apache2/mkws-examples-access.log combined
 
     RewriteEngine on
-    RewriteRule /service-proxy-auth http://mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkws&password=mkws [P]
+    RewriteRule /service-proxy-auth http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkws&password=mkws [P]
     #RewriteLog /var/log/apache2/mkws-examples-rewrite.log
     #RewriteLogLevel 9
 </VirtualHost>
index 7b1b31a..3f3885a 100644 (file)
@@ -1,20 +1,21 @@
 <VirtualHost *:80>
     ServerName x.example.indexdata.com
-    DocumentRoot /usr/local/src/git/mkws/examples/htdocs/
-    Alias /tools/htdocs/ /usr/local/src/git/mkws/tools/htdocs/
-    Alias /src/ /usr/local/src/git/mkws/src/
-    Alias /jasmine/ /usr/local/src/git/mkws/examples/jasmine/
-    Alias /test/ /usr/local/src/git/mkws/test/
+    DocumentRoot /home/mike/git/work/mkws/examples/htdocs/
+    Alias /tools/htdocs/ /home/mike/git/work/mkws/tools/htdocs/
+    Alias /src/ /home/mike/git/work/mkws/src/
+    Alias /jasmine/ /home/mike/git/work/mkws/examples/jasmine/
+    Alias /test/ /home/mike/git/work/mkws/test/
 
     <Directory />
         Allow from all
+       Require all granted
     </Directory>
 
     ErrorLog /var/log/apache2/mkws-examples-error.log
     CustomLog /var/log/apache2/mkws-examples-access.log combined
 
     RewriteEngine on
-    RewriteRule      /service-proxy-auth/ http://mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkws&password=mkws [P]
+    RewriteRule      /service-proxy-auth/ http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkws&password=mkws [P]
     #RewriteLog /var/log/apache2/mkws-examples-rewrite.log
     #RewriteLogLevel 9
 </VirtualHost>
diff --git a/examples/apache2/mkws-examples-mike-mac b/examples/apache2/mkws-examples-mike-mac
new file mode 100644 (file)
index 0000000..1f0ae6d
--- /dev/null
@@ -0,0 +1,20 @@
+<VirtualHost *:80>
+    ServerName x.example.indexdata.com
+    DocumentRoot /Users/mike/git/work/mkws/examples/htdocs/
+    Alias /tools/htdocs/ /Users/mike/git/work/mkws/tools/htdocs/
+    Alias /src/ /Users/mike/git/work/mkws/src/
+    Alias /jasmine/ /Users/mike/git/work/mkws/examples/jasmine/
+    Alias /test/ /Users/mike/git/work/mkws/test/
+
+    <Directory />
+        Allow from all
+    </Directory>
+
+    ErrorLog /var/log/apache2/mkws-examples-error.log
+    CustomLog /var/log/apache2/mkws-examples-access.log combined
+
+    RewriteEngine on
+    RewriteRule      /service-proxy-auth/ http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkws&password=mkws [P]
+    #RewriteLog /var/log/apache2/mkws-examples-rewrite.log
+    #RewriteLogLevel 9
+</VirtualHost>
index 418b161..164c006 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
 
 all: apache-config.txt
 
index e89cf48..a3d9d7a 100644 (file)
@@ -6,7 +6,7 @@
     <title>MKWS demo: Async feeling.</title>
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="http://mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="http://mkws.indexdata.com/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="http://mkws.indexdata.com/pazpar2/js/pz2.js"></script>
     <script type="text/javascript" src="http://mkws.local/mkws.js"></script>
     <link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />
   <body>
     <div id="first"></div>
     <script type="text/javascript">
-      $("#first").html("<div class='mkwsReference' autosearch='one' sentences='1'>result will appear here</div>");
+      $("#first").html("<div class='mkws-reference' autosearch='one' sentences='1'>result will appear here</div>");
       mkws.init("First div", "#first");
     </script>
     <div id="second"></div>
     <script type="text/javascript">
-      $("#second").html("<div class='mkwsReference' autosearch='two' sentences='1'>result will appear here</div>");
+      $("#second").html("<div class='mkws-reference' autosearch='two' sentences='1'>result will appear here</div>");
       mkws.init("Second div", document.getElementById("second"));
     </script>
     <div id="third"></div>
     <script type="text/javascript">
-      $("#third").html("<div class='mkwsReference' autosearch='three' sentences='1'>result will appear here</div>");
+      $("#third").html("<div class='mkws-reference' autosearch='three' sentences='1'>result will appear here</div>");
       mkws.init("Third div", "#third");
     </script>
-    <div class='mkwsReference' autosearch='four' sentences='1'>This would have been four but we're not searching it.</div>
+    <div class='mkws-reference' autosearch='four' sentences='1'>This would have been four but we're not searching it.</div>
   </body>
 </html>
index 24f14cc..0a7dbe5 100644 (file)
@@ -2,13 +2,13 @@
   <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
   <script type="text/javascript">
     mkws_config = {
-      service_proxy_auth: "http://mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc",
+      service_proxy_auth: "http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc",
       perpage_default: 5,
    };
   </script>
   <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   <div style="width: 30em; background: #f0f0f0">
     <h2>Reference results from Paratext</h2>
-    <div class='mkwsRecords' autosearch='!param!q' sort='position'></div>
+    <div class='mkws-records' autosearch='!param!q' sort='position'></div>
   </div>
 </html>
index b7c0b88..6e0d498 100644 (file)
@@ -3,18 +3,18 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: Automatic search</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript">
       mkws_config = {
-        service_proxy_auth: "http://mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc",
+        service_proxy_auth: "http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc",
        perpage_default: 5,
      };
     </script>
     <script type="text/javascript" src="//code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="//mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="//mkws.indexdata.com/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="//mkws.indexdata.com/pazpar2/js/pz2.js"></script>
     <script type="text/javascript" src="//mkws.indexdata.com/mkws.js"></script>
     <style type="text/css">
@@ -49,7 +49,7 @@
 
     <div class="panel">
       <h2>Reference results from Paratext</h2>
-      <div class='mkwsRecords' autosearch='!param!q' sort='position'></div>
+      <div class='mkws-records' autosearch='!param!q' sort='position'></div>
     </div>
 
     <div class="entrybody">
index 21ab5b2..e133454 100644 (file)
@@ -3,7 +3,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: Automatic search</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
          <h2>News</h2>
 
 
-<div class='mkwsRecords'
-       autosearch='mike'
+<div class='mkws-records'
+       autosearch='sushi'
        sort='relevance'
-       targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware'
+       targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware|lui.indexdata.com:8080/solr4/select?fq=database:3602'
 >results will appear here</div>
 
-
        </td>
       </tr>
     </table>
     <p style="color:grey">
       <a href="http://mkws.indexdata.com/">About MKWS</p>
     </p>
+    <script type="text/javascript">
+      var mkws_config = {
+        sp_auth_credentials: "mkwstest/mkwstest"
+      };
+    </script>
   </body>
 </html>
index bb53d7e..6d83894 100644 (file)
@@ -3,7 +3,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: Multiple automatic searches</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
@@ -24,7 +24,7 @@
        </td>
        <td>
          <h2>News</h2>
-<div class='mkwsRecords mkwsTeam_news'
+<div class='mkws-records mkws-team-news'
        autosearch='museum'
        sort='relevance'
        targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware'
@@ -32,7 +32,7 @@
        </td>
        <td>
          <h2>Blog</h2>
-<div class='mkwsRecords mkwsTeam_blog'
+<div class='mkws-records mkws-team-blog'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware'
index 4fef994..6df7364 100644 (file)
@@ -3,7 +3,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: Multiple automatic searches</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
@@ -35,7 +35,7 @@
       <tr>
        <td style="background: #f8f8e0">
          <h2>PLOS ONE</h2>
-<div class='mkwsRecords mkwsTeam_plos'
+<div class='mkws-records mkws-team-plos'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id=lui.indexdata.com:8080/solr4/select?fq=database:6265/'
@@ -43,7 +43,7 @@
        </td>
        <td style="background: #e0f8f0">
          <h2>Project Gutenberg</h2>
-<div class='mkwsRecords mkwsTeam_gutenberg'
+<div class='mkws-records mkws-team-gutenberg'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id=lui.indexdata.com:8080/solr4/select?fq=database:3552/'
@@ -51,7 +51,7 @@
        </td>
        <td style="background: #e0f0f8">
          <h2>Library of Congress</h2>
-<div class='mkwsRecords mkwsTeam_blog'
+<div class='mkws-records mkws-team-blog'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id=lui.indexdata.com:8080/solr4/select?fq=database:5802/'
index c26f1ab..0a36825 100644 (file)
@@ -6,13 +6,13 @@
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsProgress"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults" autosearch="!param!q" target="!param!t"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results" autosearch="!param!q" target="!param!t"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index 9aac803..efcd608 100644 (file)
@@ -4,13 +4,13 @@
     <title>Dictionary lookup demo</title>\r
     <script type="text/javascript">\r
       var mkws_config = {\r
-            //responsive_design_width: 990\r
-            //perpage_default: 10,\r
-            service_proxy_auth: "//mkws.indexdata.com/service-proxy/?command=auth&action=login&username=dic&password=dic"\r
-        };\r
+       sp_auth_credentials: "mkwsdict/mkwsdict"\r
+      };\r
     </script>\r
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />\r
+    <link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />\r
     <script src="//mkws.indexdata.com/mkws-complete.js"></script>\r
+    <script>$ = jQuery = mkws.$; </script>\r
   </head>\r
   <body>\r
 \r
        <p>Conventionally, a computer consists of at least one processing element, typically a <a href="http://en.wikipedia.org/wiki/Central_processing_unit" title="Central processing unit">central processing unit</a> (CPU) and some form of <a href="http://en.wikipedia.org/wiki/Memory_(computers)" title="Memory (computers)" class="mw-redirect">memory</a>. The processing element carries out arithmetic and logic operations, and a sequencing and control unit that can change the order of operations based on stored information. Peripheral devices allow information to be retrieved from an external source, and the result of operations saved and retrieved.</p>\r
        <p>In <a href="http://en.wikipedia.org/wiki/World_War_II" title="World War II">World War II</a>, <a href="http://en.wikipedia.org/wiki/Mechanical_computer" title="Mechanical computer">mechanical</a> <a href="http://en.wikipedia.org/wiki/Analog_computers" title="Analog computers" class="mw-redirect">analog computers</a> were used for specialized military applications. During this time the first electronic <a href="http://en.wikipedia.org/wiki/Digital_data" title="Digital data">digital</a> computers were developed. Originally they were the size of a large room, consuming as much power as several hundred modern <a href="http://en.wikipedia.org/wiki/Personal_computer" title="Personal computer">personal computers</a> (PCs).<sup id="cite_ref-1" class="reference"><a href="http://en.wikipedia.org/wiki/Computer#cite_note-1"><span>[</span>1<span>]</span></a></sup></p>\r
        <p>Modern computers based on <a href="http://en.wikipedia.org/wiki/Integrated_circuit" title="Integrated circuit">integrated circuits</a> are millions to billions of times more capable than the early machines, and occupy a fraction of the space.<sup id="cite_ref-2" class="reference"><a href="http://en.wikipedia.org/wiki/Computer#cite_note-2"><span>[</span>2<span>]</span></a></sup> Simple computers are small enough to fit into <a href="http://en.wikipedia.org/wiki/Mobile_device" title="Mobile device">mobile devices</a>, and <a href="http://en.wikipedia.org/wiki/Mobile_computing" title="Mobile computing">mobile computers</a> can be powered by small <a href="http://en.wikipedia.org/wiki/Battery_(electricity)" title="Battery (electricity)">batteries</a>. Personal computers in their various forms are <a href="http://en.wikipedia.org/wiki/Icon" title="Icon">icons</a> of the <a href="http://en.wikipedia.org/wiki/Information_Age" title="Information Age">Information Age</a> and are what most people think of as “computers.” However, the <a href="http://en.wikipedia.org/wiki/Embedded_system" title="Embedded system">embedded computers</a> found in many devices from <a href="http://en.wikipedia.org/wiki/Digital_audio_player" title="Digital audio player" class="mw-redirect">MP3 players</a> to <a href="http://en.wikipedia.org/wiki/Fighter_aircraft" title="Fighter aircraft">fighter aircraft</a> and from toys to <a href="http://en.wikipedia.org/wiki/Industrial_robot" title="Industrial robot">industrial robots</a> are the most numerous.</p>\r
+       </div>\r
       </td>\r
       <td width="40%" align="top">\r
-       <div class="mkwsSearch"></div>\r
-       <div class="mkwsRecords"></div>\r
+       <div class="mkws-search"></div>\r
+       <div class="mkws-reference"></div>\r
+       <div class="search-query"></div>\r
       </td>\r
     </tr>\r
   </table>\r
-    <script type="text/javascript">\r
-      $(".mkwsSearch").hide();\r
 \r
-      document.onclick = clickfunc;\r
-      var selectedtext="";\r
-      var clicking = false;\r
-      function clickfunc(e) {\r
-        var sel = window.getSelection();\r
-        //console.log("click: " + sel + "  clicking=" + clicking );\r
-        if ( sel != "" && ! clicking ) {\r
-          clicking  = true;\r
-          $("input.mkwsQuery").val(sel);\r
-          //console.log("click: Set value " + sel + "  clicking=" + clicking );\r
-          $("input.mkwsButton").trigger("click");\r
-          clicking = false;\r
-        }\r
+  <script>\r
+    $(".mkws-search").hide();\r
+    $(".mkws-reference").hide();\r
+\r
+    if(!window.indexdata){\r
+      indexdata = {};\r
+    }\r
+\r
+    indexdata.Selector = { 'debug': false, 'clicking': false };\r
+\r
+    indexdata.Selector.getSelected = function(){\r
+      var t = '';\r
+      if(window.getSelection){\r
+       t = window.getSelection();\r
+      }else if(document.getSelection){\r
+       t = document.getSelection();\r
+      }else if(document.selection){\r
+       t = document.selection.createRange().text;\r
       }\r
-    </script>\r
+      return t;\r
+    };\r
+\r
+    indexdata.Selector.mouseup = function(){\r
+      var text = indexdata.Selector.getSelected();\r
+      if(text != ''){\r
+       if (indexdata.Selector.debug) {\r
+         alert("You selected:\n" + text);\r
+       }\r
+       indexdata.Selector.mkws(text);\r
+      }\r
+    };\r
+\r
+    indexdata.Selector.mkws = function(query) {\r
+      if ( query != "" && ! indexdata.Selector.clicking ) {\r
+       // no recursive calls\r
+       indexdata.Selector.clicking  = true;\r
+\r
+       $(".mkws-reference").show();\r
+       $("input.mkws-query").val(query);\r
+       $(".search-query").text(query);\r
+       $("input.mkws-button").trigger("click");\r
+       indexdata.Selector.clicking = false;\r
+      }\r
+    };\r
+\r
+    $(document).ready(function(){\r
+      $(document).bind("mouseup", indexdata.Selector.mouseup);\r
+    });\r
+\r
+  </script>\r
   </body>\r
 </html>\r
index 10a2a82..aa53154 100644 (file)
@@ -9,22 +9,22 @@
           //show_sort: false,
           //perpage_default: 10,
           //sort_default: "title:1",
-          //debug_level: 1
+          //log_level: 1
       };
     </script>
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
     <script type="text/javascript" src="tools/htdocs/mkws.js"></script>
 
     <style type="text/css">
-      .mkwsTermlists div.facet {
+      .mkws-termlists div.facet {
       float:left;
       width: 30%;
       margin: 0.3em;
       }
-      .mkwsStat {
+      .mkws-stat {
       text-align: right;
       }
     </style>
@@ -32,9 +32,9 @@
   </head>
   <body>
     <h1>Heikkis test for the MOTD</h1>
-    <div class="mkwsMOTD">This is the mkwsMOTD div </div>
+    <div class="mkws-motd">This is the mkws-motd div </div>
     <br/>The MOTD should not be visible above this line.
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
   </body>
 </html>
index 5cebd8f..8a92369 100644 (file)
     </script>
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
     <script type="text/javascript" src="tools/htdocs/mkws.js"></script>
     <style type="text/css">
-      .mkwsTermlists div.facet {
+      .mkws-termlists div.facet {
       float:left;
       width: 30%;
       margin: 0.3em;
       }
-      .mkwsStat {
+      .mkws-stat {
       text-align: right;
       }
     </style>
   </head>
   <body>
     <h1>Heikki's test</h1>
-    <div class="mkwsMOTD">Welcome to Heikki's little test</div>
+    <div class="mkws-motd">Welcome to Heikki's little test</div>
     <table width="100%" border="0">
       <tr>
         <td>
-         <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
+         <div class="mkws-switch"></div>
+          <div class="mkws-lang"></div>
+          <div class="mkws-search"></div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
+            <div class="mkws-pager"></div>
+            <div class="mkws-navi"></div>
+            <div class="mkws-records"></div>
+            <div class="mkws-targets"></div>
+            <div class="mkws-ranking"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
+            <div class="mkws-termlists"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
-          <div class="mkwsStat"></div>
+          <div class="mkws-stat"></div>
         </td>
       </tr>
     </table>
index ff92c1e..6d4f8c8 100644 (file)
@@ -4,27 +4,35 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo: Images</title>
-    <link rel="stylesheet" type="text/css" href="http://mkws.indexdata.com/mkws.css" />
-    <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
-    <script class="mkwsTemplate_Summary" type="text/x-handlebars-template">
-      <a href="#" id="{{_id}}" onclick="{{_onclick}}">
-        {{#each md-thumburl}}
-         <img src="{{this}}" alt="{{../md-title}}"/>
-        {{/each}}
-       <br/>
-       {{md-title}}
-      {{#if md-title-remainder}}
-        <span>{{md-title-remainder}}</span>
-      {{/if}}
-      {{#if md-title-responsibility}}
-       <span><i>{{md-title-responsibility}}</i></span>
-      {{/if}}
-      </a>
+    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
+    <script type="text/javascript" src="//x.mkws.indexdata.com/mkws-complete.js"></script>
+    <script class="mkws-template-records" type="text/x-handlebars-template">
+      {{#each hits}}
+        <div class="{{containerClass}}">
+          <a href="#" id="{{detailLinkId}}" onclick="{{detailClick}}">
+            {{#each md-thumburl}}
+              <img src="{{this}}" alt="{{../md-title}}"/>
+            {{/each}}
+            <br/>
+            {{md-title}}
+          {{#if md-title-remainder}}
+            <span>{{md-title-remainder}}</span>
+          {{/if}}
+          {{#if md-title-responsibility}}
+            <span><i>{{md-title-responsibility}}</i></span>
+          {{/if}}
+          </a>
+        </div>
+      {{/each}}
+    </script>
+    <script type="text/javascript">
+      var mkws_config = {
+        sp_auth_credentials: "mkwsimages/mkwsimages"
+      };
     </script>
   </head>
   <body>
-    <div class='mkwsRecords' autosearch='!param!q'
-       targets='pz:id=lui.indexdata.com:8080/solr4/#5853'
-       >results will appear here</div>
+    <div class='mkws-records' autosearch='!param!q'
+        >results will appear here</div>
   </body>
 </html>
index e54fe2c..ed61a49 100644 (file)
@@ -3,7 +3,7 @@
   List to follow ...
 </p>
 <p>
-  In the mean time see the links from
-  <a href="http://mkws.indexdata.com/"
-                 >mkws.indexdata.com</a>
+  In the mean time see
+  <a href="http://mkws.indexdata.com/index.html#examples-using-the-widget-set"
+       >the examples from the widget-set documentation</a>
 </p>
index 8f97ab5..59ecd50 100644 (file)
@@ -1,15 +1,15 @@
 <html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>MKWS demo: Reference Universe widget</title>
-    <link rel="stylesheet" type="text/css" href="mkws-widget-credo.css" />
+    <title>MKWS demo: heading changes when search results appear</title>
     <script type="text/javascript">
-      var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-credoauth" };
+      var mkws_config = { sp_auth_credentials: "credo/emu" };
     </script>
-    <script type="text/javascript" src="//code.jquery.com/jquery-1.10.0.min.js"></script>
-    <script type="text/javascript" src="//x.mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="//x.mkws.indexdata.com/handlebars-v1.1.2.js"></script>
-    <script type="text/javascript" src="//x.mkws.indexdata.com/pazpar2/js/pz2.js"></script>
+    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
+    <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
+    <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
+    <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-team.js"></script>
@@ -23,7 +23,7 @@
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
-    <script type="text/javascript" src="mkws-widget-credo.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
   </head>
   <body>
     <script type="text/javascript">
       });
      });
     </script>
-    <div class="mkwsIntro">Starting the MKWS metasearch widget</div>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-intro">Starting the MKWS metasearch widget</div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index 846352d..60ff861 100644 (file)
     <script type="text/javascript" src="http://mkws-origin/mkws-complete.js"></script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
   </body>
 </html>
index a910bee..03c1e79 100644 (file)
 
     <script type="text/javascript">
     var mkws_config = {
-      service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth",
+      service_proxy_auth: "//sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkwstest&password=mkwstest",
       perpage_default: 10
     };
 
     var jasmine_config = {
-      search_query: "netbsd",
-      expected_hits: 10,
+      search_query: "freebsd",
+      expected_hits: 20,
       check_motd: false,
       show_record_url: true
     };
 
     <h2>MKWS Jasmine regression tests</h2>
 
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsProgress"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
-      <div class="mkwsBuilder"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-popup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkws-button">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-progress"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
+      <div class="mkws-builder"></div>
     </div>
 
       <!-- include jquery again -->
index d5758b3..6bc7355 100644 (file)
     <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
 
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-team.js"></script>
     <script type="text/javascript" src="src/mkws-filter.js"></script>
-    <script type="text/javascript" src="src/mkws-popup.js"></script>
     <script type="text/javascript" src="src/mkws-widget.js"></script>
     <script type="text/javascript" src="src/mkws-widget-main.js"></script>
     <script type="text/javascript" src="src/mkws-widget-termlists.js"></script>
@@ -26,6 +25,8 @@
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
+    <script type="text/javascript" src="src/mkws-popup.js"></script>
 
     <link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-1.3.1/jasmine_favicon.png">
     <link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-1.3.1/jasmine.css">
@@ -54,8 +55,8 @@
     };
 
     var jasmine_config = {
-      search_query: "netbsd",
-      expected_hits: 10,
+      search_query: "freebsd",
+      expected_hits: 20,
       active_clients: 13,
       check_motd: false,
       check_sortby: true,
 
     </script>
 
-<h2>MKWS Jasmine regression tests</h2>
+    <h2>MKWS Jasmine regression tests</h2>
 
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-popup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkws-button">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
     </div>
 
   </body>
index b2c7450..9c6eb86 100644 (file)
     <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
 
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-team.js"></script>
     <script type="text/javascript" src="src/mkws-filter.js"></script>
-    <script type="text/javascript" src="src/mkws-popup.js"></script>
     <script type="text/javascript" src="src/mkws-widget.js"></script>
     <script type="text/javascript" src="src/mkws-widget-main.js"></script>
     <script type="text/javascript" src="src/mkws-widget-termlists.js"></script>
@@ -26,6 +25,8 @@
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
+    <script type="text/javascript" src="src/mkws-popup.js"></script>
 
     <link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-1.3.1/jasmine_favicon.png">
     <link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-1.3.1/jasmine.css">
     // use a our main service proxy with mkws test account
     var mkws_config = {
       perpage_default: 10,
-      pazpar2_url:          "//mkws.indexdata.com/service-proxy/",
-      service_proxy_auth:   "//mkws.indexdata.com/service-proxy-testauth"
+      sp_auth_credentials: "mkwstest/mkwstest"
     };
 
     var jasmine_config = {
-      search_query: "netbsd",
-      expected_hits: 10,
+      search_query: "freebsd",
+      expected_hits: 20,
       active_clients: 13,
       check_motd: false,
       show_record_url: true
     };
     </script>
 
-<h2>MKWS Jasmine regression tests</h2>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
-    </div>
 
+    <h2>MKWS Jasmine regression tests</h2>
+    <div class="mkws-search"></div>
+    <div class="mkws-popup" popup_width="990" popup_height="760" popup_modal="0" popup_autoOpen="0" popup_button="input.mkws-button">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
+    </div>
 
   </body>
 </html>
index 3fea281..dbe236a 100644 (file)
     </script>
     <script type="text/javascript" src="//code.jquery.com/jquery-1.7.2.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
     <script type="text/javascript" src="tools/htdocs/mkws.js"></script>
 
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <style type="text/css">
-      .mkwsTermlists div.facet {
+      .mkws-termlists div.facet {
       float:left;
       width: 30%;
       margin: 0.3em;
       }
-      .mkwsStat {
+      .mkws-stat {
       text-align: right;
       }
     </style>
     <table width="100%" border="0">
       <tr>
         <td>
-          <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
+          <div class="mkws-switch"></div>
+          <div class="mkws-lang"></div>
+          <div class="mkws-search"></div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
+            <div class="mkws-pager"></div>
+            <div class="mkws-navi"></div>
+            <div class="mkws-records"></div>
+            <div class="mkws-targets"></div>
+            <div class="mkws-ranking"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
+            <div class="mkws-termlists"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
-          <div class="mkwsStat"></div>
+          <div class="mkws-stat"></div>
         </td>
       </tr>
     </table>
 
-    <div id="testMOTD"><div class="mkwsMOTD">This is the mkwsMOTD div</div></div>
+    <div id="testMOTD"><div class="mkws-motd">This is the mkws-motd div</div></div>
   </body>
 </html>
index afbe943..86305c5 100644 (file)
@@ -3,28 +3,15 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo jasmine test framework</title>
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
+
     <script type="text/javascript">
       var mkws_config = {
-         pazpar2_url : "//mkws.indexdata.com/service-proxy/",
-         service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth",
-         perpage_default: 10
+       sp_auth_credentials: "mkwstest/mkwstest",
+       perpage_default: 10
       };
     </script>
-    <script type="text/javascript" src="//code.jquery.com/jquery-1.7.2.min.js"></script> 
-    <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="tools/htdocs/mkws.js"></script>
-    <style type="text/css">
-      .mkwsTermlists div.facet {
-      float:left;
-      width: 30%;
-      margin: 0.3em;
-      }
-      .mkwsStat {
-      text-align: right;
-      }
-    </style>
+
+    <script type="text/javascript" src="tools/htdocs/mkws-complete.min.js"></script>
 
   <!-- SECTION jasmine -->
     <link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-1.3.1/jasmine_favicon.png">
   <!-- EOF jasmine -->
 
   </head>
-  <body>
-    <div id="testMOTD"><div class="mkwsMOTD">This is the mkwsMOTD div</div></div>
-    <table width="100%" border="0">
-      <tr>
-        <td>
-          <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div class="mkwsStat"></div>
-        </td>
-      </tr>
-    </table>
 
+  <body>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
+    <div class="mkws-motd"></div>
   </body>
 </html>
index 265f7ec..d24e017 100644 (file)
@@ -3,13 +3,13 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2014 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2014 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: full configuration</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript">
        var mkws_config = {
                lang: "da",
-               debug_level: 1,
+               log_level: 1,
                use_service_proxy: true,
                show_lang: true,
                sort_default: "relevance",
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsMOTD">
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-motd">
       <p>
        <b>Welcome to the MasterKey Widget Set demo.</b>
       </p>
@@ -79,7 +79,7 @@
       </p>
     </div>
     <div id="footer">
-      <div class="mkwsStat"></div>
+      <div class="mkws-stat"></div>
       <span>Powered by MKWS &copy; 2013-2014 <a target="_new" href="http://www.indexdata.com">Index Data</a></span>
     </div>
   </body>
index 3c5f5b0..27336ef 100644 (file)
@@ -3,12 +3,12 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: Mike's playground</title>
     <link rel="stylesheet" type="text/css" href="http://x.mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="http://x.mkws.indexdata.com/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="http://x.mkws.indexdata.com/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/pazpar2/js/pz2.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/mkws.js"></script>
     <style type="text/css">
        </td>
        <td width="30%">
          <h2>News</h2>
-<div class='mkwsRecords mkwsTeam_news'
+<div class='mkws-records mkws-team-news'
        autosearch='museum'
        sort='relevance'
        targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware'
 >News will appear here</div>
-       <div class='mkwsTermlists mkwsTeam_news'/>
+       <div class='mkws-termlists mkws-team-news'/>
        </td>
        <td width="30%">
          <h2>Blog</h2>
-<div class='mkwsRecords mkwsTeam_blog'
+<div class='mkws-records mkws-team-blog'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id~josiah.brown.edu:210/innopac|connect.indexdata.com:9000/mit_opencourseware'
 >Blog entries will appear here</div>
-       <div class='mkwsTermlists mkwsTeam_blog'/>
+       <div class='mkws-termlists mkws-team-blog'/>
        </td>
       </tr>
     </table>
index cb496db..9452025 100644 (file)
@@ -7,7 +7,7 @@
     <link rel="stylesheet" type="text/css" href="http://x.mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="http://x.mkws.indexdata.com/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="http://x.mkws.indexdata.com/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/pazpar2/js/pz2.js"></script>
     <script type="text/javascript" src="http://x.mkws.indexdata.com/mkws.js"></script>
     <style type="text/css">
@@ -38,7 +38,7 @@
       <tr>
        <td style="background: #f8f8e0">
          <h2>PLOS ONE</h2>
-<div class='mkwsRecords mkwsTeam_plos'
+<div class='mkws-records mkws-team-plos'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id~lui.indexdata.com:8080/solr4/#6265'
@@ -46,7 +46,7 @@
        </td>
        <td style="background: #e0f8f0">
          <h2>Project Gutenberg</h2>
-<div class='mkwsRecords mkwsTeam_gutenberg'
+<div class='mkws-records mkws-team-gutenberg'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id~lui.indexdata.com:8080/solr4/#3552'
@@ -54,7 +54,7 @@
        </td>
        <td style="background: #e0f0f8">
          <h2>Library of Congress</h2>
-<div class='mkwsRecords mkwsTeam_blog'
+<div class='mkws-records mkws-team-blog'
        autosearch='dinosaur'
        sort='relevance'
        targets='pz:id~lui.indexdata.com:8080/solr4/#5802'
index 239a5e8..e1e9b72 100644 (file)
@@ -6,19 +6,20 @@
     <script type="text/javascript">
       var mkws_config = {
         service_proxy_auth: "http://example.indexdata.com/service-proxy-auth/",
-        service_proxy_auth_domain : "mkws.indexdata.com"
+        service_proxy_auth_domain : "sp-mkws.indexdata.com"
       };
       // See also the Apache2 RewriteRule needed to make this work:
       // http://example.indexdata.com/apache-config.txt
     </script>
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
   </body>
 </html>
index 512c990..727fdd7 100644 (file)
@@ -4,10 +4,10 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo: LOLcat demo</title>
-    <link rel="stylesheet" type="text/css" href="http://mkws.indexdata.com/mkws.css" />
+    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript">mkws_config = { perpage_default: 1 }</script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
-    <script class="mkwsTemplate_Summary" type="text/x-handlebars-template">
+    <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+    <script class="mkws-template-summary" type="text/x-handlebars-template">
       <a href="#" id="{{_id}}" onclick="{{_onclick}}">
         {{#mkws-first md-thumburl}}
          <img src="{{this}}" alt="{{../md-title}}"/>
@@ -17,7 +17,7 @@
     </script>
   </head>
   <body>
-    <div class='mkwsRecords' autosearch='cat' sort='date:0'
+    <div class='mkws-records' autosearch='cat' sort='date:0'
        targets='pz:id=localhost:9003/flickr_api'
        >kitteh will appear here</div>
   </body>
index f8b417f..ebf4043 100644 (file)
@@ -5,12 +5,12 @@
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
     <style type="text/css">
-      .mkwsTermlists div.facet {
+      .mkws-termlists div.facet {
       float:left;
       width: 30%;
       margin: 0.3em;
       }
-      .mkwsStat {
+      .mkws-stat {
       text-align: right;
       }
     </style>
     <table width="100%" border="0">
       <tr>
         <td>
-          <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
+          <div class="mkws-switch"></div>
+          <div class="mkws-lang"></div>
+          <div class="mkws-search"></div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
+            <div class="mkws-pager"></div>
+            <div class="mkws-navi"></div>
+            <div class="mkws-records"></div>
+            <div class="mkws-targets"></div>
+            <div class="mkws-ranking"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
           <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
+            <div class="mkws-termlists"></div>
           </div>
         </td>
       </tr>
       <tr>
         <td>
-          <div class="mkwsStat"></div>
+          <div class="mkws-stat"></div>
         </td>
       </tr>
     </table>
index 198cc44..ee5e03d 100644 (file)
@@ -2,20 +2,15 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo</title>
-    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <script type="text/javascript">
       var mkws_config = {
-        // For now, we have to provide known-bad credentials to skip user/pw login: see bug MKSP-125
-        // Was: //sp-mkws.indexdata.com/service-proxy/?command=auth&action=perconfig&username=XXX&password=XXX
-//        pp2_hostname: "sp-mkws.indexdata.com",
-//        sp_auth_path: "service-proxy/",
-//        sp_auth_query: "command=auth&action=perconfig",
-//        sp_auth_credentials: "XXX/XXX",
-      };
+        sp_auth_credentials: "mkwstest/mkwstest"
+      }
     </script>
+    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
-    <script type="text/javascript" src="mkws-widget-credo.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
   </head>
   <body>
-    <div class="mkwsAuthname"></div>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsProgress"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-auth-name"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang" data-mkws-config='{ "lang_options": [ "en", "da" ] }'></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index 188cbc2..6f1387b 100644 (file)
@@ -1,16 +1,16 @@
 <html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>MKWS demo: Reference Universe widget</title>
-    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
+    <title>MKWS demo</title>
     <script type="text/javascript">
       var mkws_config = {
-        service_proxy_auth: "//mkws.indexdata.com/service-proxy/?command=auth&action=check,login&username=mkwstest&password=mkwstest"
-      };
+        sp_auth_credentials: "mkwstest/mkwstest"
+      }
     </script>
-    <script type="text/javascript" src="//code.jquery.com/jquery-1.10.0.min.js"></script>
+    <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
+    <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
-    <script type="text/javascript" src="mkws-widget-credo.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsProgress"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults" autosearch="!param!q" targets="!param!t"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-auth-name mkws-team-bar"></div>
+    <div class="mkws-switch mkws-team-bar"></div>
+    <div class="mkws-lang mkws-team-bar"></div>
+    <div class="mkws-progress mkws-team-bar"></div>
+    <div class="mkws-search mkws-team-bar"></div>
+    <div class="mkws-results mkws-team-bar"></div>
+    <div class="mkws-targets mkws-team-bar"></div>
+    <div class="mkws-stat mkws-team-bar"></div>
+    <div class="mkws-builder mkws-team-bar"></div>
   </body>
-  <script class="mkwsTemplate_facetTitle-Sources" type="text/x-handlebars-template">
-    <a href="?q={{query}}">Targets</a>
-  </script>
-  <script class="mkwsTemplate_facet-Sources" type="text/x-handlebars-template">
-    <a href="mike2.html?q={{query}}&t={{field}}">{{term}}</a>
-    <span>{{count}}</span>
-  </script>
 </html>
index b95069a..37a783c 100644 (file)
@@ -1,3 +1,3 @@
 <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
-<div class="mkwsSearch"></div>
-<div class="mkwsResults"></div>
+<div class="mkws-search"></div>
+<div class="mkws-results"></div>
diff --git a/examples/htdocs/mkws-widget-credo-bs.js b/examples/htdocs/mkws-widget-credo-bs.js
deleted file mode 100644 (file)
index 49651ea..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// The Google Images database returns links like:
-//      http://images.google.com/url?q=http://eofdreams.com/fish.html&sa=U&ei=RAB-U9XNDo2Dqga1o4L4Bw&ved=0CC4Q9QEwAA&usg=AFQjCNFhRtn6GMevHbpITZ6kfx6rsHV2ow
-// This Handlebars helper avoids a pointless redirect by transforming
-// this to the URL of the underling page, in this case
-//      http://eofdreams.com/fish.html
-//
-Handlebars.registerHelper('mkws-googleurl', function(obj) {
-  if (!obj) {
-    return "obj undefined";
-  } else if (!obj[0]) {
-    return "obj[0] undefined, JSON=" + $.toJSON(obj);
-  } else {
-    return mkws.getParameterByName('q', obj[0]);
-  }
-});
-
-
-// ### This works inefficiently by having multiple teams all run the
-// same search against different sets of targets. A much better
-// approach would be run a single search, with all these panels
-// members of the same team, but picking out only the results relevant
-// to them. That will be more work.
-
-mkws.registerWidgetType('Credo', function() {
-  var that = this;
-
-  this.team.registerTemplate('CredoImage', '\
-      <div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">\
-       <a href="{{mkws-googleurl md-electronic-url}}" target="_blank">\
-        {{#mkws-first md-thumburl}}\
-         <img src="{{this}}" alt="{{../md-title}}"/>\
-        {{/mkws-first}}\
-       <br/>\
-       </a>\
-       <p>{{{md-title}}}</p>\
-      </div>\
-');
-
-  var s = []
-  // Main panel: encylopaedia and images on the left, topics on the right
-  s.push('<div class="row">');
-
-  s.push('<div class="jumbotron panel col-md-8"><div class="panel-body">');
-  //s.push(section('encyclopaedia', 'Topic Page: <span class="x-mkws-title"/>',
-  s.push(this.subwidget('Reference', { _team: 'ref', paragraphs: 1 }));
-  // The Images widget needs to be in our team so we can set its template
-  s.push('</div></div>');
-
-  s.push('<div class="col-md-4">');
-  s.push(section('topics', 'Related Topics',
-                 this.subwidget('Facet', { _team: 'main', facet: 'subject' })));
-  s.push('</div>');
-
-  s.push('</div>');
-  
-  s.push('<div class="row">');
-  s.push(section('image col-md-12', 'Images', this.subwidget('GoogleImage', { maxrecs: 4, template: 'CredoImage', target: 'google_images_js' })));
-  s.push('</div>');
-  
-
-  s.push('<div class="row clearfix">');
-  s.push(section('entries clearfix col-md-4 col-sm-6', 'News',
-                 this.subwidget('Records', { _team: 'news', targetfilter: 'categories=news', perpage: 10 })));
-  s.push(section('articles clearfix col-md-4 col-sm-6', 'Articles',
-                    this.subwidget('Records', { _team: 'articles', targetfilter: 'categories=articles', perpage: 10 })));
-  s.push(section('books clearfix col-md-4 col-sm-6', 'Books',
-                    this.subwidget('Records', { _team: 'books', targetfilter: 'categories=books', perpage: 10 })));
-  s.push(section('news col-md-4 col-sm-6', 'Results from all targets',
-                    this.subwidget('Records', { _team: 'main' })));
-  s.push('</div>');
-  this.node.html(s.join(''));
-
-  // Fill in the titles from the query once widgets have all been prepared
-  var that = this;
-  this.team.queue("ready").subscribe(function() {
-    var query = toTitleCase(that.config.query);
-    that.log("got query '" + query + "' from team config");
-    mkws.$('.x-mkws-title').html(query);
-    mkws.$('title').html("MKWS: " + query);
-
-    mkws.$(".mkwsSummary img").addClass("media-object");
-    console.log(mkws.$("body").html());
-
-    // Derived from http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
-    function toTitleCase(str) {
-      return str.replace(/\w\S*/g, function(txt) {
-        return txt.charAt(0).toUpperCase() + txt.substr(1);
-      });
-    }
-  });
-
-
-  function section(xclass, title, content) {
-    var s = [];
-    s.push('<div class="' + xclass + '"><div class="panel panel-default">');
-    s.push('<div class="panel-heading title"><h3 class="panel-title">' + title + '</h3></div>');
-    s.push('<div class="panel-body">' + content + '</div>');
-    s.push('</div></div>');
-    return s.join('');
-  }
-
-  function sectionRow(xclass, title, content) {
-    var s = [];
-    s.push('<div class="row">');
-    s.push(section(xclass, title, content));
-    s.push('</div>');
-    return s.join('');
-  }
-});
index 4091ee0..eff934a 100644 (file)
@@ -1,30 +1,30 @@
-.mkwsCredo {
+.mkws-credo {
     font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
 }
 
-.mkwsCredo table {
+.mkws-credo table {
     width: 100%;
     border-collapse: collapse;
 }
 
-.mkwsCredo table tr.front {
+.mkws-credo table tr.front {
     background: #ddf3c3;
 }
 
-.mkwsCredo table tr:first-child td:first-child {
+.mkws-credo table tr:first-child td:first-child {
     width: 70%;
 }
 
-.mkwsCredo table tr:first-child .section {
+.mkws-credo table tr:first-child .section {
     margin: 10px;
     border: 1px solid #c0c0c0;
 }
 
-.mkwsCredo table tr {
+.mkws-credo table tr {
     vertical-align: top;
 }
 
-.mkwsCredo .front div.title {
+.mkws-credo .front div.title {
     font-size: 150%;
     font-weight: bold;
     color: white;
@@ -32,7 +32,7 @@
     padding: 0.25em 0.5em;
 }
 
-.mkwsCredo div.title {
+.mkws-credo div.title {
     font-size: 150%;
     font-weight: bold;
     color: #666699;
@@ -40,7 +40,7 @@
     padding: 0.25em 0.5em;
 }
 
-.mkwsCredo div.content {
+.mkws-credo div.content {
     background: white;
     padding: 0.5em 1em;
 
     overflow: auto;
 }
 
-.mkwsReference h1 {
+.mkws-reference h1 {
     display:none;
 }
 
-.mkwsReference img {
+.mkws-reference img {
     float: left;
     margin: 0 1.5em 1em 0;
     border: 2px solid #c0c0c0;
     padding: 0.5em;
 }
 
-.mkwsCredo .image .mkwsSummary {
+.mkws-credo .image .mkws-summary {
     float: left;
 }
 
-.mkwsCredo .image a {
+.mkws-credo .image a {
     text-decoration: none;
 }
 
-.mkwsCredo hr.divider {
+.mkws-credo hr.divider {
     margin: 20px 1%;
     border-top: 3px dotted #c0c0c0;
     color: #fff;
     width: 98%;
 }
 
-.mkwsCredit {
+.mkws-credit {
     font-size: small;
     text-align: right;
 }
 
-.mkwsCredit::before {
+.mkws-credit::before {
     content: "Source: ";
     font-weight: bold;
 }
 
-.mkwsFacet a {
+.mkws-facet a {
     text-decoration: none;
 }
 
-.mkwsFacet a:hover {
+.mkws-facet a:hover {
     text-decoration: underline;
 }
 
-.mkwsTerm {
+.mkws-term {
     clear: both;
 }
 
-.mkwsTerm span {
+.mkws-term span {
     float: right;
 }
 
index 6dfba21..71e46ac 100644 (file)
@@ -1,4 +1,4 @@
-.mkwsReference {
+.mkws-reference {
     max-width: 40em;
     font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
     background: #f0f0e0;
@@ -9,26 +9,26 @@
     -webkit-border-radius: 1em;
 }
 
-.mkwsReference h1 a {
+.mkws-reference h1 a {
     color: #806020;
 }
 
-.mkwsReference a {
+.mkws-reference a {
     text-decoration: none;
 }
 
-.mkwsReference img {
+.mkws-reference img {
     float: right;
     margin: 0 0 1em 2em;
     border: 0.5em solid white;
 }
 
-.mkwsCredit {
+.mkws-credit {
     font-size: small;
     text-align: right;
 }
 
-.mkwsCredit::before {
+.mkws-credit::before {
     content: "Source: ";
     font-weight: bold;
 }
index a311cb2..81fc380 100644 (file)
@@ -26,7 +26,7 @@
   </script>
 
   <div style="max-width: 18em; margin: 1.5em 1.5em">
-    <div class="mkwsReferenceUniverse" autosearch="sushi"></div>
+    <div class="mkws-reference-universe" autosearch="sushi"></div>
   </div>
 </body>
 </html>
index 0d5c684..1f00e33 100644 (file)
@@ -1,4 +1,4 @@
-.mkwsReferenceUniverse {
+.mkws-reference-universe {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   background: #FCFBFA;
   padding: 0.5em 1em 0.25em;
index 64ef386..482c513 100644 (file)
@@ -3,6 +3,6 @@
     <script src="//mkws.indexdata.com/mkws-complete.js"></script>
     <script src="mkws-widget-ru.js"></script>
     <link rel="stylesheet" type="text/css" href="mkws-widget-ru.css" />
-    <div class="mkwsReferenceUniverse" autosearch="!param!q"></div>
+    <div class="mkws-reference-universe" autosearch="!param!q"></div>
   </div>
 </html>
index 55b4488..20762f7 100644 (file)
@@ -1,11 +1,11 @@
 var mkws_config = {
-   service_proxy_auth: "http://mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc"
+   service_proxy_auth: "http://sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=paratext&password=paratext_mkc"
 };
 
-mkws.registerWidgetType('ReferenceUniverse', function() {
+mkws.registerWidgetType('reference-universe', function() {
   if (!this.config.perpage) this.config.perpage = 5;
   if (!this.config.sort) this.config.sort = "position";
-  this.team.registerTemplate('ReferenceUniverse', '\
+  this.team.registerTemplate('reference-universe', '\
 <h2>Results from Reference Universe</h2>\
 <ul>\
 {{#each hits}}\
@@ -27,7 +27,7 @@ mkws.registerWidgetType('ReferenceUniverse', function() {
 ');
 
   var that = this;
-  var template = that.team.loadTemplate(that.config.template || "ReferenceUniverse");
+  var template = that.team.loadTemplate(that.config.template || "reference-universe");
   this.team.queue("records").subscribe(function(data) {
     that.node.html(template(data));
   }); 
index c55272e..2a1c4e4 100644 (file)
@@ -6,7 +6,7 @@ Simply paste this inline with the markup on any page:
     <script src="//mkws.indexdata.com/mkws-complete.js"></script>
     <script src="//mkws.indexdata.com/mkws-widget-ru.js"></script>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws-widget-ru.css" />
-    <div class="mkwsReferenceUniverse" autosearch="!param!q"></div>
+    <div class="mkws-reference-universe" autosearch="!param!q"></div>
     
 ## A bit more detail 
 
@@ -21,9 +21,9 @@ The provided stylesheet is generic and you're encouraged to replace it entirely
 
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws-widget-ru.css" />
     
-Any element you give the class `mkwsReferenceUniverse` will have is contents replaced by the top results from a search against the Reference Universe service for the current query.
+Any element you give the class `mkws-reference-universe` will have is contents replaced by the top results from a search against the Reference Universe service for the current query.
     
-    <div class="mkwsReferenceUniverse" autosearch="!param!q"></div>
+    <div class="mkws-reference-universe" autosearch="!param!q"></div>
 
 ### Finding the query 
 
diff --git a/examples/htdocs/mkws-widget-sru.js b/examples/htdocs/mkws-widget-sru.js
new file mode 100644 (file)
index 0000000..b288029
--- /dev/null
@@ -0,0 +1,2 @@
+mkws.registerWidgetType('SRU', function() {
+});
index 2212e25..a567a9f 100644 (file)
@@ -1,4 +1,4 @@
-.mkwsWimp {
+.mkws-wimp {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   background: #FCFBFA;
   padding: 0.5em 1em 0.25em;
index b203ef2..f014cca 100644 (file)
@@ -3,6 +3,6 @@
     <script src="//mkws.indexdata.com/mkws-complete.js"></script>
     <script src="mkws-widget-wimp.js"></script>
     <link rel="stylesheet" type="text/css" href="mkws-widget-wimp.css" />
-    <div class="mkwsWimp" autosearch="!param!q"></div>
+    <div class="mkws-wimp" autosearch="!param!q"></div>
   </div>
 </html>
index 5d78b2d..b2a9c4c 100644 (file)
@@ -3,7 +3,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <meta name="copyright" content="(c) 1999-2013 IndexData ApS, http://indexdata.com" />
+    <meta name="copyright" content="(c) 1999-2013 Index Data ApS, http://indexdata.com" />
     <title>MKWS demo: mobile-screen resizing</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript">
     <script src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
   </body>
 </html>
index 174fc37..2ebf5ce 100644 (file)
@@ -1,7 +1,7 @@
 <html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>MKWS demo: Reference widget with popup window</title>
+    <title>MKWS demo: Reference & Credo, and popup widget, development</title>
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
     <link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />
@@ -9,7 +9,7 @@
 
     <script type="text/javascript">
       var mkws_config = {
-         service_proxy_auth: "//mkws.indexdata.com/service-proxy-credoauth"
+       sp_auth_credentials: "mkwstest/mkwstest"
       };
     </script>
 
     <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
 
     <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
 
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-team.js"></script>
     <script type="text/javascript" src="src/mkws-filter.js"></script>
-    <script type="text/javascript" src="src/mkws-popup.js"></script>
     <script type="text/javascript" src="src/mkws-widget.js"></script>
     <script type="text/javascript" src="src/mkws-widget-main.js"></script>
     <script type="text/javascript" src="src/mkws-widget-termlists.js"></script>
     <script type="text/javascript" src="src/mkws-widget-record.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
+    <script type="text/javascript" src="src/mkws-popup.js"></script>
 
     <script type="text/javascript" src="mkws-widget-credo.js"></script>
   </head>
   <body>
-    <h3>MKWS widgets in a popup window</h3>
-
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
+    <h3>MKWS demo: Reference & Credo, and popup widget, development</h3>
+
+    <div class="mkws-search"></div>
+    <div class="mkws-popup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkws-button">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
     </div>
 
-    <div class="mkwsPopup" popup_width="1024" popup_height="800" popup_autoOpen="1">
-      <div class="mkwsCredo mkwsTeam_credo" autosearch="!param!q">mkwsCredo result will appear here</div>
+    <div class="mkws-popup" popup_width="1024" popup_height="800" popup_autoOpen="1">
+      <div class="mkws-credo mkws-team-credo" autosearch="!param!q">mkws-credo result will appear here</div>
     </div>
 
-    <div class="mkwsPopup" popup_width="700" popup_height="600" popup_autoOpen="1">
-      <div class="mkwsReference mkwsTeam_credo" sentences="1" autosearch="!param!q">mkwsReference result will appear here</div>
+    <div class="mkws-popup" popup_width="700" popup_height="600" popup_autoOpen="1">
+      <div class="mkws-reference mkws-team-credo" sentences="1" autosearch="!param!q">mkws-reference result will appear here</div>
     </div>
 
   </body>
index 9a1a35e..256d695 100644 (file)
@@ -1,50 +1,57 @@
 <html>
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>MKWS demo: Reference widget with popup window</title>
+    <title>MKWS demo: Popup Widget</title>
     <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
-    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
-    <link rel="stylesheet" type="text/css" href="//example.indexdata.com/mkws-widget-reference.css" />
-    <link rel="stylesheet" type="text/css" href="//example.indexdata.com/mkws-widget-credo.css" />
 
     <script type="text/javascript">
       var mkws_config = {
-         service_proxy_auth: "//mkws.indexdata.com/service-proxy-credoauth"
+       sp_auth_credentials: "mkwstest/mkwstest"
       };
     </script>
 
-    <!--
-    <script type="text/javascript" src="tools/htdocs/mkws-complete.js"></script>
-    <script>jQuery = mkws.$</script>
-    <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
-    -->
-    <script type="text/javascript" src="//code.jquery.com/jquery-1.10.0.min.js"></script>
-    <script type="text/javascript" src="//jquery-json.googlecode.com/files/jquery.json-2.4.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+
+    <link rel="stylesheet" type="text/css" href="//code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
+    <!-- jquery-ui need a reference to the internal jQuery object -->
+    <script>$ = jQuery = mkws.$; </script>
     <script type="text/javascript" src="//code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
-    <script type="text/javascript" src="//git.indexdata.com/?p=pazpar2.git;a=blob_plain;f=js/pz2.js;hb=HEAD"></script>
-    <script type="text/javascript" src="//builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.1.2.js"></script>
-    <script type="text/javascript" src="//mkws.indexdata.com/mkws.js"></script>
-   
-    <script type="text/javascript" src="//example.indexdata.com/mkws-widget-credo.js"></script>
+
+    <style>
+    .mkws-search { float: left !important; }
+    .mkws-search input.mkws-button { color: black; }
+    </style>
   </head>
+
   <body>
-    <h3>MKWS widgets in a popup window</h3>
-
-    <div class="mkwsSearch"></div>
-    <div class="mkwsPopup" popup_width="1024" popup_height="650" popup_modal="0" popup_autoOpen="0" popup_button="input.mkwsButton">
-      <div class="mkwsSwitch"></div>
-      <div class="mkwsLang"></div>
-      <div class="mkwsResults"></div>
-      <div class="mkwsTargets"></div>
-      <div class="mkwsStat"></div>
+    <h3>MKWS demo: popup widget(s)</h3>
+
+    <div>
+      <p><a id="popup_no1">popup number 1</a></p>
+      <p><a id="popup_no2">popup number 2</a></p>
+    </div>
+
+    <!-- search box is outside the popup window -->
+    <div class="mkws-search"></div>
+
+    <!-- popup widget config -->
+    <div class="mkws-popup" popup_width="1024" popup_height="750" popup_modal="0" popup_autoOpen="0" popup_button="input.mkws-button">
+      <div class="mkws-switch"></div>
+      <div class="mkws-lang"></div>
+      <div class="mkws-results"></div>
+      <div class="mkws-targets"></div>
+      <div class="mkws-stat"></div>
     </div>
 
-    <div class="mkwsPopup" popup_width="1024" popup_height="800" popup_autoOpen="1">
-      <div class="mkwsCredo mkwsTeam_credo" autosearch="!param!q">mkwsCredo result will appear here</div>
+    <!-- popup widget config -->
+    <div class="mkws-popup" popup_width="500" popup_height="350" popup_modal="0" popup_autoOpen="0" popup_button="a#popup_no1">
+       <h1>popup no 1</h1>
+       some text...
     </div>
 
-    <div class="mkwsPopup" popup_width="700" popup_height="600" popup_autoOpen="1">
-      <div class="mkwsReference mkwsTeam_credo" sentences="1" autosearch="!param!q">mkwsReference result will appear here</div>
+    <div class="mkws-popup" popup_width="400" popup_height="250" popup_modal="0" popup_autoOpen="0" popup_button="a#popup_no2">
+       <h1>popup no 2</h1>
+       other text...
     </div>
 
   </body>
diff --git a/examples/htdocs/ref-bootstrap.html b/examples/htdocs/ref-bootstrap.html
deleted file mode 100644 (file)
index 503a8fe..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <title>MKWS demo: Compound reference widget</title>
-    <!-- <link rel="stylesheet" type="text/css" href="mkws&#45;widget&#45;credo.css" /> -->
-    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
-    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
-    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
-    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
-    <script type="text/javascript">
-      var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-credoauth" };
-    </script>
-    <script class="mkwsTemplate_FacetBootstrap" type="text/x-handlebars-template">
-      <h3>Results from Reference Universe</h3>
-      {{#each hits}}
-        <div class="refinement">
-          {{#mkws-first md-electronic-url}}
-          <a href="{{this}}">
-          {{/mkws-first}}
-            {{md-title}}
-          </a>
-        {{#if md-title-remainder}}
-          <span>{{md-title-remainder}}</span>
-        {{/if}}
-        {{#if md-title-responsibility}}
-          <span><i>{{md-title-responsibility}}</i></span>
-        {{/if}}
-        </div>
-      {{/each}}
-    </script>
-    <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
-    <script type="text/javascript" src="mkws-widget-credo-bs.js"></script>
-    <style>
-      .mkwsCredo {
-        max-width: 1440px;
-      }
-      .mkwsGoogleImage img {
-        max-width: 95%;
-      }
-    </style>
-  </head>
-  <body>
-    <div class='mkwsCredo page-header container-fluid' autosearch='!param!q'></div>
-  </body>
-</html>
index 9ba47a1..f74556c 100644 (file)
@@ -4,12 +4,12 @@
     <title>MKWS demo: Compound reference widget</title>
     <link rel="stylesheet" type="text/css" href="mkws-widget-credo.css" />
     <script type="text/javascript">
-      var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-credoauth" };
+      var mkws_config = { sp_auth_credentials: "credo/emu" };
     </script>
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
     <script type="text/javascript" src="mkws-widget-credo.js"></script>
   </head>
   <body>
-    <div class='mkwsCredo' autosearch='!param!q'></div>
+    <div class='mkws-credo' autosearch='!param!q'></div>
   </body>
 </html>
index b4cb8ca..16d1a3d 100644 (file)
@@ -4,11 +4,11 @@
     <title>MKWS demo: Reference Universe widget</title>
     <link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />
     <script type="text/javascript">
-      var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth" };
+      var mkws_config = { service_proxy_auth: "//sp-mkws.indexdata.com/service-proxy/?command=auth&action=login&username=mkwstest&password=mkwstest" };
     </script>
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class='mkwsReference' autosearch='!param!q' sentences='1'>result will appear here</div>
+    <div class='mkws-reference' autosearch='!param!q' sentences='1'>result will appear here</div>
   </body>
 </html>
index f94de5d..ed81295 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2014 Index Data ApS. http://indexdata.com
 
 User-agent: *
 Disallow: /service-proxy
index 2f2788c..c4c32d1 100644 (file)
@@ -2,17 +2,17 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo client</title>
-    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+    <link rel="stylesheet" href="//mkws.indexdata.com/mkws.css" />
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsProgress"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index 875c056..29eba86 100644 (file)
@@ -7,14 +7,14 @@
     <style>.searchbox { float: right; }</style>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
     <form>
       <input type="text" name="q" class="searchbox"/>
     </form>
-    <div class="mkwsResults" autosearch="!param!q"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
-    <div class="mkwsBuilder"></div>
+    <div class="mkws-results" autosearch="!param!q"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <div class="mkws-builder"></div>
   </body>
 </html>
index ef9c436..a06d648 100644 (file)
@@ -4,15 +4,15 @@
     <title>MKWS demo: Multiple autosearching widgets get their own teams</title>
     <link rel="stylesheet" type="text/css" href="mkws-widget-reference.css" />
     <script type="text/javascript">
-      var mkws_config = { service_proxy_auth: "//mkws.indexdata.com/service-proxy-testauth" };
+      var mkws_config = { service_proxy_auth: "//sp-mkws.indexdata.com/service-proxy-testauth" };
     </script>
     <!-- <script type="text/javascript" src="//mkws.local/mkws&#45;complete.js"></script> -->
     <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
   </head>
   <body>
-    <div class='mkwsReference' autosearch='one' sentences='1'>result will appear here</div>
-    <div class='mkwsReference' autosearch='two' sentences='1'>result will appear here</div>
-    <div class='mkwsReference' autosearch='three' sentences='1'>result will appear here</div>
-    <div class='mkwsReference' sentences='1'>result will appear here</div>
+    <div class='mkws-reference' autosearch='one' sentences='1'>result will appear here</div>
+    <div class='mkws-reference' autosearch='two' sentences='1'>result will appear here</div>
+    <div class='mkws-reference' autosearch='three' sentences='1'>result will appear here</div>
+    <div class='mkws-reference' sentences='1'>result will appear here</div>
   </body>
 </html>
index bed0122..6c02276 100644 (file)
@@ -2,9 +2,9 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo client</title>
-    <link rel="stylesheet" type="text/css" href="http://mkws.indexdata.com/mkws.css" />
-    <script type="text/javascript" src="http://mkws.indexdata.com/mkws-complete.js"></script>
-    <script class="mkwsTemplate_Summary" type="text/x-handlebars-template">
+    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
+    <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+    <script class="mkws-template-summary" type="text/x-handlebars-template">
       <a href="#" id="{{_id}}" onclick="{{_onclick}}">
        <b>{{md-title}}</b>
       </a>
@@ -15,7 +15,7 @@
        <span><i>{{md-title-responsibility}}</i></span>
       {{/if}}
     </script>
-    <script class="mkwsTemplate_Record" type="text/x-handlebars-template">
+    <script class="mkws-template-record" type="text/x-handlebars-template">
       <table>
        <tr>
          <th>Title</th>
     </script>
   </head>
   <body>
-    <div class="mkwsSwitch"></div>
-    <div class="mkwsLang"></div>
-    <div class="mkwsSearch"></div>
-    <div class="mkwsResults"></div>
-    <div class="mkwsTargets"></div>
-    <div class="mkwsStat"></div>
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
   </body>
 </html>
diff --git a/examples/htdocs/topic.css b/examples/htdocs/topic.css
new file mode 100644 (file)
index 0000000..47da435
--- /dev/null
@@ -0,0 +1,102 @@
+body {
+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
+  background: radial-gradient(ellipse at center,  #ffffff 0%,#f8f8f8 100%);
+  font-weight: 300;
+}
+b, strong {
+  font-weight: 400; 
+}
+.panel {
+  border: none;
+  background: white;
+  padding: 1em .75em;
+  border-radius: 3px;
+  -moz-border-radius: 3px;
+  -webkit-border-radius: 3px;
+  color: #76868A;
+  box-shadow: 0 0 2px rgba(0, 0, 0, 0.09);
+  margin-bottom: 2em;
+}
+
+.panel-default > .panel-heading {
+  background-image: none; 
+  border: none;
+  background-color: white;
+}
+
+.panel-heading {
+  padding: 0.5em 15px 0;
+}
+
+.panel-title {
+  font-size: 130%;
+  color: #4A5456;
+}
+
+.panel-body {
+  padding: 10px 15px; 
+}
+
+.mkws-facet-title {
+  font-style: italic;
+  font-weight: 400;
+}
+  .mkws-term {
+    padding: .1em 0;
+  }
+  .mkws-term a {
+    padding-right: .5em; 
+    font-weight: 400;
+  }
+
+.mkws-summary {
+  padding: .5em 0;
+  line-height: 1.35;
+}
+.mkws-summary:last-child {
+  padding-bottom: 0;
+}
+  
+.container .jumbotron {
+  background: none;
+  padding: 0 2em 0 0;
+  box-shadow: none;
+  color: black;
+}  
+  .jumbotron .mkws-summary {
+    line-height: 1.5;  
+  }
+  .jumbotron p{
+    font-size: 150%; 
+  }
+  .mkws-credit {
+    font-size: 125% !important;
+    font-style: italic;
+  }
+  
+.mkws-google-image .mkws-summary {
+  padding: 0;
+  font-weight: 400;
+}
+  .mkws-google-image img {
+    max-width: 100%;
+    max-height: 200px;
+    padding: 1em 0 .5em;
+  }
+.list-group-item {
+  padding: 10px 15px !important;
+}
+.list-group {
+  box-shadow: none;
+  -webkit-box-shadow: none;
+}
+@media screen and (min-width:700px) {
+  .multicol {
+    column-count: 2;
+    column-gap: 20px;
+    -moz-column-count: 2;
+    -moz-column-gap: 20px;
+    -webkit-column-count: 2;
+    -webkit-column-gap: 20px;
+  }
+}
diff --git a/examples/htdocs/topic.html b/examples/htdocs/topic.html
new file mode 100644 (file)
index 0000000..642941b
--- /dev/null
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>MKWS demo: Compound reference widget, Bootstrap edition</title>
+  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
+  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
+  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
+  <!-- http://www.bootstrapcdn.com/#bootswatch_tab has some themes that look mediumly okay -->
+  <!-- <link href="//maxcdn.bootstrapcdn.com/bootswatch/3.1.1/cyborg/bootstrap.min.css" rel="stylesheet"> -->
+  <!-- <link href="//maxcdn.bootstrapcdn.com/bootswatch/3.1.1/amelia/bootstrap.min.css" rel="stylesheet"> -->
+  <!-- <link href="//maxcdn.bootstrapcdn.com/bootswatch/3.1.1/united/bootstrap.min.css" rel="stylesheet"> -->
+  <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
+  <script type="text/javascript">
+    var mkws_config = { sp_auth_credentials: "credo/emu" };
+  </script>
+  <script type="text/javascript" src="//mkws.indexdata.com/mkws-complete.js"></script>
+  <!-- <script type="text/javascript" src="//mkws.local/mkws&#45;complete.js"></script> -->
+  <link rel="stylesheet" type="text/css" href="topic.css">
+  <script>
+    // The Google Images database returns links like:
+    //      http://images.google.com/url?q=http://eofdreams.com/fish.html&sa=U&ei=RAB-U9XNDo2Dqga1o4L4Bw&ved=0CC4Q9QEwAA&usg=AFQjCNFhRtn6GMevHbpITZ6kfx6rsHV2ow
+    // This Handlebars helper avoids a pointless redirect by transforming
+    // this to the URL of the underling page, in this case
+    //      http://eofdreams.com/fish.html
+    Handlebars.registerHelper('mkws-googleurl', function(obj) {
+      if (!obj) {
+        return "obj undefined";
+      } else if (!obj[0]) {
+        return "obj[0] undefined, JSON=" + $.toJSON(obj);
+      } else {
+        return mkws.getParameterByName('q', obj[0]);
+      }
+    });
+    Handlebars.registerHelper('mkws-topicurl', function(topic) {
+      return window.location.pathname + "?q=" + encodeURIComponent(topic);
+    });
+  </script>
+  <script class="mkws-template-topic-image" type="text/x-handlebars-template">
+    {{#each hits}}
+      <div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
+       <a href="{{mkws-googleurl md-electronic-url}}" target="_blank">
+        {{#mkws-first md-thumburl}}
+          <img src="{{this}}" alt="{{../md-title}}"/>
+        {{/mkws-first}}
+        <br/>
+       </a>
+       <p>{{{md-title}}}</p>
+      </div>
+    {{/each}}
+  </script>
+  <script class="mkws-template-topic-facet" type="text/x-handlebars-template">
+    {{#each terms}}
+      <li class="list-group-item mkws-term">
+        <span class="badge">{{count}}</span>
+        <a href="{{mkws-topicurl term}}">{{term}}</a>
+      </li>
+    {{/each}}
+  </script>
+</head>
+<body>
+  <div class='page-header container' autosearch='!param!q'>
+    <div class="row">
+      <!-- reference entry -->
+      <div class="jumbotron panel col-md-8">
+        <div class="panel-body mkws-reference mkws-team-ref" autosearch="!param!q"
+             data-mkws-config='{"paragraphs":1}'></div>
+      </div>
+      <!-- related topics -->
+      <div class="col-md-offset-1 col-md-3"><div class="panel panel-default">
+        <div class="panel-heading title">
+          <h3 class="panel-title">Related Topics</h3>
+        </div>
+        <ul class="panel-body list-group mkws-facet mkws-team-main"
+            autosearch="!param!q"
+            data-mkws-facet="subject"
+            data-mkws-config='{ "template": "topic-facet" }'></ul>
+      </div></div>
+    </div>
+    <!-- images -->
+    <div class="row">
+      <div class="col-md-12"><div class="panel panel-default">
+        <div class="panel-heading title">
+          <h3 class="panel-title">Images</h3>
+        </div>
+        <div class="panel-body mkws-google-image" autosearch="!param!q"
+             data-mkws-config='{ "maxrecs": 4, "template": "topic-image", "target": "google_images_js" }'></div>
+      </div></div>
+    </div>
+
+    <!-- sources -->
+    <div class="row">
+        <div class="col-md-4 col-sm-6"><div class="panel panel-default">
+          <div class="panel-heading title">
+            <h3 class="panel-title">News</h3>
+          </div>
+          <div class="panel-body mkws-records mkws-team-news" autosearch="!param!q"
+               data-mkws-config='{"targetfilter":"categories=news",
+                                  "perpage":7}'></div>
+        </div></div>
+        <div class="col-md-4 col-sm-6"><div class="panel panel-default">
+          <div class="panel-heading title">
+            <h3 class="panel-title">Articles</h3>
+          </div>
+          <div class="panel-body mkws-records mkws-team-articles" autosearch="!param!q"
+               data-mkws-config='{"targetfilter":"categories=articles",
+                                  "perpage":7}'></div>
+        </div></div>
+        <div class="col-md-4 col-sm-6"><div class="panel panel-default">
+          <div class="panel-heading title">
+            <h3 class="panel-title">Books</h3>
+          </div>
+          <div class="panel-body mkws-records mkws-team-books" autosearch="!param!q"
+               data-mkws-config='{"targetfilter":"categories=books",
+                                  "perpage":7}'></div>
+        </div></div>
+    </div>
+    <div class="row">
+        <div class="col-md-12"><div class="panel panel-default">
+          <div class="panel-heading title">
+            <h3 class="panel-title">Results from all targets</h3>
+          </div>
+          <div class="panel-body multicol mkws-records mkws-team-main"></div>
+        </div></div>
+    </div>
+  </div>
+</body>
+</html>
index 004ed32..f521523 100644 (file)
@@ -7,7 +7,7 @@
 
 
 <!-- MKWS demo! A template to fit the Toronto Public Library -->
-<script class="mkwsTemplate_ReferenceUniverse" type="text/x-handlebars-template">
+<script class="mkws-template-reference-universe" type="text/x-handlebars-template">
   <h3>Results from Reference Universe</h3>
   {{#each hits}}
     <div class="refinement">
@@ -891,7 +891,7 @@ pageTracker._trackEvent(category,action,document.title);
 
 
 
-<div class="mkwsReferenceUniverse refinement-container" autosearch="!param!q"></div>
+<div class="mkws-reference-universe refinement-container" autosearch="!param!q"></div>
 
 
 
index 006f11b..a41c840 100644 (file)
@@ -4,35 +4,35 @@
   <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo: Mike's playground</title>
-    <link rel="stylesheet" type="text/css" href="http://mkws.indexdata.com/mkws.css" />
+    <link rel="stylesheet" type="text/css" href="//mkws.indexdata.com/mkws.css" />
     <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/jquery.json-2.4.js"></script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/handlebars-v1.1.2.js"></script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/pazpar2/js/pz2.js"></script>
-    <script type="text/javascript" src="http://mkws.indexdata.com/mkws.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/jquery.json-2.4.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/handlebars-v2.0.0.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/pazpar2/js/pz2.js"></script>
+    <script type="text/javascript" src="//mkws.indexdata.com/mkws.js"></script>
   </head>
   <body>
     <table width="100%" border="1">
       <tr>
        <td valign="top" width="50%">
-         <div class="mkwsSwitch"></div>
-         <div class="mkwsLang"></div>
-         <div class="mkwsSearch"></div>
-         <div class="mkwsResults"></div>
-         <div class="mkwsTargets"></div>
-         <div class="mkwsStat"></div>
+         <div class="mkws-switch"></div>
+         <div class="mkws-lang"></div>
+         <div class="mkws-search"></div>
+         <div class="mkws-results"></div>
+         <div class="mkws-targets"></div>
+         <div class="mkws-stat"></div>
        </td>
        <td valign="top" width="50%">
-         <div class="mkwsSwitch mkwsTeam_2"></div>
-         <div class="mkwsLang mkwsTeam_2"></div>
-         <div class="mkwsSearch mkwsTeam_2"></div>
-         <div class="mkwsResults mkwsTeam_2"></div>
-         <div class="mkwsTargets mkwsTeam_2"></div>
-         <div class="mkwsStat mkwsTeam_2"></div>
+         <div class="mkws-switch mkws-team-2"></div>
+         <div class="mkws-lang mkws-team-2"></div>
+         <div class="mkws-search mkws-team-2"></div>
+         <div class="mkws-results mkws-team-2"></div>
+         <div class="mkws-targets mkws-team-2"></div>
+         <div class="mkws-stat mkws-team-2"></div>
        </td>
       </tr>
     </table>
-    <div class="mkwsMOTD">This is the first MOTD</div>
-    <div class="mkwsMOTD mkwsTeam_2">This is the second MOTD</div>
+    <div class="mkws-motd">This is the first MOTD</div>
+    <div class="mkws-motd mkws-team-2">This is the second MOTD</div>
   </body>
 </html>
index f2653aa..268c414 100644 (file)
@@ -7,25 +7,26 @@
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
     <script type="text/javascript">
       var mkws_config = {
-         pazpar2_url : "/service-proxy/",
          show_perpage: false,
          show_sort: false,
          perpage_default: 10,
          sort_default: "title:1",
          lang: "de",
-         service_proxy_auth : "/service-proxy-testauth"
+          sp_auth_credentials: "mkwstest/mkwstest"
       };
     </script>
+
     <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
-    <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
-    <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
     <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
-   
+    <script type="text/javascript" src="tools/htdocs/handlebars-v2.0.0.js"></script>
+    <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
+
     <!-- <script type="text/javascript" src="tools/htdocs/mkws.js"></script> -->
     <script type="text/javascript" src="src/mkws-handlebars.js"></script>
     <script type="text/javascript" src="src/mkws-core.js"></script>
     <script type="text/javascript" src="src/mkws-team.js"></script>
     <script type="text/javascript" src="src/mkws-filter.js"></script>
+
     <script type="text/javascript" src="src/mkws-widget.js"></script>
     <script type="text/javascript" src="src/mkws-widget-main.js"></script>
     <script type="text/javascript" src="src/mkws-widget-termlists.js"></script>
     <script type="text/javascript" src="src/mkws-widget-reference.js"></script>
     <script type="text/javascript" src="src/mkws-widget-builder.js"></script>
 
-    <style type="text/css">
-      .mkwsTermlists div.facet {
-      float:left;
-      width: 30%;
-      margin: 0.3em;
-      }
-      .mkwsStat {
-      text-align: right;
-      }
-    </style>
+    <script type="text/javascript" src="src/mkws-templates.js"></script>
+
   </head>
-  <body>
-    <table width="100%" border="0">
-      <tr>
-        <td>
-         <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div class="mkwsStat"></div>
-        </td>
-      </tr>
-    </table>
 
+  <!-- Test case: using single JS files in the right order, MKWS config in HEAD
+       before JS files loaded, and a broken jQuery object in BODY section -->
+  <body>
+    <div class="mkws-auth-name mkws-auth-name"></div>
+    <div class="mkws-switch mkws-switch"></div>
+    <div class="mkws-lang mkws-lang"></div>
+    <div class="mkws-progress mkws-progress"></div>
+    <div class="mkws-search mkws-search"></div>
+    <div class="mkws-results mkws-results"></div>
+    <div class="mkws-targets mkws-targets"></div>
+    <div class="mkws-stat mkws-stat"></div>
 
     <!-- <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script> -->
     <script type="text/javascript">
       // check for the real jQuery / $ object
-      console.log("Reset jQuery and $ objection to null....");
+      mkws.log("Reset jQuery and $ objection to null....");
       $ = null;
       jQuery = null;
     </script>
 
   </body>
 </html>
-
index 277342e..ce86af3 100644 (file)
@@ -5,61 +5,25 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <title>MKWS demo: Wolfram's playground</title>
     <link rel="stylesheet" type="text/css" href="tools/htdocs/mkws.css" />
-    <style type="text/css">
-      .mkwsTermlists div.facet {
-      float:left;
-      width: 30%;
-      margin: 0.3em;
-      }
-      .mkwsStat {
-      text-align: right;
-      }
-    </style>
   </head>
-  <body>
-    <table width="100%" border="0">
-      <tr>
-        <td>
-         <div class="mkwsSwitch"></div>
-          <div class="mkwsLang"></div>
-          <div class="mkwsSearch"></div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:500px; overflow: auto">
-            <div class="mkwsPager"></div>
-            <div class="mkwsNavi"></div>
-            <div class="mkwsRecords"></div>
-            <div class="mkwsTargets"></div>
-            <div class="mkwsRanking"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div style="height:300px; overflow: hidden">
-            <div class="mkwsTermlists"></div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td>
-          <div class="mkwsStat"></div>
-        </td>
-      </tr>
-    </table>
 
-    <script type="text/javascript" src="src/mkws-complete.js"></script>
-    <!-- <script type="text/javascript" src="https://mkws.indexdata.com/mkws-complete.js"></script> -->
+  <!-- Test case: using mkws-complete.js and MKWS config in the body section -->
+  <body>
+    <!-- <div class="mkws-auth-name"></div> -->
+    <div class="mkws-switch"></div>
+    <div class="mkws-lang"></div>
+    <div class="mkws-progress"></div>
+    <div class="mkws-search"></div>
+    <div class="mkws-results"></div>
+    <div class="mkws-targets"></div>
+    <div class="mkws-stat"></div>
+    <!-- <div class="mkws-builder"></div> -->
 
+    <script type="text/javascript" src="tools/htdocs/mkws-complete.js"></script>
     <script type="text/javascript">
       var mkws_config = {
-          pazpar2_url : "/service-proxy/",
-          service_proxy_auth: "/service-proxy-testauth",
-          perpage_default: 10
+       sp_auth_credentials: "mkwstest/mkwstest"
       };
     </script>
-
   </body>
 </html>
diff --git a/notes/using-mkadmin b/notes/using-mkadmin
deleted file mode 100644 (file)
index 0d78b94..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-The set of targets provided by MKWS by default can be maintained using
-MKAdmin.  Go to
-       http://mkc-admin.indexdata.com/console/
-and act as the "DEMO MKWS: the MasterKey Widget Set" library administrator.
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644 (file)
index 0000000..f2fc3f4
--- /dev/null
@@ -0,0 +1 @@
+mkws-templates.js
index d44c596..bd05b9b 100644 (file)
@@ -1,6 +1,123 @@
-**default**:
-       make -C ../tools/htdocs
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
 
-clean:
-       make -C ../tools/htdocs clean
+DEST = ../tools/htdocs
 
+HANDLEBARS_FILE = handlebars-v2.0.0.js
+JQUERY_FILE = jquery-1.10.0.min.js
+JQUERY_JSON_FILE = jquery.json-2.4.js
+PP2_FILE = pz2.js
+
+HANDLEBARS_URL = http://builds.handlebarsjs.com.s3.amazonaws.com/${HANDLEBARS_FILE}
+JQUERY_URL = http://code.jquery.com/${JQUERY_FILE}
+JQUERY_JSON_URL = https://jquery-json.googlecode.com/files/${JQUERY_JSON_FILE}
+PP2_URL = http://git.indexdata.com/?p=pazpar2.git;a=blob_plain;f=js/${PP2_FILE};hb=HEAD
+
+VERSION = $(shell tr -d '\012' < VERSION)
+HANDLEBARS = ../test/node_modules/.bin/handlebars
+YUI_COMPRESSOR = $(shell which yui-compressor ../test/bin/yui-compressor | head -1)
+
+COMPONENTS = mkws-handlebars.js \
+       mkws-core.js \
+       mkws-team.js \
+       mkws-filter.js \
+       mkws-widget.js \
+       mkws-widget-main.js \
+       mkws-widget-termlists.js \
+       mkws-widget-authname.js \
+       mkws-widget-categories.js \
+       mkws-widget-log.js \
+       mkws-widget-record.js \
+       mkws-widget-reference.js \
+       mkws-widget-builder.js \
+       mkws-templates.js \
+       mkws-popup.js
+
+DOWNLOADABLE = ${HANDLEBARS_FILE} ${JQUERY_FILE} ${JQUERY_JSON_FILE} ${PP2_FILE}
+RELEASABLE = mkws.js mkws.min.js mkws-complete.js mkws-complete.min.js
+AVAILABLE = $(DOWNLOADABLE) $(RELEASABLE) NEWS VERSION
+INSTALLED_DOWNLOADABLE = $(DOWNLOADABLE:%=$(DEST)/%)
+INSTALLED_RELEASABLE = $(RELEASABLE:%=$(DEST)/%)
+INSTALLED = $(AVAILABLE:%=$(DEST)/%)
+
+all: $(INSTALLED)
+
+$(DEST)/mkws-complete.js: Makefile $(INSTALLED_DOWNLOADABLE) $(DEST)/mkws.js
+       ( set -e; \
+         echo "/*! Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com"; \
+         echo "   Licence: LGPL, http://www.indexdata.com/licences/lgpl"; \
+         echo "   created at: $$(date)"; \
+         echo "   MKWS GIT id: $$(git show | head -n 1 | perl -npe 's,\S+\s+,,')"; \
+         echo "   pz2.js GIT id: $$(curl -sSf 'http://git.indexdata.com/?p=pazpar2.git;a=rss' | egrep '<guid' | head -1 | perl -ne 'print "$$1\n" if m,.*=([0-9a-f]+)</guid>,')"; \
+         echo "*/"; \
+         cat $(DEST)/${JQUERY_FILE}; \
+         cat $(DEST)/${JQUERY_JSON_FILE}; \
+         echo 'mkws_jQuery = jQuery.noConflict(true);'; \
+         cat $(DEST)/${HANDLEBARS_FILE}; \
+         cat $(DEST)/${PP2_FILE}; \
+         cat $(DEST)/mkws.js; \
+       ) > $@.tmp
+       mv -f $@.tmp $@
+
+%.min.js: %.js
+       ${YUI_COMPRESSOR} $? > $@.tmp
+       mv -f $@.tmp $@
+
+$(DEST)/${HANDLEBARS_FILE}:
+       curl -sSf ${HANDLEBARS_URL} -o $@.tmp
+       mv -f $@.tmp $@
+
+$(DEST)/${JQUERY_FILE}:
+       curl -sSf ${JQUERY_URL} -o $@.tmp
+       perl -npe 's,sourceMappingURL=jquery.*map,,' $@.tmp > $@
+       rm -f $@.tmp
+
+$(DEST)/${JQUERY_JSON_FILE}:
+       curl -sSf ${JQUERY_JSON_URL} -o $@.tmp
+       mv -f $@.tmp $@
+
+$(DEST)/${PP2_FILE}:
+       curl -sSf "${PP2_URL}" -o $@.tmp
+       mv -f $@.tmp $@
+
+$(DEST)/%: %
+       rm -f $@
+       cp $? $@
+       chmod 444 $@
+
+release: $(RELEASABLE)
+       @if [ -f ${DEST}/releases/mkws-$(VERSION).js ]; then \
+               echo "*** There is already a release $(VERSION)"; \
+       else \
+               cp -p $(DEST)/mkws.js ${DEST}/releases/mkws-$(VERSION).js; \
+               cp -p $(DEST)/mkws.min.js ${DEST}/releases/mkws-$(VERSION).min.js; \
+               cp -p $(DEST)/mkws-complete.js ${DEST}/releases/mkws-complete-$(VERSION).js; \
+               cp -p $(DEST)/mkws-complete.min.js ${DEST}/releases/mkws-complete-$(VERSION).min.js; \
+               echo "Made release $(VERSION)"; \
+       fi
+
+$(DEST)/mkws.js: $(COMPONENTS) Makefile
+       cat ${COMPONENTS} > $@.tmp
+       mv -f $@.tmp $@
+       chmod 444 $@
+
+mkws-templates.js: templates/*.handlebars
+       ${HANDLEBARS} -n mkws.defaultTemplates templates/*.handlebars -f $@.tmp
+       mv -f $@.tmp $@
+
+# Checks that the JavaScript can be parsed
+syntax-check: $(DEST)/mkws.js
+       ${YUI_COMPRESSOR} $(DEST)/mkws.js >/dev/null
+
+# Emits a list of <script> elements to include in HTML applications
+html-includes:
+       echo $(COMPONENTS) | perl -npe "s/\s+/\0/g" | \
+         perl -n0e 'chomp(); print qq{    <script type="text/javascript" src="src/$$_"></script>\n}'
+
+clean distclean:
+       rm -f ${INSTALLED} mkws-templates.js
+
+help:
+       @echo "make [ all | clean | release ]"
+       @echo "     [ syntax-check | html-includes ]"
+       @echo "     [ mkws-templates.js | $(DEST)/mkws-complete.min.js ]"
+       @echo ""
index 6b3e00d..6bb98b3 100644 (file)
@@ -20,6 +20,7 @@ window.mkws = {
                 // initial value allows jQuery popup to use logging.
   teams: {},
   widgetType2function: {},
+  defaultTemplates: {},
 
   locale_lang: {
     "de": {
@@ -108,24 +109,6 @@ mkws.log = function(string) {
 };
 
 
-// Incredible that the standard JavaScript runtime doesn't define a
-// unique windowId. Instead, we have to make one up. And since there's
-// no global area shared between windows, the best we can do for
-// ensuring uniqueness is generating a random ID and crossing our
-// fingers. We stash this in window.name, as it's the only place to
-// keep data that is preserved across reloads and within-site
-// navigation. pz2.js picks this up and uses it as part of the
-// cookie-name, to ensure each tab gets its own session.
-if (window.name) {
-  mkws.log("Using existing window.name '" + window.name + "'");
-} else {
-  // Ten chars from 26 alpha-numerics = 36^10 = 3.65e15 combinations.
-  // At one per second, it will take 116 million years to duplicate a session
-  window.name = Math.random().toString(36).slice(2, 12);
-  mkws.log("Generated new window.name '" + window.name + "'");
-}
-
-
 // Translation function.
 mkws.M = function(word) {
   var lang = mkws.config.lang;
@@ -149,6 +132,11 @@ mkws.getParameterByName = function(name, url) {
 
 
 mkws.registerWidgetType = function(name, fn) {
+  if(mkws._old2new.hasOwnProperty(name)) {
+      mkws.log("Warning: registerWidgetType old widget name: " + name + " => " + mkws._old2new[name]);
+      name = mkws._old2new[name];
+  }
+
   mkws.widgetType2function[name] = fn;
   mkws.log("registered widget-type '" + name + "'");
 };
@@ -160,9 +148,7 @@ mkws.promotionFunction = function(name) {
 
 mkws.setMkwsConfig = function(overrides) {
   // Set global log_level flag early so that mkws.log() works
-  // Fall back to old "debug_level" setting for backwards compatibility
   var tmp = overrides.log_level;
-  if (typeof(tmp) === 'undefined') tmp = overrides.debug_level;
   if (typeof(tmp) !== 'undefined') mkws.log_level = tmp;
 
   var config_default = {
@@ -188,6 +174,7 @@ mkws.setMkwsConfig = function(overrides) {
     facets: ["xtargets", "subject", "author"], /* display facets, in this order, [] for none */
     responsive_design_width: undefined, /* a page with less pixel width considered as narrow */
     log_level: 1,     /* log level for development: 0..2 */
+    template_vars: {}, /* values that may be exposed to templates */
 
     dummy: "dummy"
   };
@@ -211,110 +198,6 @@ mkws.objectInheritingFrom = function(o) {
 }
 
 
-mkws.defaultTemplate = function(name) {
-  if (name === 'Record') {
-    return '\
-<table>\
-  <tr>\
-    <th>{{mkws-translate "Title"}}</th>\
-    <td>\
-      {{md-title}}\
-      {{#if md-title-remainder}}\
-        ({{md-title-remainder}})\
-      {{/if}}\
-      {{#if md-title-responsibility}}\
-        <i>{{md-title-responsibility}}</i>\
-      {{/if}}\
-    </td>\
-  </tr>\
-  {{#if md-date}}\
-  <tr>\
-    <th>{{mkws-translate "Date"}}</th>\
-    <td>{{md-date}}</td>\
-  </tr>\
-  {{/if}}\
-  {{#if md-author}}\
-  <tr>\
-    <th>{{mkws-translate "Author"}}</th>\
-    <td>{{md-author}}</td>\
-  </tr>\
-  {{/if}}\
-  {{#if md-electronic-url}}\
-  <tr>\
-    <th>{{mkws-translate "Links"}}</th>\
-    <td>\
-      {{#each md-electronic-url}}\
-        <a href="{{this}}">Link{{mkws-index1}}</a>\
-      {{/each}}\
-    </td>\
-  </tr>\
-  {{/if}}\
-  {{#mkws-if-any location having="md-subject"}}\
-  <tr>\
-    <th>{{mkws-translate "Subject"}}</th>\
-    <td>\
-      {{#mkws-first location having="md-subject"}}\
-        {{#if md-subject}}\
-          {{#mkws-commaList md-subject}}\
-            {{this}}{{/mkws-commaList}}\
-        {{/if}}\
-      {{/mkws-first}}\
-    </td>\
-  </tr>\
-  {{/mkws-if-any}}\
-  <tr>\
-    <th>{{mkws-translate "Locations"}}</th>\
-    <td>\
-      {{#mkws-commaList location}}\
-        {{mkws-attr "@name"}}{{/mkws-commaList}}\
-    </td>\
-  </tr>\
-</table>\
-';
-  } else if (name === "Summary") {
-    return '\
-<a href="#" id="{{_id}}" onclick="{{_onclick}}">\
-  <b>{{md-title}}</b>\
-</a>\
-{{#if md-title-remainder}}\
-  <span>{{md-title-remainder}}</span>\
-{{/if}}\
-{{#if md-title-responsibility}}\
-  <span><i>{{md-title-responsibility}}</i></span>\
-{{/if}}\
-{{#if md-date}}, {{md-date}}\
-{{#if location}}\
-, {{#mkws-first location}}{{mkws-attr "@name"}}{{/mkws-first}}\
-{{/if}}\
-{{#if md-medium}}\
-<span>, {{md-medium}}</span>\
-{{/if}}\
-{{/if}}\
-';
-  } else if (name === "Image") {
-    return '\
-      <a href="#" id="{{_id}}" onclick="{{_onclick}}">\
-        {{#mkws-first md-thumburl}}\
-          <img src="{{this}}" alt="{{../md-title}}"/>\
-        {{/mkws-first}}\
-        <br/>\
-      </a>\
-';
-  } else if (name === 'Facet') {
-    return '\
-<a href="#"\
-{{#if fn}}\
-onclick="mkws.{{fn}}(\'{{team}}\', \'{{field}}\', \'{{term}}\');return false;"\
-{{/if}}\
->{{term}}</a>\
-<span>{{count}}</span>\
-';
-  }
-
-  return null;
-};
-
-
 // The following functions are dispatchers for team methods that
 // are called from the UI using a team-name rather than implicit
 // context.
@@ -371,9 +254,61 @@ mkws.pazpar2_url = function() {
 };
 
 
+// We put a session token in window.name, as it's the only place to
+// keep data that is preserved across reloads and within-site
+// navigation. pz2.js picks this up and uses it as part of the
+// cookie-name, to ensure we get a new session when we need one.
+//
+// We want to use different sessions for different windows/tabs (so
+// they don't receive each other's messages), different hosts and
+// different paths on a host (since in general these will
+// authenticate as different libraries). So the window name needs to
+// include the hostname and the path from the URL, plus the token.
+//
+var token;
+if (window.name) {
+  token = window.name.replace(/.*\//, '');
+  mkws.log("Reusing existing window token '" + token + "'");
+} else {
+  // Incredible that the standard JavaScript runtime doesn't define a
+  // unique windowId. Instead, we have to make one up. And since there's
+  // no global area shared between windows, the best we can do for
+  // ensuring uniqueness is generating a random ID and crossing our
+  // fingers.
+  //
+  // Ten chars from 26 alpha-numerics = 36^10 = 3.65e15 combinations.
+  // At one per second, it will take 116 million years to duplicate a token
+  token = Math.random().toString(36).slice(2, 12);
+  mkws.log("Generated new window token '" + token + "'");
+}
+
+window.name = window.location.hostname + window.location.pathname + '/' + token;
+mkws.log("Using window.name '" + window.name + "'");
+
+
 // wrapper to provide local copy of the jQuery object.
 (function($) {
   var log = mkws.log;
+  var _old2new = { // Maps old-style widget names to new-style
+    'Authname': 'auth-name',
+    'ConsoleBuilder': 'console-builder',
+    'Coverart': 'cover-art',
+    'GoogleImage': 'google-image',
+    'MOTD': 'motd',
+    'MOTDContainer': 'motd-container',
+    'Perpage': 'per-page',
+    'SearchForm': 'search-form',
+    'ReferenceUniverse': 'reference-universe'
+  };
+  // Annoyingly, there is no built-in way to invert a hash
+  var _new2old = {};
+  for (var key in _old2new) {
+    if(_old2new.hasOwnProperty(key)) {
+      _new2old[_old2new[key]] = key;
+    }
+  }
+
+  mkws._old2new = _old2new;
 
   function handleNodeWithTeam(node, callback) {
     // First branch for DOM objects; second branch for jQuery objects
@@ -391,10 +326,19 @@ mkws.pazpar2_url = function() {
 
     for (var i = 0; i < list.length; i++) {
       var cname = list[i];
-      if (cname.match(/^mkwsTeam_/)) {
+      if (cname.match(/^mkws-team-/)) {
+        // New-style teamnames of the form mkws-team-xyz
+        teamName = cname.replace(/^mkws-team-/, '');
+      } else if (cname.match(/^mkwsTeam_/)) {
+        // Old-style teamnames of the form mkwsTeam_xyz
         teamName = cname.replace(/^mkwsTeam_/, '');
+      } else if (cname.match(/^mkws-/)) {
+        // New-style names of the from mkws-foo-bar
+        type = cname.replace(/^mkws-/, '');
       } else if (cname.match(/^mkws/)) {
-        type = cname.replace(/^mkws/, '');
+        // Old-style names of the form mkwsFooBar
+        var tmp = cname.replace(/^mkws/, '');
+        type = _old2new[tmp] || tmp.toLowerCase();
       }
     }
 
@@ -403,7 +347,7 @@ mkws.pazpar2_url = function() {
       teamName = "AUTO";
       // Autosearch widgets don't join team AUTO if there is already an
       // autosearch on the team or the team has otherwise gotten a query
-      if (node.hasAttribute("autosearch")) {
+      if (node.getAttribute("autosearch")) {
         if (mkws.autoHasAuto ||
             mkws.teams["AUTO"] && mkws.teams["AUTO"].config["query"]) {
           log("AUTO team already has a query, using unique team");
@@ -441,8 +385,8 @@ mkws.pazpar2_url = function() {
       for (var tname in mkws.teams) {
         var team = mkws.teams[tname];
         team.visitWidgets(function(t, w) {
-          var w1 = team.widget(t + "-Container-" + from);
-          var w2 = team.widget(t + "-Container-" + to);
+          var w1 = team.widget(t + "-container-" + from);
+          var w2 = team.widget(t + "-container-" + to);
           if (w1) {
             w1.node.hide();
           }
@@ -531,9 +475,14 @@ mkws.pazpar2_url = function() {
       var s = "";
       for (var type in mkws.widgetType2function) {
        if (s) s += ',';
-       s += '.mkws' + type;
-       s += ',.mkws' + type + "-Container-wide";
-       s += ',.mkws' + type + "-Container-narrow";
+       s += '.mkws-' + type;
+       s += ',.mkws-' + type + "-container-wide";
+       s += ',.mkws-' + type + "-container-narrow";
+        // Annoyingly, we also need to recognise old-style names
+        var oldtype = _new2old[type] || type.charAt(0).toUpperCase() + type.slice(1);
+       s += ',.mkws' + oldtype;
+       s += ',.mkws' + oldtype + "-Container-wide";
+       s += ',.mkws' + oldtype + "-Container-narrow";
       }
       return s;
     }
@@ -549,16 +498,15 @@ mkws.pazpar2_url = function() {
       handleNodeWithTeam(this, function(tname, type) {
         var myTeam = mkws.teams[tname];
         if (!myTeam) {
-          myTeam = mkws.teams[tname] = team($, tname);
-          log("made MKWS team '" + tname + "'");
+          myTeam = mkws.teams[tname] = mkws.makeTeam($, tname);
         }
 
         var oldHTML = this.innerHTML;
-        var myWidget = widget($, myTeam, type, this);
+        var myWidget = mkws.makeWidget($, myTeam, type, this);
         myTeam.addWidget(myWidget);
         var newHTML = this.innerHTML;
         if (newHTML !== oldHTML) {
-          log("widget " + tname + ":" + type + " HTML changed: reparsing");
+          myTeam.log("widget " + type + " HTML changed: reparsing");
           makeWidgetsWithin(level+1, $(this));
         }
       });
@@ -585,21 +533,6 @@ mkws.pazpar2_url = function() {
     if (message) greet += " :: " + message; 
     mkws.log(greet);
 
-    // TODO: Let's remove this soon
-    // Backwards compatibility: set new magic class names on any
-    // elements that have the old magic IDs.
-    var ids = [ "Switch", "Lang", "Search", "Pager", "Navi",
-                "Results", "Records", "Targets", "Ranking",
-                "Termlists", "Stat", "MOTD" ];
-    for (var i = 0; i < ids.length; i++) {
-      var id = 'mkws' + ids[i];
-      var node = $('#' + id);
-      if (node.attr('id')) {
-        node.addClass(id);
-        log("added magic class to '" + node.attr('id') + "'");
-      }
-    }
-
     // MKWS is not active until init() has been run against an object with widget nodes.
     // We only set initial configuration when MKWS is first activated.
     if (!mkws.isActive) {
@@ -670,16 +603,16 @@ mkws.pazpar2_url = function() {
     var now = $.now();
 
     log("walking MKWS nodes took " + (now-then) + " ms");
-
-    /*
-      for (var tName in mkws.teams) {
+    for (var tName in mkws.teams) {
       var myTeam = mkws.teams[tName]
-      log("team '" + tName + "' = " + myTeam + " ...");
-      myTeam.visitWidgets(function(t, w) {
-      log("  has widget of type '" + t + "': " + w);
-      });
-      }
-    */
+      myTeam.makePz2();
+      myTeam.log("made PZ2 object");
+      /*
+        myTeam.visitWidgets(function(t, w) {
+          log("  has widget of type '" + t + "': " + w);
+        });
+      */
+    }
 
     function sp_auth_url(config) {
       if (config.service_proxy_auth) {
index 866dc8a..bd9af8d 100644 (file)
@@ -96,3 +96,11 @@ Handlebars.registerHelper('mkws-commaList', function(items, options) {
 Handlebars.registerHelper('mkws-index1', function(obj) {
   return obj.data.index + 1;
 });
+
+Handlebars.registerHelper('mkws-repeat', function(count, options) {
+  var out = "";
+  for (var i = 0; i < count; i++) {
+    out += options.fn(this);
+  }
+  return out;
+});
index bc54f3c..7cc3792 100644 (file)
@@ -4,13 +4,13 @@
 
 //"use strict";
 // $(document).ready(function () {
-mkws.registerWidgetType('Popup', function() {
+mkws.registerWidgetType('popup', function() {
     var $ = mkws.$;
-    var debug = mkws.log;
+    var debug = this.log;
     debug("init popup window");
 
-    var popup_window = $(this.node); // mkws.registerWidgetType('Popup',....)
-    // var popup_window = $(".mkwsPopup"); // $(document).ready()
+    var popup_window = $(this.node);
+    // var popup_window = $(".mkws-popup mkwsPopup"); // $(document).ready()
     if (!popup_window) {
         debug("no popup found, skip...");
         return;
@@ -49,7 +49,7 @@ mkws.registerWidgetType('Popup', function() {
             close: function() {}
         });
 
-        // open at search query submit: "input.mkwsButton"
+        // open at search query submit: "input.mkws-button mkwsButton"
         var id_botton = that.attr("popup_button");
         if (id_botton) {
             $(id_botton).button().click(function() {
index 011d643..7ec9c2f 100644 (file)
@@ -8,7 +8,10 @@
 // limitCategory(), delimitTarget(), delimitQuery(), showPage(),
 // pagerPrev(), pagerNext().
 //
-function team($, teamName) {
+// Before the team can be used for searching and related operations,
+// its pz2 object must be created by calling team.makePz2().
+//
+mkws.makeTeam = function($, teamName) {
   var that = {};
   var m_teamName = teamName;
   var m_submitted = false;
@@ -41,11 +44,13 @@ function team($, teamName) {
   that.submitted = function() { return m_submitted; };
   that.sortOrder = function() { return m_sortOrder; };
   that.perpage = function() { return m_perpage; };
+  that.query = function() { return m_query; };
   that.totalRecordCount = function() { return m_totalRecordCount; };
   that.currentPage = function() { return m_currentPage; };
   that.currentRecordId = function() { return m_currentRecordId; };
   that.currentRecordData = function() { return m_currentRecordData; };
   that.filters = function() { return m_filterSet; };
+  that.gotRecords = function() { return m_gotRecords; };
 
   // Accessor methods for individual widgets: writers
   that.set_sortOrder = function(val) { m_sortOrder = val };
@@ -59,17 +64,17 @@ function team($, teamName) {
   //    team.queue("eventName").subscribe(function(param1, param2 ...) { ... });
   //    team.queue("eventName").publish(arg1, arg2, ...);
   //
-  var queues = {};
+  var m_queues = {};
   function queue(id) {
-    if (!queues[id]) {
+    if (!m_queues[id]) {
       var callbacks = $.Callbacks();
-      queues[id] = {
+      m_queues[id] = {
         publish: callbacks.fire,
         subscribe: callbacks.add,
         unsubscribe: callbacks.remove
       };
     }
-    return queues[id];
+    return m_queues[id];
   };
   that.queue = queue;
 
@@ -89,24 +94,7 @@ function team($, teamName) {
 
   m_sortOrder = config.sort_default;
   m_perpage = config.perpage_default;
-
-  // create a parameters array and pass it to the pz2's constructor
-  // then register the form submit event with the pz2.search function
-  // autoInit is set to true on default
-  m_paz = new pz2({ "windowid": teamName,
-                    "pazpar2path": mkws.pazpar2_url(),
-                    "usesessions" : config.use_service_proxy ? false : true,
-                    "oninit": onInit,
-                    "onbytarget": onBytarget,
-                    "onstat": onStat,
-                    "onterm": (config.facets.length ? onTerm : undefined),
-                    "onshow": onShow,
-                    "onrecord": onRecord,
-                    "showtime": 500,            //each timer (show, stat, term, bytarget) can be specified this way
-                    "termlist": config.facets.join(',')
-                  });
-  log("created main pz2 object");
-
   // pz2.js event handlers:
   function onInit() {
     log("init");
@@ -149,6 +137,7 @@ function team($, teamName) {
     log("record");
     // FIXME: record is async!!
     clearTimeout(m_paz.recordTimer);
+    queue("record").publish(data);
     var detRecordDiv = findnode(recordDetailsId(data.recid[0]));
     if (detRecordDiv.length) {
       // in case on_show was faster to redraw element
@@ -161,15 +150,54 @@ function team($, teamName) {
   }
 
 
+  // create a parameters array and pass it to the pz2's constructor
+  // then register the form submit event with the pz2.search function
+  // autoInit is set to true on default
+  that.makePz2 = function() {
+    log("m_queues=" + $.toJSON(m_queues));
+    var params = {
+      "windowid": teamName,
+      "pazpar2path": mkws.pazpar2_url(),
+      "usesessions" : config.use_service_proxy ? false : true,
+      "showtime": 500,            //each timer (show, stat, term, bytarget) can be specified this way
+      "termlist": config.facets.join(',')
+    };
+
+    params.oninit = onInit;
+    if (m_queues.targets) {
+      params.onbytarget = onBytarget;
+      log("setting bytarget callback");
+    }
+    if (m_queues.stat) {
+      params.onstat = onStat;
+      log("setting stat callback");
+    }
+    if (m_queues.termlists && config.facets.length) {
+      params.onterm = onTerm;
+      log("setting term callback");
+    }
+    if (m_queues.records) {
+      log("setting show callback");
+      params.onshow = onShow;
+      // Record callback is subscribed from records callback
+      log("setting record callback");
+      params.onrecord = onRecord;
+    }
+
+    m_paz = new pz2(params);
+    log("created main pz2 object");
+  }
+
+
   // Used by the Records widget and onRecord()
   function recordElementId(s) {
-    return 'mkwsRec_' + s.replace(/[^a-z0-9]/ig, '_');
+    return 'mkws-rec_' + s.replace(/[^a-z0-9]/ig, '_');
   }
   that.recordElementId = recordElementId;
 
   // Used by onRecord(), showDetails() and renderDetails()
   function recordDetailsId(s) {
-    return 'mkwsDet_' + s.replace(/[^a-z0-9]/ig, '_');
+    return 'mkws-det_' + s.replace(/[^a-z0-9]/ig, '_');
   }
 
 
@@ -303,13 +331,19 @@ function team($, teamName) {
     m_paz.search(m_query, m_perpage, m_sortOrder, pp2filter, undefined, params);
   }
 
+  // fetch record details to be retrieved from the record queue
+  that.fetchDetails = function(recId) {
+    log("fetchDetails() requesting record '" + recId + "'");
+    m_paz.record(recId);
+  };
+
 
   // switching view between targets and records
   function switchView(view) {
-    var targets = widgetNode('Targets');
-    var results = widgetNode('Results') || widgetNode('Records');
-    var blanket = widgetNode('Blanket');
-    var motd    = widgetNode('MOTD');
+    var targets = widgetNode('targets');
+    var results = widgetNode('results') || widgetNode('records');
+    var blanket = widgetNode('blanket');
+    var motd    = widgetNode('motd');
 
     switch(view) {
     case 'targets':
@@ -356,10 +390,10 @@ function team($, teamName) {
     teamName = teamName || m_teamName;
 
     if (teamName === 'AUTO') {
-      selector = (selector + '.mkwsTeam_' + teamName + ',' +
-                  selector + ':not([class^="mkwsTeam"],[class*=" mkwsTeam"])');
+      selector = (selector + '.mkws-team-' + teamName + ',' +
+                  selector + ':not([class^="mkws-team"],[class*=" mkws-team"])');
     } else {
-      selector = selector + '.mkwsTeam_' + teamName;
+      selector = selector + '.mkws-team-' + teamName;
     }
 
     var node = $(selector);
@@ -374,53 +408,58 @@ function team($, teamName) {
   }
 
   function renderDetails(data, marker) {
-    var template = loadTemplate("Record");
+    var template = loadTemplate("details");
     var details = template(data);
-    return '<div class="mkwsDetails mkwsTeam_' + m_teamName + '" ' +
+    return '<div class="mkws-details mkwsDetails mkwsTeam_' + m_teamName + '" ' +
       'id="' + recordDetailsId(data.recid[0]) + '">' + details + '</div>';
   }
   that.renderDetails = renderDetails;
 
 
   that.registerTemplate = function(name, text) {
+    if(mkws._old2new.hasOwnProperty(name)) {
+      mkws.log("Warning: registerTemplate old widget name: " + name + " => " + mkws._old2new[name]);
+      name = mkws._old2new[name];
+    }
     m_templateText[name] = text;
   };
 
 
   function loadTemplate(name, fallbackString) {
-    var template = m_template[name];
+    if(mkws._old2new.hasOwnProperty(name)) {
+       mkws.log("Warning loadTemplate: old widget name: " + name + " => " + mkws._old2new[name]);
+       name = mkws._old2new[name];
+    }
 
-    if (template === undefined) {
-      // Fall back to generic template if there is no team-specific one
+    var template = m_template[name];
+    if (template === undefined && Handlebars.compile) {
       var source;
-      var node = $(".mkwsTemplate_" + name + " .mkwsTeam_" + that.name());
+      var node = $(".mkws-template-" + name + " .mkws-team-" + that.name());
       if (node && node.length < 1) {
-        node = $(".mkwsTemplate_" + name);
-      }
-      if (node) {
-        source = node.html();
+        node = $(".mkws-template-" + name);
       }
-
-      // If the template is not defined in HTML, check the following
-      // in order: template registered in the team by a widget;
-      // fallback string provided on this invocation; global default.
-      if (!source) {
-        source = m_templateText[name];
-      }
-      if (!source) {
-        source = fallbackString;
+      if (node) source = node.html();
+      if (!source) source = m_templateText[name];
+      if (source) {
+        template = Handlebars.compile(source);
+        log("compiled template '" + name + "'");
       }
-      if (!source) {
-        source = mkws.defaultTemplate(name);
-      }
-
-      if (!source) return null;
-      template = Handlebars.compile(source);
-      log("compiled template '" + name + "'");
+    }
+    //if (template === undefined) template = mkws_templatesbyteam[m_teamName][name];
+    if (template === undefined && Handlebars.templates) {
+      template = Handlebars.templates["mkws-template-" + name];
+    }
+    if (template === undefined && mkws.defaultTemplates) {
+      template = mkws.defaultTemplates[name];
+    }
+    if (template) {
       m_template[name] = template;
+      return template;
     }
-
-    return template;
+    else {
+      log("No MKWS template for " + name);
+      return null;
+    }  
   }
   that.loadTemplate = loadTemplate;
 
index b1e0b1f..b96dad2 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Authname', function() {
+mkws.registerWidgetType('auth-name', function() {
   var that = this;
 
   this.team.queue("authenticated").subscribe(function(authName) {
index 6468e86..110f24a 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Builder', function() {
+mkws.registerWidgetType('builder', function() {
   var that = this;
   var team = this.team;
 
@@ -8,11 +8,11 @@ mkws.registerWidgetType('Builder', function() {
   });
   this.node.append(button);
   button.click(function() {
-    var   query = team.widget('Query').value();
-    var    sort = team.widget('Sort').value();
-    var perpage = team.widget('Perpage').value();
+    var   query = team.widget('query').value();
+    var    sort = team.widget('sort').value();
+    var perpage = team.widget('per-page').value();
 
-    var html = ('<div class="mkwsRecords" ' +
+    var html = ('<div class="mkws-records mkwsRecords" ' +
                 'autosearch="' + query + '" ' +
                 'sort="' + sort + '" ' +
                 'perpage="' + perpage + '"></div>');
@@ -21,8 +21,8 @@ mkws.registerWidgetType('Builder', function() {
   });
 });
 
-mkws.registerWidgetType('ConsoleBuilder', function() {
-  mkws.promotionFunction('Builder').call(this);
+mkws.registerWidgetType('console-builder', function() {
+  mkws.promotionFunction('builder').call(this);
   this.callback = function(s) {
     console.log("generated widget: " + s);
   }
index 6982db8..fc8896f 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Categories', function() {
+mkws.registerWidgetType('categories', function() {
   var that = this;
 
   if (!mkws.authenticated) {
@@ -20,7 +20,7 @@ mkws.registerWidgetType('Categories', function() {
 
       var text = [];
       text.push("Select category: ");
-      text.push("<select name='mkwsCategory' " +
+      text.push("<select name='mkws-category mkwsCategory' " +
                 "onchange='mkws.limitCategory(\"" + that.team.name() + "\", this.value)'>");
       text.push("<option value=''>[All]</option>");
       $(data).find('category').each(function() {
index 4ea6cd8..b520e35 100644 (file)
@@ -1,4 +1,4 @@
-mkws.registerWidgetType('Log', function() {
+mkws.registerWidgetType('log', function() {
   var that = this;
 
   this.team.queue("log").subscribe(function(teamName, timestamp, message) {
index fcffe5b..ac43dcd 100644 (file)
+(function($) { // jQuery wrapper
+
 // Functions follow for promoting the regular widget object into
 // widgets of specific types. These could be moved into their own
 // source files.
 
 
-mkws.registerWidgetType('Targets', function() {
+mkws.registerWidgetType('targets', function() {
   if (!this.config.show_switch) return;
   var that = this;
-  var M = mkws.M;
 
   this.node.html('No information available yet.');
   this.node.css("display", "none");
 
   this.team.queue("targets").subscribe(function(data) {
-    var table ='<table><thead><tr>' +
-      '<td>' + M('Target ID') + '</td>' +
-      '<td>' + M('Hits') + '</td>' +
-      '<td>' + M('Diags') + '</td>' +
-      '<td>' + M('Records') + '</td>' +
-      '<td>' + M('State') + '</td>' +
-      '</tr></thead><tbody>';
-
+    // There is a bug in pz2.js wherein it makes each data object an array but
+    // simply assigns properties to it.
+    // TODO: remove this when PAZ-946 is addressed.
+    var cleandata = [];
     for (var i = 0; i < data.length; i++) {
-      table += "<tr><td>" + data[i].id +
-        "</td><td>" + data[i].hits +
-        "</td><td>" + data[i].diagnostic +
-        "</td><td>" + data[i].records +
-        "</td><td>" + data[i].state + "</td></tr>";
+      var cur = {};
+      cur.id = data[i].id;
+      cur.hits = data[i].hits;
+      cur.diagnostic = data[i].diagnostic;
+      cur.records = data[i].records;
+      cur.state = data[i].state;
+      cleandata.push(cur);
     }
 
-    table += '</tbody></table>';
-    that.node.html(table);
+    var template = that.team.loadTemplate(that.config.template || "targets");
+    that.node.html(template({data: cleandata}));
   });
 });
 
 
-mkws.registerWidgetType('Stat', function() {
+mkws.registerWidgetType('stat', function() {
   var that = this;
-  var M = mkws.M;
-
   this.team.queue("stat").subscribe(function(data) {
-    that.node.html(' -- ' +
-                      '<span class="mkwsClientCount">' + M('Active clients') + ': ' + data.activeclients + '/' + data.clients + '</span>' +
-                      ' -- ' +
-                      M('Retrieved records') + ': ' + data.records + '/' + data.hits);
+    var template = that.team.loadTemplate(that.config.template || "stat");
+    that.node.html(template(data));
   });
 });
 
 
-mkws.registerWidgetType('Pager', function() {
+mkws.registerWidgetType('pager', function() {
   var that = this;
   var M = mkws.M;
 
   this.team.queue("pager").subscribe(function(data) {
-    that.node.html(drawPager(data))
-
-    function drawPager(data) {
-      var teamName = that.team.name();
-      var s = '<div style="float: right">' + M('Displaying') + ': '
-        + (data.start + 1) + ' ' + M('to') + ' ' + (data.start + data.num) +
-        ' ' + M('of') + ' ' + data.merged + ' (' + M('found') + ': '
-        + data.total + ')</div>';
-
-      //client indexes pages from 1 but pz2 from 0
-      var onsides = 6;
-      var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
-      var currentPage = that.team.currentPage();
-
-      var firstClkbl = (currentPage - onsides > 0)
-        ? currentPage - onsides
-        : 1;
-
-      var lastClkbl = firstClkbl + 2*onsides < pages
-        ? firstClkbl + 2*onsides
-        : pages;
-
-      var prev = '<span class="mkwsPrev">&#60;&#60; ' + M('Prev') + '</span> | ';
-      if (currentPage > 1)
-        prev = '<a href="#" class="mkwsPrev" onclick="mkws.pagerPrev(\'' + teamName + '\');">'
-        +'&#60;&#60; ' + M('Prev') + '</a> | ';
-
-      var middle = '';
-      for(var i = firstClkbl; i <= lastClkbl; i++) {
-        var numLabel = i;
-        if(i == currentPage)
-          numLabel = '<span class="mkwsCurrentPage">' + i + '</span>';
-
-        middle += '<a href="#" onclick="mkws.showPage(\'' + teamName + '\', ' + i + ')"> '
-          + numLabel + ' </a>';
+    var teamName = that.team.name();
+    var output = {};
+    output.first = data.start + 1;
+    output.last = data.start + data.num;
+    output.count = data.merged;
+    output.found = data.total;
+
+    //client indexes pages from 1 but pz2 from 0
+    var onsides = 6;
+    var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
+    var currentPage = that.team.currentPage();
+
+    var firstClkbl = (currentPage - onsides > 0)
+      ? currentPage - onsides
+      : 1;
+    var lastClkbl = firstClkbl + 2*onsides < pages
+      ? firstClkbl + 2*onsides
+      : pages;
+
+    if (firstClkbl > 1) output.morePrev = true;
+    if (lastClkbl < pages) output.moreNext = true;
+
+    if (currentPage > 1) output.prevClick = "mkws.pagerPrev(\'" + teamName + "\');";
+
+    output.pages = [];
+    for(var i = firstClkbl; i <= lastClkbl; i++) {
+      var o = {};
+      o.number = i;
+      if (i !== currentPage) {
+        o.click = "mkws.showPage(\'" + teamName + "\', " + i + ");";
       }
+      output.pages.push(o);
+    }
 
-      var next = ' | <span class="mkwsNext">' + M('Next') + ' &#62;&#62;</span>';
-      if (pages - currentPage > 0)
-        next = ' | <a href="#" class="mkwsNext" onclick="mkws.pagerNext(\'' + teamName + '\')">'
-        + M('Next') + ' &#62;&#62;</a>';
-
-      var predots = '';
-      if (firstClkbl > 1)
-        predots = '...';
-
-      var postdots = '';
-      if (lastClkbl < pages)
-        postdots = '...';
+    if (pages - currentPage > 0) output.nextClick = "mkws.pagerNext(\'" + teamName + "\')";
 
-      s += '<div style="float: clear">'
-        + prev + predots + middle + postdots + next + '</div>';
+    var template = that.team.loadTemplate(that.config.template || "pager");
+    that.node.html(template(output));
+  });
+});
 
-      return s;
+mkws.registerWidgetType('details', function() {
+  var that = this;
+  var recid = that.node.attr("data-mkws-recid");
+  if (this.team.gotRecords()) { 
+    that.team.fetchDetails(recid);
+  } else {
+    this.team.queue("firstrecords").subscribe(function() {
+      that.team.fetchDetails(recid);
+    });
+  }
+  this.team.queue("record").subscribe(function(data) {
+    console.log(data);
+    if ($.inArray(recid, data.recid) > -1) {
+      var template = that.team.loadTemplate(that.config.template || "details");
+      that.node.html(template(data));
     }
   });
+  that.autosearch();
 });
 
-
-mkws.registerWidgetType('Records', function() {
+mkws.registerWidgetType('records', function() {
   var that = this;
   var team = this.team;
 
   this.team.queue("records").subscribe(function(data) {
-    var html = [];
     for (var i = 0; i < data.hits.length; i++) {
       var hit = data.hits[i];
       that.team.queue("record").publish(hit);
-      var divId = team.recordElementId(hit.recid[0]);
-      html.push('<div class="mkwsSummary mkwsTeam_' + team.name() + ' ' + divId + '">', renderSummary(hit), '</div>');
+      hit.detailLinkId = team.recordElementId(hit.recid[0]);
+      hit.detailClick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;";
+      hit.containerClass = "mkws-summary mkwsSummary mkws-team-" + team.name();
+      hit.containerClass += " " + hit.detailLinkId;
       // ### At some point, we may be able to move the
       // m_currentRecordId and m_currentRecordData members
       // from the team object into this widget.
       if (hit.recid == team.currentRecordId()) {
-        if (team.currentRecordData())
-          html.push(team.renderDetails(team.currentRecordData()));
+        if (team.currentRecordData()) {
+          hit.renderedDetails = team.renderDetails(team.currentRecordData());
+        } 
       }
     }
-    that.node.html(html.join(''));
-
-    function renderSummary(hit) {
-      var template = team.loadTemplate(that.config.template || "Summary");
-      hit._id = team.recordElementId(hit.recid[0]);
-      hit._onclick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;"
-      return template(hit);
-    }
+    var template = team.loadTemplate(that.config.template || "records");
+    var summaryPartial = team.loadTemplate("summary");
+    var tdata = $.extend({}, {"hits": data.hits}, that.config.template_vars);
+    that.node.html(template(tdata, {"partials":{"summary":summaryPartial}}));
   });
 
   that.autosearch();
 });
 
 
-mkws.registerWidgetType('Navi', function() {
+mkws.registerWidgetType('navi', function() {
   var that = this;
   var teamName = this.team.name();
-  var M = mkws.M;
 
   this.team.queue("navi").subscribe(function() {
     var filters = that.team.filters();
-    var text = "";
+    var output = {filters:[]};
 
     filters.visitTargets(function(id, name) {
-      if (text) text += " | ";
-      text += M('source') + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitTarget(\'' + teamName +
-        "', '" + id + "'" + ');return false;">' + name + '</a>';
+      var cur = {};
+      cur.facet = 'source';
+      cur.value = name;
+      cur.click = "mkws.delimitTarget('" + teamName + "', '" + id + "'); return false;";
+      output.filters.push(cur);
     });
 
     filters.visitFields(function(field, value) {
-      if (text) text += " | ";
-      text += M(field) + ': <a class="mkwsRemovable" href="#" onclick="mkws.delimitQuery(\'' + teamName +
-        "', '" + field + "', '" + value + "'" +
-        ');return false;">' + value + '</a>';
+      var cur = {};
+      cur.facet = field;
+      cur.value = value;
+      cur.click = "mkws.delimitQuery('" + teamName + "', '" + field + "', '" + value + "'" + ");return false;";
+      output.filters.push(cur);
     });
 
-    that.node.html(text);
+    var template = that.team.loadTemplate(that.config.template || "navi");
+    that.node.html(template(output));
   });
 });
 
@@ -174,7 +172,7 @@ mkws.registerWidgetType('Navi', function() {
 // It seems this and the Perpage widget doen't need to subscribe to
 // anything, since they produce events rather than consuming them.
 //
-mkws.registerWidgetType('Sort', function() {
+mkws.registerWidgetType('sort', function() {
   var that = this;
 
   this.node.change(function() {
@@ -187,7 +185,7 @@ mkws.registerWidgetType('Sort', function() {
 });
 
 
-mkws.registerWidgetType('Perpage', function() {
+mkws.registerWidgetType('per-page', function() {
   var that = this;
 
   this.node.change(function() {
@@ -200,137 +198,87 @@ mkws.registerWidgetType('Perpage', function() {
 });
 
 
-mkws.registerWidgetType('Done', function() {
+mkws.registerWidgetType('done', function() {
   var that = this;
-
   this.team.queue("complete").subscribe(function(n) {
-    that.node.html("Search complete: found " + n + " records");
+    var template = that.team.loadTemplate(that.config.template || "done");
+    that.node.html(template({count: n}));
   });
 });
 
 
-mkws.registerWidgetType('Switch', function() {
+mkws.registerWidgetType('switch', function() {
   if (!this.config.show_switch) return;
   var tname = this.team.name();
-  this.node.html('\
-<a href="#" onclick="mkws.switchView(\'' + tname + '\', \'records\')">Records</a><span> \
-| \
-</span><a href="#" onclick="mkws.switchView(\'' + tname + '\', \'targets\')">Targets</a>');
+  var output = {};
+  output.recordClick = "mkws.switchView(\'" + tname + "\', \'records\')";
+  output.targetClick = "mkws.switchView(\'" + tname + "\', \'targets\')";
+  var template = this.team.loadTemplate(this.config.template || "switch");
+  this.node.html(template(output));
   this.hideWhenNarrow();
 });
 
 
-mkws.registerWidgetType('Search', function() {
-  var tname = this.team.name();
-  var M = mkws.M;
-
-  this.node.html('\
-<form name="mkwsSearchForm" class="mkwsSearchForm mkwsTeam_' + tname + '" action="" >\
-  <input class="mkwsQuery mkwsTeam_' + tname + '" type="text" size="' + this.config.query_width + '" />\
-  <input class="mkwsButton mkwsTeam_' + tname + '" type="submit" value="' + M('Search') + '" />\
-</form>');
+mkws.registerWidgetType('search', function() {
+  var output = {};
+  output.team = this.team.name();
+  output.queryWidth = this.config.query_width;
+  var template = this.team.loadTemplate(this.config.template || "search");
+  this.node.html(template(output));
 });
 
 
-mkws.registerWidgetType('SearchForm', function() {
+mkws.registerWidgetType('search-form', function() {
   var team = this.team;
   this.node.submit(function() {
-    var val = team.widget('Query').value();
+    var val = team.widget('query').value();
     team.newSearch(val);
     return false;
   });
 });
 
 
-mkws.registerWidgetType('Results', function() {
-  var tname = this.team.name();
-
-  this.node.html('\
-<table width="100%" border="0" cellpadding="6" cellspacing="0">\
-  <tr>\
-    <td class="mkwsTermlists-Container-wide mkwsTeam_' + tname + '" width="250" valign="top">\
-      <div class="mkwsTermlists mkwsTeam_' + tname + '"></div>\
-    </td>\
-    <td class="mkwsMOTDContainer mkwsTeam_' + tname + '" valign="top">\
-      <div class="mkwsRanking mkwsTeam_' + tname + '"></div>\
-      <div class="mkwsPager mkwsTeam_' + tname + '"></div>\
-      <div class="mkwsNavi mkwsTeam_' + tname + '"></div>\
-      <div class="mkwsRecords mkwsTeam_' + tname + '"></div>\
-    </td>\
-  </tr>\
-  <tr>\
-    <td colspan="2">\
-      <div class="mkwsTermlists-Container-narrow mkwsTeam_' + tname + '"></div>\
-    </td>\
-  </tr>\
-</table>');
-
+mkws.registerWidgetType('results', function() {
+  var template = this.team.loadTemplate(this.config.template || "results");
+  this.node.html(template({team: this.team.name()}));
   this.autosearch();
 });
 
 
-mkws.registerWidgetType('Ranking', function() {
-  var tname = this.team.name();
-  var that = this;
-  var M = mkws.M;
-
-  var s = '<form>';
-  if (this.config.show_sort) {
-    s +=  M('Sort by') + ' ' + mkwsHtmlSort() + ' ';
+mkws.registerWidgetType('ranking', function() {
+  var output = {};
+  output.perPage = [];
+  output.sort = [];
+  output.team = this.team.name();
+  output.showSort = this.config.show_sort;
+  output.showPerPage = this.config.show_perpage;
+
+  var order = this.team.sortOrder();
+  this.log("making sort, sortOrder = '" + order + "'");
+  for (var i = 0; i < this.config.sort_options.length; i++) {
+    var cur = {};
+    var opt = this.config.sort_options[i];
+    cur.key = opt[0];
+    cur.label = opt.length == 1 ? opt[0] : opt[1];
+    if (order == cur.key || order == cur.label) cur.selected = true;
+    output.sort.push(cur);
   }
-  if (this.config.show_perpage) {
-    s += M('and show') + ' ' + mkwsHtmlPerpage() + ' ' + M('per page') + '.';
-  }
-  s += '</form>';
-
-  this.node.html(s);
-
-
-  function mkwsHtmlSort() {
-    var order = that.team.sortOrder();
-
-    that.log("making sort HTML, sortOrder = '" + order + "'");
-    var sort_html = '<select class="mkwsSort mkwsTeam_' + tname + '">';
 
-    for(var i = 0; i < that.config.sort_options.length; i++) {
-      var opt = that.config.sort_options[i];
-      var key = opt[0];
-      var val = opt.length == 1 ? opt[0] : opt[1];
-
-      sort_html += '<option value="' + key + '"';
-      if (order == key || order == val) {
-        sort_html += ' selected="selected"';
-      }
-      sort_html += '>' + M(val) + '</option>';
-    }
-    sort_html += '</select>';
-
-    return sort_html;
+  var perpage = this.team.perpage();
+  this.log("making perpage, perpage = " + perpage);
+  for(var i = 0; i < this.config.perpage_options.length; i++) {
+    var cur = {};
+    cur.perPage = this.config.perpage_options[i];
+    if (cur.perPage == perpage) cur.selected = true;
+    output.perPage.push(cur);
   }
 
-  function mkwsHtmlPerpage() {
-    var perpage = that.team.perpage();
-
-    that.log("making perpage HTML, perpage = " + perpage);
-    var perpage_html = '<select class="mkwsPerpage mkwsTeam_' + tname + '">';
-
-    for(var i = 0; i < that.config.perpage_options.length; i++) {
-      var key = that.config.perpage_options[i];
-
-      perpage_html += '<option value="' + key + '"';
-      if (key == perpage) {
-        perpage_html += ' selected="selected"';
-      }
-      perpage_html += '>' + key + '</option>';
-    }
-    perpage_html += '</select>';
-
-    return perpage_html;
-  }
+  var template = this.team.loadTemplate(this.config.template || "ranking");
+  this.node.html(template(output));
 });
 
 
-mkws.registerWidgetType('Lang', function() {
+mkws.registerWidgetType('lang', function() {
   // dynamic URL or static page? /path/foo?query=test
   /* create locale language menu */
   if (!this.config.show_lang) return;
@@ -347,34 +295,30 @@ mkws.registerWidgetType('Lang', function() {
   }
 
   for (var k in mkws.locale_lang) {
-    if (toBeIncluded[k] || lang_options.length == 0)
-      list.push(k);
+    if (toBeIncluded[k] || lang_options.length == 0) {
+      cur = {};
+      if (lang === k) cur.selected = true;
+      cur.code = k;
+      cur.url = lang_url(k);
+      list.push(cur);
+    }
   }
 
   // add english link
-  if (lang_options.length == 0 || toBeIncluded[lang_default])
-    list.push(lang_default);
+  if (lang_options.length == 0 || toBeIncluded[lang_default]) {
+      cur = {};
+      if (lang === lang_default) cur.selected = true;
+      cur.code = lang_default;
+      cur.url = lang_url(lang_default);
+      list.push(cur);
+  }
 
   this.log("language menu: " + list.join(", "));
 
-  /* the HTML part */
-  var data = "";
-  for (var i = 0; i < list.length; i++) {
-    var l = list[i];
-    if (data)
-      data += ' | ';
-
-    if (lang == l) {
-      data += ' <span>' + l + '</span> ';
-    } else {
-      data += ' <a href="' + lang_url(l) + '">' + l + '</a> '
-    }
-  }
-
-  this.node.html(data);
+  var template = this.team.loadTemplate(this.config.template || "lang");
+  this.node.html(template({languages: list}));
   this.hideWhenNarrow();
 
-
   // set or re-set "lang" URL parameter
   function lang_url(lang) {
     var query = location.search;
@@ -396,8 +340,8 @@ mkws.registerWidgetType('Lang', function() {
 });
 
 
-mkws.registerWidgetType('MOTD', function() {
-  var container = this.team.widget('MOTDContainer');
+mkws.registerWidgetType('motd', function() {
+  var container = this.team.widget('motd-container');
   if (container) {
     // Move the MOTD from the provided element down into the container
     this.node.appendTo(container.node);
@@ -409,7 +353,7 @@ mkws.registerWidgetType('MOTD', function() {
 // is copied up into its team, allowing it to affect other widgets in
 // the team.
 //
-mkws.registerWidgetType('Config', function() {
+mkws.registerWidgetType('config', function() {
   var c = this.config;
   for (var name in c) {
     if (c.hasOwnProperty(name)) {
@@ -420,21 +364,15 @@ mkws.registerWidgetType('Config', function() {
 });
 
 
-mkws.registerWidgetType('Progress', function() {
+mkws.registerWidgetType('progress', function() {
   var that = this;
-
   this.node.hide();
   this.team.queue("stat").subscribe(function(data) {
-    var s = '<span class="mkwsDone">';
-    for (var i = 0; i < data.clients; i++) {
-      if (i == data.clients - data.activeclients) {
-        s += '</span>';
-        s += '<span class="mkwsWaiting">';
-      }
-      s += '&#x2588;';
-    }
-    s += '</span>';
-    that.node.html(s);
+    var template = that.team.loadTemplate(that.config.template || "progress");
+    that.node.html(template({
+      done: data.clients - data.activeclients,
+      waiting: data.activeclients
+    }));
     that.node.show();
   });
 });
@@ -445,8 +383,9 @@ mkws.registerWidgetType('Progress', function() {
 // no actual functionality. We register these to prevent ignorable
 // warnings when they occur.
 
-mkws.registerWidgetType('Query', function() {});
-mkws.registerWidgetType('MOTDContainer', function() {});
-mkws.registerWidgetType('Button', function() {});
+mkws.registerWidgetType('query', function() {});
+mkws.registerWidgetType('motd-container', function() {});
+mkws.registerWidgetType('button', function() {});
 
 
+})(mkws.$); // jQuery wrapper
index 106c8a3..ad62425 100644 (file)
@@ -1,24 +1,32 @@
-mkws.registerWidgetType('Record', function() {
-  mkws.promotionFunction('Records').call(this);
+// A widget for a record-list of a single record
+mkws.registerWidgetType('record', function() {
   if (!this.config.maxrecs) this.config.maxrecs = 1;
+  var that = this;
+  var team = this.team;
+  team.queue("records").subscribe(function(data) {
+    var template = team.loadTemplate(that.config.template || "details");
+    var targs = mkws.$.extend({}, data.hits[0], that.config.template_vars);
+    that.node.html(template(targs));
+  });
+  that.autosearch();
 });
 
-mkws.registerWidgetType('Image', function() {
-  mkws.promotionFunction('Record').call(this);
-  if (!this.config.template) this.config.template = 'Image';
+mkws.registerWidgetType('images', function() {
+  mkws.promotionFunction('records').call(this);
+  if (!this.config.template) this.config.template = 'images';
 });
 
-mkws.registerWidgetType('GoogleImage', function() {
-  mkws.promotionFunction('Image').call(this);
+mkws.registerWidgetType('google-image', function() {
+  mkws.promotionFunction('images').call(this);
   if (!this.config.target) this.config.target = 'Google_Images';
 });
 
-mkws.registerWidgetType('Lolcat', function() {
-  mkws.promotionFunction('GoogleImage').call(this);
+mkws.registerWidgetType('lolcat', function() {
+  mkws.promotionFunction('google-image').call(this);
   if (!this.config.autosearch) this.config.autosearch = 'kitteh';
 });
 
-mkws.registerWidgetType('Coverart', function() {
-  mkws.promotionFunction('Image').call(this);
+mkws.registerWidgetType('cover-art', function() {
+  mkws.promotionFunction('images').call(this);
   if (!this.config.target) this.config.target = 'AmazonBooks';
 });
index b1044d2..85c04b8 100644 (file)
@@ -1,20 +1,7 @@
-mkws.registerWidgetType('Reference', function() {
-  mkws.promotionFunction('Record').call(this);
+mkws.registerWidgetType('reference', function() {
+  mkws.promotionFunction('record').call(this);
   if (!this.config.target) this.config.target = 'wikimedia_wikipedia_single_result';
-  if (!this.config.template) this.config.template = 'Reference';
-  var nPara = this.config.paragraphs || 0;
-  var nSent = this.config.sentences || 0;
-
-  this.team.registerTemplate('Reference', '\
-  <img src="{{md-thumburl}}" alt="{{md-title}}">\
-  <h1><a href="{{md-electronic-url}}">{{md-title}}</a></h1>\
-{{#if md-title-remainder}}\
-  <b>{{md-title-remainder}}</b>\
-{{/if}}\
-{{#if md-title-responsibility}}\
-  <i>{{md-title-responsibility}}</i>\
-{{/if}}\
-  {{{mkws-paragraphs md-description ' + nPara + ' ' + nSent + '}}}\
-  <p class="mkwsCredit">Wikipedia</p>\
-');
+  if (!this.config.template) this.config.template = 'reference';
+  this.config.template_vars.paragraphs = this.config.paragraphs || 0;
+  this.config.template_vars.sentences = this.config.sentences || 0;
 });
index fef616f..e3dc55e 100644 (file)
@@ -1,34 +1,28 @@
-mkws.registerWidgetType('Termlists', function() {
-  var that = this;
-
+mkws.registerWidgetType('termlists', function() {
   // Initially hide the termlists; display when we get results
-  mkws.$(document).ready(function() {
-    that.node.hide();
-  });
-  this.team.queue("termlists").subscribe(function(data) {
-    that.node.show();
+  var that = this;
+  var team = this.team;
+  team.queue("termlists").subscribe(function(data) {
+    that.node.addClass("active");
   });
 
-  var acc = [];
-  var facets = this.config.facets;
-  acc.push('<div class="mkwsTermlistsTitle">' + mkws.M('Termlists') + '</div>');
-  for (var i = 0; i < facets.length; i++) {
-    acc.push('<div class="mkwsFacet mkwsTeam_', this.team.name(), '" data-mkws-facet="', facets[i], '">', '</div>');
-  }
-  this.node.html(acc.join(''));
-
+  var template = team.loadTemplate(this.config.template || "termlists");
+  this.node.html(template({
+    team: team.name(),
+    facets: this.config.facets
+  }));
   this.autosearch();
 });
 
 
-mkws.registerWidgetType('Facet', function() {
+mkws.registerWidgetType('facet', function() {
   var facetConfig = {
     xtargets: [ "Sources",  16, false ],
     subject:  [ "Subjects", 10, true ],
     author:   [ "Authors",  10, true ]
   }
-
   var that = this;
+  var team = this.team;
   var name = that.config.facet;
   var ref = facetConfig[name] || [ "Unknown", 10, true ];
   var caption = this.config['facet_caption_' + name] || ref[0];
@@ -36,47 +30,52 @@ mkws.registerWidgetType('Facet', function() {
   var pzIndex = ref[2] ? name : null;
 
   that.toString = function() {
-    return '[Widget ' + that.team.name() + ':' + that.type + '(' + name + ')]';
+    return '[Widget ' + team.name() + ':' + that.type + '(' + name + ')]';
   };
 
-  var t2 = that.team.loadTemplate('Facet-' + caption);
-  that.log("template for Facet-" + caption + " is " + !!t2);
-  if (!t2) {
-    that.log("no " + caption + "-specific template, falling back");
-    t2 = that.team.loadTemplate('Facet');
-  }
-  that.log("template for Facet is " + !!t2);
-
-  that.team.queue("termlists").subscribe(function(data) {
+  team.queue("termlists").subscribe(function(data) {
     data = data[name];
-    var t1 = that.team.loadTemplate('facetTitle-' + caption, mkws.M(caption))
-    var title = t1({ query: that.config.query });
-    var acc = [];
-    acc.push('<div class="mkwsFacetTitle">', title, '</div>');
-
-    var teamName = that.team.name();
+    var terms = [];
+    var teamName = team.name();
     for (var i = 0; i < data.length && i < max; i++) {
-      var fn, field;
-      // General case modifies the query; special case selects a target
-      if (pzIndex) {
-        fn = 'limitQuery'; field = pzIndex;
-      } else if (!that.team.targetFiltered(data[i].id)) {
-        fn = 'limitTarget'; field = data[i].id;
+      var linkdata = "";
+      var action = "";
+      if (!pzIndex) {
+        // Special case: target selection
+        linkdata += ('target_id='+data[i].id+' ');
+        if (!team.targetFiltered(data[i].id)) {
+          action = 'mkws.limitTarget(\'' + teamName + '\', this.getAttribute(\'target_id\'),this.firstChild.nodeValue)';
+        }
+      } else {
+        action = 'mkws.limitQuery(\'' + teamName + '\', \'' + pzIndex + '\', this.firstChild.nodeValue)';
       }
-
-      var s = t2({ 
-        team: teamName,
-        fn: fn,
-        field: field,
+      linkdata += 'onclick="' + action + ';return false;"';
+      terms.push({
         term: data[i].name,
+        field: data[i].id,
         count: data[i].freq,
-        query: that.config.query
-      });
-      acc.push('<div class="mkwsTerm">', s, '</div>');
+        linkdata: linkdata
+      }); 
     }
-
-    that.node.html(acc.join(''));
+    // configured template > facet specific template > default facet template
+    var template;
+    if (that.config.template) {
+      template = team.loadTemplate(that.config.template);
+    } else {
+      template = team.loadTemplate("facet-" + name);
+      if (template) {
+        that.log("Using facet-" + name + " template.")
+      } else {
+        that.log("No " + name + " specific template, using default.")
+        template = team.loadTemplate("facet");
+      }
+    }
+    that.node.html(template({
+      name: name,
+      caption: caption,
+      query: that.config.query,
+      terms: terms
+    }));
   });
-
   this.autosearch();
 });
index 9a3a7f7..4e428b1 100644 (file)
@@ -1,5 +1,5 @@
 // Factory function for widget objects.
-function widget($, team, type, node) {
+mkws.makeWidget = function($, team, type, node) {
   // Static register of attributes that do not contribute to config
   var ignoreAttrs = {
     id:1, 'class':1, style:1, name:1, action:1, type:1, size:1,
@@ -57,7 +57,7 @@ function widget($, team, type, node) {
     }
 
     var s = [];
-    s.push('<div class="mkws', type, ' mkwsTeam_', attrs._team, '"');
+    s.push('<div class="mkws', type, ' mkws-team-', attrs._team, '"');
     for (var name in attrs) {    
       if (name !== '_team')
         s.push(' ', name, '="', attrs[name], '"');
@@ -66,8 +66,7 @@ function widget($, team, type, node) {
     return s.join('');
   };
 
-  // ### why is this a member function? It's never called from outside this file.
-  that.expandValue = function(val) {
+  function expandValue(val) {
     if (val.match(/^!param!/)) {
       var param = val.replace(/^!param!/, '');
       val = mkws.getParameterByName(param);
@@ -153,7 +152,7 @@ function widget($, team, type, node) {
 
   for (var i = 0; i < node.attributes.length; i++) {
     var a = node.attributes[i];
-    var val = that.expandValue(a.value);
+    var val = expandValue(a.value);
     if (a.name === 'data-mkws-config') {
       // Treat as a JSON fragment configuring just this widget
       log(node + ": parsing config fragment '" + val + "'");
@@ -188,4 +187,4 @@ function widget($, team, type, node) {
   }
 
   return that;
-}
+};
diff --git a/src/templates/details.handlebars b/src/templates/details.handlebars
new file mode 100644 (file)
index 0000000..9e8184e
--- /dev/null
@@ -0,0 +1,61 @@
+{{!
+Full record display.
+
+Top level object is metadata from Service Proxy / Pazpar2
+}}
+<table>
+  <tr>
+    <th>{{mkws-translate "Title"}}</th>
+    <td>
+      {{md-title}}
+      {{#if md-title-remainder}}
+        ({{md-title-remainder}})
+      {{/if}}
+      {{#if md-title-responsibility}}
+        <i>{{md-title-responsibility}}</i>
+      {{/if}}
+    </td>
+  </tr>
+  {{#if md-date}}
+  <tr>
+    <th>{{mkws-translate "Date"}}</th>
+    <td>{{md-date}}</td>
+  </tr>
+  {{/if}}
+  {{#if md-author}}
+  <tr>
+    <th>{{mkws-translate "Author"}}</th>
+    <td>{{md-author}}</td>
+  </tr>
+  {{/if}}
+  {{#if md-electronic-url}}
+  <tr>
+    <th>{{mkws-translate "Links"}}</th>
+    <td>
+      {{#each md-electronic-url}}
+        <a href="{{this}}">Link{{mkws-index1}}</a>
+      {{/each}}
+    </td>
+  </tr>
+  {{/if}}
+  {{#mkws-if-any location having="md-subject"}}
+  <tr>
+    <th>{{mkws-translate "Subject"}}</th>
+    <td>
+      {{#mkws-first location having="md-subject"}}
+        {{#if md-subject}}
+          {{#mkws-commaList md-subject}}
+            {{this}}{{/mkws-commaList}}
+        {{/if}}
+      {{/mkws-first}}
+    </td>
+  </tr>
+  {{/mkws-if-any}}
+  <tr>
+    <th>{{mkws-translate "Locations"}}</th>
+    <td>
+      {{#mkws-commaList location}}
+        {{mkws-attr "@name"}}{{/mkws-commaList}}
+    </td>
+  </tr>
+</table>
diff --git a/src/templates/done.handlebars b/src/templates/done.handlebars
new file mode 100644 (file)
index 0000000..59a0b4f
--- /dev/null
@@ -0,0 +1,7 @@
+{{!
+Displayed on search completion
+
+count - number of results found
+}}
+{{{mkws-translate "Search complete: found"}}} {{count}} {{{mkws-translate "records"}}}
+
diff --git a/src/templates/facet.handlebars b/src/templates/facet.handlebars
new file mode 100644 (file)
index 0000000..7a4eedf
--- /dev/null
@@ -0,0 +1,18 @@
+{{!
+A facet in the search.
+
+name - facet identifier, typically English and lowercase
+caption - caption for this facet
+terms:
+  term - term name
+  count - count of items matching in the current search for this team
+  linkdata - attributes to add to the term element including an onclick handler
+  field - for the xtargets facet ONLY, the opaque identifier of the target
+}}
+
+<div class="mkws-facet-title mkwsFacetTitle">{{caption}}</div>
+{{#each terms}}
+  <div class="mkws-term mkwsTerm">
+    <a href="#" {{{linkdata}}}>{{term}}</a> <span>{{count}}</span>
+  </div>
+{{/each}}
diff --git a/src/templates/images.handlebars b/src/templates/images.handlebars
new file mode 100644 (file)
index 0000000..f74f174
--- /dev/null
@@ -0,0 +1,21 @@
+{{!
+Records presented as images.
+
+The non-metadata keys enable an optional link to display an AJAX popup that
+fetches additional record detail.
+
+hits:
+  containerClass - partial class attribute for element containing a record
+  detailLinkId - id for the element triggering detail display
+  detailClick - a click event handler for details
+  renderedDetails - active record details rendered from the Record template
+  md-* - metadata fields passed through from backend
+}}
+{{#each hits}}
+  <a href="#" id="{{detailLinkId}}" onclick="{{detailClick}}">
+    {{#mkws-first md-thumburl}}
+      <img src="{{this}}" alt="{{../md-title}}"/>
+    {{/mkws-first}}
+    <br/>
+  </a>
+{{/each}}
diff --git a/src/templates/lang.handlebars b/src/templates/lang.handlebars
new file mode 100644 (file)
index 0000000..26ee6da
--- /dev/null
@@ -0,0 +1,19 @@
+{{!
+Language selection widget
+
+languages
+  code - two character language identifier
+  selected - exists for the current language
+  url - url to switch to this language
+}}
+{{#each languages}}
+  {{~#if selected~}}
+    <span>{{code}}</span>
+  {{~else~}}
+    <a href="{{{url}}}">{{code}}</a>
+  {{~/if~}}
+  {{#unless last}}
+    |
+  {{/unless}}
+{{/each}}
+
diff --git a/src/templates/navi.handlebars b/src/templates/navi.handlebars
new file mode 100644 (file)
index 0000000..5139fd7
--- /dev/null
@@ -0,0 +1,13 @@
+{{!
+Facet breadcrumbs -- filters on the current search
+
+filters
+  facet - name of facet being limited
+  value - limit to this value
+  click - handler script to remove limit
+}}
+{{#each filters}}
+  {{{mkws-translate facet}}}: <a class="mkws-removable mkwsRemovable" href="#" onclick="{{{click}}}">{{value}}</a>
+  {{#unless @last}}|{{/unless}}
+{{/each}}
+
diff --git a/src/templates/pager.handlebars b/src/templates/pager.handlebars
new file mode 100644 (file)
index 0000000..55768e8
--- /dev/null
@@ -0,0 +1,46 @@
+{{!
+Pager
+
+nextClick - handler script for "next" button, only available if there is a next page
+prevClick - handler script for "previous" button if there is a previous page
+moreNext - indicates there are more pages following those displayed
+morePrev - indicates there are more pages preceding
+first - first record displayed
+last - last record displayed
+count - number of records available
+found - number of records found
+pages:
+  number - page number
+  click - script to go to this page unless it is the current one
+}}
+<div style="float: right">
+  {{mkws-translate "Displaying"}}:
+  {{first}} {{mkws-translate "to"}} {{last}}
+  {{mkws-translate "of"}} {{count}} ({{{mkws-translate "found"}}}: {{found}})
+</div>
+
+<div style="float: clear">
+  {{#if prevClick}}
+    <a href="#" class="mkws-prev mkwsPrev" onclick="{{prevClick}}">&#60;&#60; {{{mkws-translate "Prev"}}}</a> |
+  {{else}}
+    <span class="mkws-prev mkwsPrev">&#60;&#60; {{{mkws-translate "Prev"}}}</span> |
+  {{/if}}
+
+  {{#if morePrev}}...{{/if}}
+
+  {{#each pages}}
+    {{#if click}}
+      <a href="#" onclick="{{click}}">{{number}}</a>
+    {{else}}
+      <span class="mkws-current-page mkwsCurrentPage">{{number}}</span>
+    {{/if}}
+  {{/each}}
+
+  {{#if moreNext}}...{{/if}}
+
+  {{#if nextClick}}
+    | <a href="#" class="mkws-next mkwsNext" onclick="{{nextClick}}">{{{mkws-translate "Next"}}} &#62;&#62;</a>
+  {{else}}
+    | <span class="mkws-next mkwsNext">{{{mkws-translate "Next"}}} &#62;&#62;</span>
+  {{/if}}
+</div>
diff --git a/src/templates/progress.handlebars b/src/templates/progress.handlebars
new file mode 100644 (file)
index 0000000..603c5ca
--- /dev/null
@@ -0,0 +1,11 @@
+{{!
+Progress
+
+done - number of targets complete
+waiting - number of targets waiting
+}}
+<span class="mkws-done mkws-done mkwsDone">{{#mkws-repeat done}}&#x2588;{{/mkws-repeat}}</span>
+{{~#if waiting~}}
+<span class="mkws-waiting mkws-waiting mkwsWaiting">{{#mkws-repeat waiting}}&#x2588;{{/mkws-repeat}}</span>
+{{~/if~}}
+
diff --git a/src/templates/ranking.handlebars b/src/templates/ranking.handlebars
new file mode 100644 (file)
index 0000000..890e29a
--- /dev/null
@@ -0,0 +1,42 @@
+{{!
+Ranking -- widget to select sort ordering and number of records to display
+
+team - team for this widget
+showSort - set if sort control is to be displayed
+showPerPage - set if per-page control is to be displayed
+sort
+  key - machine readable value for this sort option
+  label - text to display for this sort option
+  selected - exists if this sort is selected
+perPage
+  perPage - a number of records per page that can be selected
+  selected - exists if this number is the current selection
+}}
+<form>
+  {{~#if showSort~}}
+    {{{mkws-translate "Sort by"}}}
+    <select class="mkws-sort mkwsSort mkws-team-{{team}}">
+      {{#each sort}}
+        {{#if selected}}
+          <option value="{{{key}}}" selected="selected">{{{mkws-translate label}}}</option>
+        {{else}}
+          <option value="{{key}}">{{{mkws-translate label}}}</option>
+        {{/if}}
+      {{/each}}  
+    </select>
+  {{~/if~}}
+  {{~#if showPerPage}}
+    {{{mkws-translate "and show"}}}
+    <select class="mkws-perpage mkwsPerpage mkws-team-{{team}}">
+      {{#each perPage}}
+        {{#if selected}}
+          <option value="{{perPage}}" selected="selected">{{perPage}}</option>
+        {{else}}
+          <option value="{{perPage}}">{{perPage}}</option>
+        {{/if}}
+      {{/each}}  
+    </select>
+    {{{mkws-translate "per page"}}}
+  {{~/if~}}
+</form>
+
diff --git a/src/templates/records.handlebars b/src/templates/records.handlebars
new file mode 100644 (file)
index 0000000..07e6801
--- /dev/null
@@ -0,0 +1,18 @@
+{{!
+Records from a search.
+
+The non-metadata keys enable an optional link to display an AJAX popup that
+fetches additional record detail.
+
+hits:
+  containerClass - partial class attribute for element containing a record
+  detailLinkId - id for the element triggering detail display
+  detailClick - a click event handler for details
+  renderedDetails - active record details rendered from the details template
+  md-* - metadata fields passed through from backend
+}}
+{{#each hits}}
+  <div class="{{containerClass}}">
+    {{>summary}}
+  </div>
+{{/each}}
diff --git a/src/templates/reference.handlebars b/src/templates/reference.handlebars
new file mode 100644 (file)
index 0000000..cedad80
--- /dev/null
@@ -0,0 +1,17 @@
+{{!
+Paragraphs and images from a reference source.
+
+sentences - number of sentences to include
+paragraphs - number of paragraphs to include
+md-* - metadata fields passed through from backend
+}}
+<img src="{{md-thumburl}}" alt="{{md-title}}">
+<h1><a href="{{md-electronic-url}}">{{md-title}}</a></h1>
+{{#if md-title-remainder}}
+<b>{{md-title-remainder}}</b>
+{{/if}}
+{{#if md-title-responsibility}}
+<i>{{md-title-responsibility}}</i>
+{{/if}}
+{{{mkws-paragraphs md-description paragraphs sentences}}}
+<p class="mkws-credit mkwsCredit">Wikipedia</p>
diff --git a/src/templates/results.handlebars b/src/templates/results.handlebars
new file mode 100644 (file)
index 0000000..fcda1bc
--- /dev/null
@@ -0,0 +1,24 @@
+{{!
+Results -- compound widget to display search results
+
+team - team for this widget
+}}
+<table width="100%" border="0" cellpadding="6" cellspacing="0">
+  <tr>
+    <td class="mkws-termlists-container-wide mkws-team-{{team}}" width="250" valign="top">
+      <div class="mkws-termlists mkwsTermlists mkws-team-{{team}}"></div>
+    </td>
+    <td class="mkws-motd-container mkwsMOTDContainer mkws-team-{{team}}" valign="top">
+      <div class="mkws-ranking mkwsRanking mkws-team-{{team}}"></div>
+      <div class="mkws-pager mkwsPager mkws-team-{{team}}"></div>
+      <div class="mkws-navi mkwsNavi mkws-team-{{team}}"></div>
+      <div class="mkws-records mkwsRecords mkws-team-{{team}}"></div>
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2">
+      <div class="mkws-termlists-container-narrow mkws-team-{{team}}"></div>
+    </td>
+  </tr>
+</table>
+
diff --git a/src/templates/search.handlebars b/src/templates/search.handlebars
new file mode 100644 (file)
index 0000000..82cbd15
--- /dev/null
@@ -0,0 +1,11 @@
+{{!
+Search form
+
+team - MKWS team
+queryWidth - configured width for search box
+}}
+<form name="mkws-search-form" class="mkws-search-form mkws-team-{{team}}" action="">
+  <input class="mkws-query mkws-query mkwsQuery mkws-team-{{team}}" type="text" size="{{queryWidth}}">
+  <input class="mkws-button mkws-button mkwsButton mkws-team-{{team}}" type="submit" value="{{{mkws-translate "Search"}}}">
+</form>
+
diff --git a/src/templates/stat.handlebars b/src/templates/stat.handlebars
new file mode 100644 (file)
index 0000000..340c1f8
--- /dev/null
@@ -0,0 +1,9 @@
+{{!
+Search statistics
+
+activeclients - number of targets currently searching
+clients - total targets for this search
+records - number of records returned and available
+hits - number of hits across all targets
+}}
+ -- <span class="mkws-client-count mkwsClientCount">{{{mkws-translate "Active clients"}}} : {{activeclients}}/{{clients}}</span> -- {{{mkws-translate "Retrieved records"}}} : {{records}}/{{hits}}
diff --git a/src/templates/summary.handlebars b/src/templates/summary.handlebars
new file mode 100644 (file)
index 0000000..aa2ed10
--- /dev/null
@@ -0,0 +1,24 @@
+{{!
+Brief record from a search.
+
+The non-metadata keys enable an optional link to display an AJAX popup that
+fetches additional record detail.
+
+containerClass - partial class attribute for element containing a record
+detailLinkId - id for the element triggering detail display
+detailClick - a click event handler for details
+renderedDetails - active record details rendered from the details template
+md-* - metadata fields passed through from backend
+}}
+<a href="#" id="{{detailLinkId}}" onclick="{{detailClick}}">
+  <b>{{md-title}}</b>
+</a>
+{{#if md-title-remainder}}
+  <span>{{md-title-remainder}}</span>
+{{/if}}
+{{#if md-title-responsibility}}
+  <span><i>{{md-title-responsibility}}</i></span>
+{{/if}}
+{{#if renderedDetails}}
+  {{{renderedDetails}}}
+{{/if}}
diff --git a/src/templates/switch.handlebars b/src/templates/switch.handlebars
new file mode 100644 (file)
index 0000000..2b8e29c
--- /dev/null
@@ -0,0 +1,9 @@
+{{!
+Switch between record and target view
+
+recordClick - handler to switch to record view
+targetClick - handler to switch to target view
+}}
+<a href="#" onclick="{{{recordClick}}}">{{{mkws-translate "Records"}}}</a>
+<span>|</span>
+<a href="#" onclick="{{{targetClick}}}">{{{mkws-translate "Targets"}}}</a>
diff --git a/src/templates/targets.handlebars b/src/templates/targets.handlebars
new file mode 100644 (file)
index 0000000..132f87f
--- /dev/null
@@ -0,0 +1,33 @@
+{{!
+Target detail
+
+data:
+  id - target id, an opaque identifier
+  hits - number of hits for this target, or "Error" if an error has occurred
+  diagnostic - diagnostic code returned by target, if any. May be numeric or human-readable
+  records - number of record retrieved from target
+  state - target state (Client_Idle, Client_Working, Client_Disconnected or Client_Error)
+}}
+<table>
+  <thead>
+    <tr>
+      <td>{{{mkws-translate "Target ID"}}}</td>
+      <td>{{{mkws-translate "Hits"}}}</td>
+      <td>{{{mkws-translate "Diags"}}}</td>
+      <td>{{{mkws-translate "Records"}}}</td>
+      <td>{{{mkws-translate "State"}}}</td>
+      </td>
+    </tr>
+  </thead>
+  <tbody>
+  {{#each data}}
+    <tr>
+      <td>{{{id}}}</td>
+      <td>{{hits}}</td>
+      <td>{{diagnostic}}</td>
+      <td>{{records}}</td>
+      <td>{{state}}</td>
+    </tr>
+  {{/each}}
+  </tbody>
+</table>
diff --git a/src/templates/termlists.handlebars b/src/templates/termlists.handlebars
new file mode 100644 (file)
index 0000000..66caa83
--- /dev/null
@@ -0,0 +1,11 @@
+{{!
+Termlists, a container of all configured facets.
+
+team - the current team
+facets - array of facet names
+}}
+
+<div class="mkws-termlists-title mkwsTermlistsTitle">Termlists</div>
+{{#each facets}}
+  <div class="mkws-facet mkwsFacet mkws-team-{{../team}}" data-mkws-facet="{{this}}"></div>
+{{/each}}
index dd1c75a..221cf5c 100644 (file)
@@ -1,7 +1,8 @@
+libexec
+logs/error-*\.log
+logs/jasmine-dev-*\.conf
+logs/mkws-jasmine-*\.log
 node_modules
-logs/error_log
-logs/jasmine-dev
-logs/mkws-jasmine-access.log
-logs/mkws-jasmine-error.log
-logs/mkws-jasmine-rewrite.log
-logs/mkws-jasmine.pid
+widgets/images/http---*
+widgets/images/index.html
+images/screenshot.png
index 89c0c02..1b986b4 100644 (file)
@@ -1,14 +1,14 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
 
 # For running on Mike's local install of node.js
 MIKE = PATH=$$PATH:/usr/local/lib/node-v0.10.24-linux-x64/bin
 
 APACHE_PORT:= $(shell echo $${APACHE_PORT-4040})
 
-#PHANTOMJS_URL=https://mkws-dev.indexdata.com/jasmine-popup.html       
+#PHANTOMJS_URL=https://mkws-dev.indexdata.com/jasmine-popup.html
 PHANTOMJS_PATH=jasmine-local-popup.html
 PHANTOMJS_URL=http://localhost:${APACHE_PORT}/${PHANTOMJS_PATH}
-PHANTOMJS_TIMEOUT=18
+PHANTOMJS_TIMEOUT=30
 
 NPM_INSTALL_FLAGS=-q
 JASMINE_NODE=  ./node_modules/jasmine-node/bin/jasmine-node
@@ -18,16 +18,17 @@ SCREENSHOT_WIDTH=   360 480 640 768 1024 1200 1440 2048
 PERL_SCRIPTS=  bin/bomb.pl
 TMP_DIR=       ./logs
 APACHE_HTTPD:= $(shell env PATH=$$PATH:/usr/sbin which apache2 httpd false | head -1 )
+APACHE_PORT ?= 4040
 
 all: check
 
 clean:
-       rm -f mkws-error.png mkws-error.html 
+       rm -f mkws-error.png mkws-error.html
        rm -f images/*.png
+       ${MAKE} -C./widgets $@
 
-distclean: clean clean-tmp clean-error
+distclean: apache-stop clean clean-tmp clean-error
        rm -rf node_modules
-       rm -f ${TMP_DIR}/jasmine-dev
        rm -f libexec
 
 clean-error:
@@ -39,28 +40,34 @@ clean-tmp:
        touch ${TMP_DIR}/.gitkeep
 
 mkws-complete-syntax-check:
-       ${MAKE} -C../tools/htdocs mkws-complete.min.js
+       ${MAKE} -C../src ../tools/htdocs/mkws-complete.min.js
 
-check: mkws-complete-syntax-check
-       @if [ ! -e node_modules ]; then echo "please run first: make node-modules"; exit 1; fi 
+check check-js: node-modules mkws-complete-syntax-check
        ${JASMINE_NODE} --noColor --captureExceptions --forceexit ./spec
 
+check-node-installation:
+       @if [ ! -e node_modules ]; then \
+           echo "==> please run first: make node-modules"; \
+           echo ""; \
+           exit 1; \
+       fi
+
 test: check
 
 terse:
        $(MIKE) jasmine-node --noColor --captureExceptions --forceexit spec
 
-phantomjs p: apache-stop apache-start _phantomjs 
+phantomjs p: check-js apache-stop apache-start _phantomjs
        ${MAKE} apache-stop
 
 _phantomjs:
        perl ./bin/bomb.pl --timeout="${PHANTOMJS_TIMEOUT}.5" ${PHANTOMJS} phantom/run-jasmine.js ${PHANTOMJS_URL} ${PHANTOMJS_TIMEOUT}
 
 phantomjs-all p-all:
-       ${MAKE} phantomjs PHANTOMJS_PATH=jasmine.html
-       ${MAKE} phantomjs PHANTOMJS_PATH=jasmine-cors-popup.html
        ${MAKE} phantomjs PHANTOMJS_PATH=jasmine-local-popup.html
        ${MAKE} phantomjs PHANTOMJS_PATH=jasmine-popup.html
+       ${MAKE} phantomjs PHANTOMJS_PATH=jasmine-cors-popup.html
+       ${MAKE} phantomjs PHANTOMJS_PATH=jasmine.html
 
 mike-test:
        $(MAKE) _phantomjs PHANTOMJS_URL=http://x.example.indexdata.com/jasmine-popup.html
@@ -80,6 +87,9 @@ screenshot-indexdata:
        done; wait
        ls -l ${IMAGES}
 
+screenshots:
+       ${MAKE} -C ./widgets $@
+
 jsbeautifier jsb indent:
        for i in package.json ./spec*/*.js ./js/*.js ./phantom/*.js; do \
          jsbeautifier -j $$i > $@.tmp && mv -f $@.tmp $$i; \
@@ -95,21 +105,23 @@ node_modules node-modules:
 
 apache-start:
        bin/apache-template-update
-       ${APACHE_HTTPD} -f `pwd`/${TMP_DIR}/jasmine-dev
+       ${APACHE_HTTPD} -f `pwd`/${TMP_DIR}/jasmine-dev-${APACHE_PORT}.conf
 
+APACHE_PID_FILE=${TMP_DIR}/mkws-jasmine-${APACHE_PORT}.pid
 apache-stop:
-       @-if [ -e ${TMP_DIR}/mkws-jasmine.pid ]; then \
-          kill `cat ${TMP_DIR}/mkws-jasmine.pid`; \
+       @-if [ -e ${APACHE_PID_FILE} ]; then \
+          kill `cat ${APACHE_PID_FILE}`; \
        else \
-          killall apache2 2> /dev/null; \
+          killall ${APACHE_HTTPD} 2> /dev/null; \
        fi
-       @sleep 0.3
-       rm -f ${TMP_DIR}/mkws-jasmine.pid
+       @sleep 0.6
+       rm -f ${APACHE_PID_FILE}
 
 help:
        @echo "make [ all | check | clean | distclean ]"
        @echo "     [ phantomjs | phantomjs-all ]"
        @echo "     [ jsbeautifier | perltidy | screenshot ]"
+       @echo "     [ screenshots ]"
        @echo "     [ node-modules ]"
        @echo "     [ apache-stop apache-start ]"
        @echo ""
@@ -119,6 +131,6 @@ help:
        @echo "DEBUG=0 APACHE_PORT=5050 make -s phantomjs PHANTOMJS_TIMEOUT=12 PHANTOMJS_PATH=${PHANTOMJS_PATH}"
        @echo "DEBUG=2 make phantomjs PHANTOMJS_TIMEOUT=12 PHANTOMJS_URL=${PHANTOMJS_URL}"
        @echo ""
+       @echo "make APACHE_PORT=5050 apache-start"
        @echo "make phantomjs-all"
        @echo ""
-
index fb6bfa5..227a35a 100644 (file)
@@ -1,15 +1,39 @@
 Jasmine / jasmine-node test frame works
----------------------------------------
+=============================================
 
 This directory contains the MasterKey Widget Set (MKWS) Test framework.
 
-To install (some) prerequisites, run:
 
+Installation
+-------------------------------------
+1. install node.js, see http://nodejs.org/
+(and apache2 if you have not already)
+
+# debian7
 $ sudo apt-get install npm
-$ sudo npm install -g
+$ sudo apt-get install apache2
+
+# centos6
+$ sudo yum install npm
+$ sudo yum install httpd
+
+
+The nodejs modules are configured in ./package.json
+You can install them manually with
+$ make node-modules
+
+if you want. The top level makefile in ./mkws/Makefile takes care to
+checkout and update the modules automatically.
+
+
+Testing
+---------------------------------------
+
 
 To run the tests, run:
 
+1. basic javscript tests
+
 $ make check
 jasmine-node ./spec
 .......................................
@@ -18,22 +42,30 @@ Finished in 2.024 seconds
 39 tests, 194 assertions, 0 failures, 0 skipped
 
 
+2. Testing the Widgets in a headless browser with Jasmine
+
 $ make phantomjs
 [ headless jasmine test with console.log() messages
 
-$ DEBUG=1 make phantomjs PHANTOM_URL=https://mkws-dev.indexdata.com/jasmine-popup.html
+$ DEBUG=1 make phantomjs PHANTOM_URL=https://example.indexdata.com/jasmine-popup.html
 [ less debug noise ]
 
+
 To get a basic help, run:
 $ make help
 
 
 File system hierarchy
 --------------------------------------
-./spec         contains *spec.js files
+./spec         contains *spec.js files for phantomjs
+./spec-dev     development *spec.js files
 ./js           jasmine runtime JS lib
 ./phantom      scripts for phantomjs tests
-
+./bin          helper scripts
+./etc          configuration files
+./logs         apache access and error log files
+./widgets      screenshots for MKWS widgets
+./images       screenshots for testing
 
 Documentation
 ---------------------------------------
@@ -42,12 +74,6 @@ https://github.com/pivotal/jasmine
 http://phantomjs.org/
 
 
-Installation
--------------------------------------
-1. install node.js, see http://nodejs.org/
-2. install node modules with npm: 
-$ make node-modules
-
 --
-Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
-Feb 2014, Wolfram
+Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
+Oct 2014, Wolfram
index 6c90341..db0c6e5 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (c) 2014-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2014-2014 Index Data ApS. http://indexdata.com
 # Wolfram Schneider
 #
 # generate temp config file for testing
@@ -9,11 +9,12 @@ export APACHE_SERVER_ROOT=$(pwd)
 export APACHE_RUN_USER=$(whoami)
 export APACHE_RUN_GROUP=$(groups | awk '{ print $1 }')
 
-export APACHE_LOG_DIR=$APACHE_SERVER_ROOT/logs
-export APACHE_PID_FILE=$APACHE_LOG_DIR/mkws-jasmine.pid
-export APACHE_LOCK_FILE=$APACHE_LOG_DIR/accept.lock
 : ${APACHE_PORT=4040}; export APACHE_PORT
 
+export APACHE_LOG_DIR=$APACHE_SERVER_ROOT/logs
+export APACHE_PID_FILE=$APACHE_LOG_DIR/mkws-jasmine-${APACHE_PORT}.pid
+export APACHE_LOCK_FILE=$APACHE_LOG_DIR/accept-${APACHE_PORT}.lock
+
 export MKWS_ROOT=$(pwd)/..
 
 MKWS_OS=debian
@@ -47,7 +48,7 @@ else
     APACHE_MODULES="$MKWS_ROOT/tools/apache2/jasmine-dev.apache-modules.$MKWS_OS.conf"
 fi
 
-: ${MKWS_APACHE_FILE="$APACHE_LOG_DIR/jasmine-dev"}
+: ${MKWS_APACHE_FILE="$APACHE_LOG_DIR/jasmine-dev-${APACHE_PORT}.conf"}
 export APACHE_MODULES
 
 perl -npe 's,\${(.*?)},$ENV{$1},g; ' $MKWS_APACHE_TEMPLATE > $MKWS_APACHE_FILE.tmp
index a79be99..0f434d0 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# Copyright (c) 2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2014 Index Data ApS. http://indexdata.com
 #
 # bomb.pl - wrapper to stop a process after N seconds
 #
@@ -45,7 +45,7 @@ eval {
     BSD::Resource::setrlimit("RLIMIT_CPU", $timeout, 2*$timeout) or die "Cannot set CPU limit: $!\n";
 };
 if ($@) {
-    warn "Please install the package BSD::Resource!\n\n$@\n";
+    warn "WARNING: things would go more nicely with the BSD::Resource package\n";
 }
 
 
diff --git a/test/bin/yui-compressor b/test/bin/yui-compressor
new file mode 100755 (executable)
index 0000000..c55de67
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/sh
+# 
+# yui-compressor - dummy wrapper for missing java tool yui-compressor
+
+cat <<EOF >&2
+==>  Warning: the real program yui-compressor does not exists <==
+     will use cat(1) instead! 
+EOF
+
+cat "$@"
+
index 5450176..c0aca1c 100644 (file)
         "jQuery": "*",
         "xmlhttprequest": "*",
         "jsdom": "<= 0.11.1",
+        "cssstyle": "<= 0.2.14",
         "request": "*",
         "jasmine-reporters": "<= 0.4.1",
         "jasmine-node": "*",
-        "phantomjs": "*"
+        "phantomjs": "*",
+        "handlebars": "= 2.0.0"
     },
     "repository": {
         "type": "git",
index 396417b..ef0577a 100644 (file)
@@ -136,7 +136,7 @@ page.open(url, function (status) {
                 html: $("html").html(),
                 duration: $(".duration").text(),
                 error_msg: error_msg,
-                failed: list.length,
+                failed: (list.length > 0 || !passing),
                 passing: passing
             };
         })
index ac4de3b..5bec386 100644 (file)
@@ -3,12 +3,25 @@ var page = require('webpage').create(),
 
 var url = system.args[1] || 'http://www.indexdata.com/';
 var file_png = system.args[2] || 'indexdata.png';
+var timeout = system.args[5] ? system.args[5] : 0.2;
 
-if (system.args.length === 1) {
-    console.log('Usage: screenshot.js <some URL> <file.png>');
+function usage (message) {
+    if (message) {
+        console.log(message + "\n");
+    }
+    console.log('Usage: screenshot.js <some URL> <file.png> <width px> <height px> <timeout sec>');
     phantom.exit();
 }
 
+if (system.args.length === 1) {
+    usage();
+}
+
+if (!file_png.match(/\.png$/)) {
+    usage("File name has no .png extension: '" + file_png + "'");
+}
+
+
 // page.zoomFactor = 1.0;
 page.viewportSize = {
     width: system.args[3] ? system.args[3] : 1200,
@@ -25,5 +38,7 @@ page.open(url, function () {
     setTimeout(function () {
         var ret = page.render(file_png);
         phantom.exit();
-    }, 200);
+    }, timeout * 1000);
 });
+
+// EOF
index dc09ceb..6de372d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
  *
  * async check
  *
index 1f473c9..152f719 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
  *
  * jQuery test
  *
index c83809a..273f591 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
  *
  * jQuery test with DOM/windows object
  *
index b6852a9..980b262 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
  *
  * check mkws_config = {} object in browser
  *
index 2e49726..91543c2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
  *
  * perform papzpar2 / pz2.js search & retrieve request in the browser
  *
@@ -61,9 +61,9 @@ function init_jasmine_config() {
 function get_hit_counter() {
     var $ = mkws.$;
     // not yet here
-    if ($(".mkwsPager").length == 0) return -1;
+    if ($(".mkws-pager").length == 0) return -1;
 
-    var found = $(".mkwsPager").text();
+    var found = $(".mkws-pager").text();
     var re = /\([A-Za-z]+:\s+([0-9]+)\)/;
     re.exec(found);
     var hits = -1;
@@ -97,19 +97,19 @@ xdescribe("Check MOTD before search", function () {
 
     // Check that the MOTD has been moved into its container, and
     // is visible before the search.
-    // the mkwsMOTD div was originally inside a testMOTD div, which should
+    // the mkws-motd div was originally inside a testMOTD div, which should
     // now be empty
     // Note that the testMOTD is a regular div, and uses #testMOTD,
     // since the automagic class-making does not apply to it.
     it("MOTD is hidden", function () {
-        expect($(".mkwsMOTD").length).toBe(1);
+        expect($(".mkws-motd").length).toBe(1);
         expect($("#testMOTD").length).toBe(1);
         expect($("#testMOTD").text()).toMatch("^ *$");
     });
 
-    it("mkwsMOTDContainer has received the text", function () {
-        expect($(".mkwsMOTDContainer").length).toBe(1);
-        expect($(".mkwsMOTDContainer").text()).toMatch(/MOTD/);
+    it("mkws-motd-container has received the text", function () {
+        expect($(".mkws-motd-container").length).toBe(1);
+        expect($(".mkws-motd-container").text()).toMatch(/MOTD/);
     });
 });
 
@@ -121,18 +121,18 @@ describe("Check pazpar2 search", function () {
     });
 
     it("validate HTML id's", function () {
-        expect($("input.mkwsQuery").length).toBe(1);
-        expect($("input.mkwsButton").length).toBe(1);
+        expect($("input.mkws-query").length).toBe(1);
+        expect($("input.mkws-button").length).toBe(1);
 
-        expect($(".mkwsNext").length).not.toBe(1);
-        expect($(".mkwsPrev").length).not.toBe(1);
+        expect($(".mkws-next").length).not.toBe(1);
+        expect($(".mkws-prev").length).not.toBe(1);
     });
 
     it("run search query", function () {
         var search_query = jasmine_config.search_query; // short hit counter with some paging
-        $("input.mkwsQuery").val(search_query);
+        $("input.mkws-query").val(search_query);
         debug("set search query: " + search_query)
-        expect($("input.mkwsQuery").val()).toMatch("^" + search_query + "$");
+        expect($("input.mkws-query").val()).toMatch("^" + search_query + "$");
 
         if (mkws.config.use_service_proxy) {
             // wait for service proxy auth
@@ -145,7 +145,7 @@ describe("Check pazpar2 search", function () {
 
         runs(function () {
             debug("Click on submit button");
-            $("input.mkwsButton").trigger("click");
+            $("input.mkws-button").trigger("click");
         })
     });
 });
@@ -158,10 +158,10 @@ describe("Check MOTD after search", function () {
             return;
         }
 
-        expect($(".mkwsMOTD").length).toBe(1);
-        expect($(".mkwsMOTD").is(":hidden")).toBe(true);
-        debug("motd t=" + $(".mkwsMOTD").text());
-        debug("motd v=" + $(".mkwsMOTD").is(":visible"));
+        expect($(".mkws-motd").length).toBe(1);
+        expect($(".mkws-motd").is(":hidden")).toBe(true);
+        debug("motd t=" + $(".mkws-motd").text());
+        debug("motd v=" + $(".mkws-motd").is(":visible"));
     });
 });
 
@@ -176,7 +176,7 @@ describe("Check pazpar2 navigation", function () {
 
     // Asynchronous part
     it("check running search next/prev", function () {
-        expect($(".mkwsPager").length).toBe(1);
+        expect($(".mkws-pager").length).toBe(1);
 
         function my_click(id, time) {
             setTimeout(function () {
@@ -186,22 +186,22 @@ describe("Check pazpar2 navigation", function () {
         }
 
         waitsFor(function () {
-            return $("div.mkwsPager div:nth-child(2) a").length >= 2 ? true : false;
+            return $("div.mkws-pager div:nth-child(2) a").length >= 2 ? true : false;
         }, "Expect next link 2", 10 * jasmine_config.second);
 
         runs(function () {
             // click next/prev after N seconds
-            my_click(".mkwsNext", 0);
+            my_click(".mkws-next", 0);
         });
 
         waitsFor(function () {
-            return $("div.mkwsPager div:nth-child(2) a").length >= 3 ? true : false;
+            return $("div.mkws-pager div:nth-child(2) a").length >= 3 ? true : false;
         }, "Expect next link 3", 5 * jasmine_config.second);
 
         runs(function () {
             // click next/prev after N seconds
-            my_click(".mkwsNext", 0);
-            my_click(".mkwsPrev", 0.2);
+            my_click(".mkws-next", 0);
+            my_click(".mkws-prev", 0.2);
         });
     });
 });
@@ -221,7 +221,7 @@ describe("Check pazpar2 hit counter", function () {
 
         runs(function () {
             debug("mkws pager found records: '" + hits + "'");
-            expect($(".mkwsPager").length).toBe(1);
+            expect($(".mkws-pager").length).toBe(1);
             expect(hits).toBeGreaterThan(expected_hits);
         });
     });
@@ -231,33 +231,33 @@ describe("Check Termlist", function () {
     var $ = mkws.$;
 
     it("found Termlist", function () {
-        var termlist = $("div.mkwsTermlists");
+        var termlist = $("div.mkws-termlists");
         debug("Termlist success: " + termlist.length);
         expect(termlist.length).toBe(1);
 
         waitsFor(function () {
-            return $("div.mkwsFacet[data-mkws-facet='xtargets']").length == 1 ? true : false;
+            return $("div.mkws-facet[data-mkws-facet='xtargets']").length == 1 ? true : false;
         }, "check for facet sources", 4 * jasmine_config.second);
 
         // everything displayed?
         runs(function () {
-            var sources = $("div.mkwsFacet[data-mkws-facet='xtargets']");
+            var sources = $("div.mkws-facet[data-mkws-facet='xtargets']");
             debug("Termlist sources success: " + sources.length);
             expect(sources.length).toBe(1);
 
-            var subjects = $("div.mkwsFacet[data-mkws-facet='subject']");
+            var subjects = $("div.mkws-facet[data-mkws-facet='subject']");
             expect(subjects.length).toBe(1);
 
-            var authors = $("div.mkwsFacet[data-mkws-facet='author']");
+            var authors = $("div.mkws-facet[data-mkws-facet='author']");
             expect(authors.length).toBe(1);
         });
 
         waitsFor(function () {
-            return $("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm").length >= 2 ? true : false;
-        }, "At least one author link displayed", 4 * jasmine_config.second);
+            return $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term").length >= 2 ? true : false;
+        }, "At least two author link displayed", 4 * jasmine_config.second);
 
         runs(function () {
-            expect($("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm").length).toBeGreaterThan(1);
+            expect($("div.mkws-facet[data-mkws-facet='author'] div.mkws-term").length).toBeGreaterThan(1);
         });
     });
 });
@@ -279,7 +279,7 @@ describe("Check Author Facets", function () {
         // do not click on author names without a comma, e.g.: "Joe Barbara"
         // because searching on such authors won't find anything.
         runs(function () {
-            var terms = $("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm a");
+            var terms = $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term a");
             for (var i = 0; i < terms.length; i++) {
                 var term = $(terms[i]).text();
                 if (term.match(/[0-9].+[0-9]/i) || !term.match(/,/)) {
@@ -289,13 +289,13 @@ describe("Check Author Facets", function () {
                     break;
                 }
             }
-            if ($("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").text().length == 0) {
+            if ($("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").text().length == 0) {
                 debug("No good authors found. Not clicking on the bad ones");
                 return;
             }
 
-            debug("Clicking on author (" + author_number + ") " + $("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").text());
-            $("div.mkwsFacet[data-mkws-facet='author'] div.mkwsTerm:nth-child(" + author_number + ") a").trigger("click");
+            debug("Clicking on author (" + author_number + ") " + $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").text());
+            $("div.mkws-facet[data-mkws-facet='author'] div.mkws-term:nth-child(" + author_number + ") a").trigger("click");
         });
 
         waitsFor(function () {
@@ -316,14 +316,14 @@ describe("Check active clients author", function () {
 
     it("check for active clients after limited author search", function () {
         waitsFor(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
+            var clients = $("div.mkws-stat span.mkws-client-count");
             // debug("clients: " + clients.text());
             return clients.length == 1 && clients.text().match("/[1-9]+[0-9]*$");
         }, "wait for Active clients: x/y", 5.5 * jasmine_config.second);
 
         runs(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
-            debug("span.mkwsClientCount: " + clients.text());
+            var clients = $("div.mkws-stat span.mkws-client-count");
+            debug("span.mkws-client-count: " + clients.text());
             expect(clients.text()).toMatch("/[1-9]+[0-9]*$");
 
             // exact match of active clients (e.g. a SP misconfiguration)
@@ -344,7 +344,7 @@ describe("Check Source Facets", function () {
         // wait for a stat response
         var waitcount = 0;
         // do not click on wikipedia link - no author or subject facets possible
-        var link = "div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm a";
+        var link = "div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term a";
 
         // wait for a visible source link in facets
         waitsFor(function () {
@@ -368,22 +368,22 @@ describe("Check Source Facets", function () {
             }
             debug("Source counter: " + terms.length + ", select: " + (source_number - 1));
 
-            if ($("div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm:nth-child(" + source_number + ") a").text().length == 0) {
+            if ($("div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term:nth-child(" + source_number + ") a").text().length == 0) {
                 debug("No good source found. Not clicking on the bad ones");
                 return;
             }
 
             debug("click on source link nth-child(): " + source_number);
-            $("div.mkwsFacet[data-mkws-facet='xtargets'] div.mkwsTerm:nth-child(" + source_number + ") a").trigger("click");
+            $("div.mkws-facet[data-mkws-facet='xtargets'] div.mkws-term:nth-child(" + source_number + ") a").trigger("click");
 
-            $(".mkwsPager").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
+            $(".mkws-pager").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
                 waitcount++;
-                debug("DOM change mkwsPager, for stat: " + waitcount);
+                debug("DOM change mkws-pager, for stat: " + waitcount);
             });
         });
 
         waitsFor(function () {
-            if ($("div.mkwsNavi").length && $("div.mkwsNavi").text().match(/(Source|datenquelle|kilder): /i)) {
+            if ($("div.mkws-navi").length && $("div.mkws-navi").text().match(/(Source|datenquelle|kilder): /i)) {
                 return true;
             } else {
                 return false;
@@ -404,7 +404,7 @@ describe("Check Source Facets", function () {
             expect(hits_all_targets).not.toBeLessThan(hits_single_target);
             jasmine_status.source_click = 1;
 
-            $(".mkwsPager").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
+            $(".mkws-pager").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
         });
     });
 });
@@ -420,20 +420,20 @@ describe("Check record list", function () {
         }
 
         waitsFor(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
+            var clients = $("div.mkws-stat span.mkws-client-count");
             //debug("clients: " + clients.text());
             return clients.length == 1 && clients.text().match("/1$");
         }, "wait for Active clients: x/1", 5 * jasmine_config.second);
 
         runs(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
-            debug("span.mkwsClientCount: " + clients.text());
+            var clients = $("div.mkws-stat span.mkws-client-count");
+            debug("span.mkws-client-count: " + clients.text());
             expect(clients.text()).toMatch("/1$");
         });
     });
 
     it("got a record", function () {
-        var linkaddr = "div.mkwsRecords div.mkwsSummary:nth-child(1) a";
+        var linkaddr = "div.mkws-records div.mkws-summary:nth-child(1) a";
 
         waitsFor(function () {
             // remove + insert node: must be at least 2
@@ -451,20 +451,20 @@ describe("Show record", function () {
 
     var record_number = 1; // the Nth record in hit list
     it("show record author", function () {
-        var click = $("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") a").trigger("click");
+        var click = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") a").trigger("click");
         debug("show record click is success: " + click.length);
         expect(click.length).toBe(1);
 
         // wait until the record pops up
         waitsFor(function () {
-            var show = $("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") > div.mkwsDetails");
-            //debug("poprecord: " + (show ? show.length : -1) + " " + $("div.mkwsRecords div.mkwsSummary").text());
+            var show = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") > div.mkws-details");
+            //debug("poprecord: " + (show ? show.length : -1) + " " + $("div.mkws-records div.mkws-summary").text());
             return show != null && show.length ? true : false;
         }, "wait some miliseconds to show up a record", 2 * jasmine_config.second);
 
         runs(function () {
             debug("show record pop up");
-            expect($("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") div")).not.toBe(null);
+            expect($("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") div")).not.toBe(null);
         });
     });
 
@@ -474,7 +474,7 @@ describe("Show record", function () {
             return;
         }
 
-        var urls = $("div.mkwsRecords div.mkwsSummary:nth-child(" + record_number + ") div table tbody tr td a");
+        var urls = $("div.mkws-records div.mkws-summary:nth-child(" + record_number + ") div table tbody tr td a");
         debug("number of extracted URL from record: " + urls.length);
         // expect(urls.length).toBeGreaterThan(0); // LoC has records without links
         for (var i = 0; i < urls.length; i++) {
@@ -491,19 +491,19 @@ describe("Show record", function () {
 describe("Check switch menu Records/Targets", function () {
     var $ = mkws.$;
 
-    it("check mkwsSwitch", function () {
-        expect($("div.mkwsSwitch").length).toBe(1);
+    it("check mkws-switch", function () {
+        expect($("div.mkws-switch").length).toBe(1);
 
         // expect 2 clickable links
-        expect($("div.mkwsSwitch > a").length).toBe(2);
+        expect($("div.mkws-switch > a").length).toBe(2);
     });
 
     it("switch to target view", function () {
-        $("div.mkwsSwitch > a").eq(1).trigger("click");
+        $("div.mkws-switch > a").eq(1).trigger("click");
 
         // now the target table must be visible
-        expect($("div.mkwsTargets").is(":visible")).toBe(true);
-        expect($("div.mkwsRecords").is(":visible")).toBe(false);
+        expect($("div.mkws-targets").is(":visible")).toBe(true);
+        expect($("div.mkws-records").is(":visible")).toBe(false);
 
         // wait a half second, to show the target view
         var time = (new Date).getTime();
@@ -513,16 +513,16 @@ describe("Check switch menu Records/Targets", function () {
 
         // look for table header
         runs(function () {
-            expect($("div.mkwsTargets").html()).toMatch(/Target ID/);
+            expect($("div.mkws-targets").html()).toMatch(/Target ID/);
         });
     });
 
     it("switch back to record view", function () {
-        $("div.mkwsSwitch > a").eq(0).trigger("click");
+        $("div.mkws-switch > a").eq(0).trigger("click");
 
         // now the target table must be visible
-        expect($("div.mkwsTargets").is(":visible")).toBe(false);
-        expect($("div.mkwsRecords").is(":visible")).toBe(true);
+        expect($("div.mkws-targets").is(":visible")).toBe(false);
+        expect($("div.mkws-records").is(":visible")).toBe(true);
     });
 });
 
@@ -542,7 +542,7 @@ describe("Check status client counter", function () {
         }
 
         waitsFor(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
+            var clients = $("div.mkws-stat span.mkws-client-count");
             debug("clients: " + clients.text());
             if (clients.length == 1 && clients.text().match("0/1$")) {
                 return true;
@@ -552,8 +552,8 @@ describe("Check status client counter", function () {
         }, "wait for Active clients: 0/1", 4 * jasmine_config.second);
 
         runs(function () {
-            var clients = $("div.mkwsStat span.mkwsClientCount");
-            debug("span.mkwsClientCount: " + clients.text());
+            var clients = $("div.mkws-stat span.mkws-client-count");
+            debug("span.mkws-client-count: " + clients.text());
             expect(clients.text()).toMatch("0/1$");
         });
     });
@@ -572,44 +572,44 @@ describe("Check removable facets links", function () {
 
 
         runs(function () {
-            var click = $("a.mkwsRemovable").eq(0).trigger("click");
+            var click = $("a.mkws-removable").eq(0).trigger("click");
             debug("Removed first facets link: " + click.length);
             expect(click.length).toBe(1);
         });
 
         runs(function () {
-            $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
+            $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
                 waitcount++;
-                debug("DOM change mkwsRecords for removeable: " + waitcount);
+                debug("DOM change mkws-records for removeable: " + waitcount);
             });
         });
 
         waitsFor(function () {
-            return waitcount >= 2 && $("a.mkwsRemovable").length == 1 ? 1 : 0;
-        }, "Records DOM change mkwsRecords, removable", 2 * jasmine_config.second);
+            return waitcount >= 2 && $("a.mkws-removable").length == 1 ? 1 : 0;
+        }, "Records DOM change mkws-records, removable", 2 * jasmine_config.second);
 
         runs(function () {
             debug("unbind removable");
-            $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
+            $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
             waitcount = 0;
 
-            $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
+            $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
                 waitcount++;
-                debug("DOM change mkwsRecords for removeable2: " + waitcount);
+                debug("DOM change mkws-records for removeable2: " + waitcount);
             });
 
-            var click = $("a.mkwsRemovable").eq(0).trigger("click");
+            var click = $("a.mkws-removable").eq(0).trigger("click");
             debug("Removed second facets link: " + click.length);
             expect(click.length).toBe(1);
         });
 
         waitsFor(function () {
-            return waitcount >= 2 && $("a.mkwsRemovable").length == 0 ? true : false;
-        }, "DOM change mkwsRecords, removable2", 2 * jasmine_config.second);
+            return waitcount >= 2 && $("a.mkws-removable").length == 0 ? true : false;
+        }, "DOM change mkws-records, removable2", 2 * jasmine_config.second);
 
         runs(function () {
             debug("unbind removable2");
-            $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
+            $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
         });
     });
 });
@@ -628,30 +628,30 @@ describe("Check per page options", function () {
 
 
         runs(function () {
-            var select = $("select.mkwsPerpage option[selected='selected']");
+            var select = $("select.mkws-perpage option[selected='selected']");
             debug("per page default is: " + select.text() + " and unselect it");
             select.removeAttr('selected');
 
-            select = $("select.mkwsPerpage option[value='" + per_page_number + "']").attr('selected', true);
+            select = $("select.mkws-perpage option[value='" + per_page_number + "']").attr('selected', true);
             debug("per page is set to: " + select.text());
             select.trigger("change");
 
-            $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
+            $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
                 waitcount++;
-                debug("DOM change mkwsRecords, per page: " + waitcount);
+                debug("DOM change mkws-records, per page: " + waitcount);
             });
         });
 
         waitsFor(function () {
             // debug("per page waitcounter: " + waitcount)
             return waitcount >= (per_page_number + 10) ? true : false;
-        }, "DOM change mkwsRecords, by per page", 3 * jasmine_config.second);
+        }, "DOM change mkws-records, by per page", 3 * jasmine_config.second);
 
         runs(function () {
             debug("unbind per page");
-            $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
+            $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
 
-            var records = $("div.mkwsRecords > div.mkwsSummary");
+            var records = $("div.mkws-records > div.mkws-summary");
             debug("Per page got now " + records.length + " records");
             expect(records.length).toBe(per_page_number);
         });
@@ -674,9 +674,9 @@ describe("Check SortBy options", function () {
 
         function title_list(prefix) {
             var list = [];
-            var terms = $("div.mkwsRecords > div.mkwsSummary > a");
+            var terms = $("div.mkws-records > div.mkws-summary > a");
             for (var i = 0; i < terms.length; i++) {
-                var term = $(terms[i]).text();
+                var term = $(terms[i]).text().trim();
                 list.push(term);
                 // debug(prefix + "title: " + term);
             }
@@ -684,16 +684,16 @@ describe("Check SortBy options", function () {
         }
 
         runs(function () {
-            $("div.mkwsRecords").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
+            $("div.mkws-records").bind("DOMNodeInserted DOMNodeRemoved propertychange", function () {
                 waitcount++;
-                debug("DOM change mkwsRecords, sort by: " + waitcount);
+                debug("DOM change mkws-records, sort by: " + waitcount);
             });
 
-            var select = $("select.mkwsSort option[selected='selected']");
+            var select = $("select.mkws-sort option[selected='selected']");
             debug("Sort by default is: " + select.text() + " and unselect it");
             select.removeAttr('selected');
 
-            select = $("select.mkwsSort option[value='" + sort_value + "']").attr('selected', true);
+            select = $("select.mkws-sort option[value='" + sort_value + "']").attr('selected', true);
             debug("sort by is set to: " + select.text());
             select.trigger("change");
         });
@@ -701,13 +701,13 @@ describe("Check SortBy options", function () {
         waitsFor(function () {
             //debug("wait for2: " + waitcount);
             return waitcount >= (per_page_number + 10) ? true : false;
-        }, "DOM change mkwsRecords, by sort page", 3 * jasmine_config.second);
+        }, "DOM change mkws-records, by sort page", 3 * jasmine_config.second);
 
         runs(function () {
-            $("div.mkwsRecords").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
+            $("div.mkws-records").unbind("DOMNodeInserted DOMNodeRemoved propertychange");
             debug("unbind by sort");
 
-            var records = $("div.mkwsRecords > div.mkwsSummary > a");
+            var records = $("div.mkws-records > div.mkws-summary > a");
             debug("Sort by got now " + records.length + " records");
             expect(records.length).toBe(per_page_number);
         });
@@ -716,7 +716,7 @@ describe("Check SortBy options", function () {
             var title_list_new = title_list("yyy ");
             var diff_flag = 0;
             for (var i = 0; i < title_list_old.length; i++) {
-                debug(title_list_old[i] + " :: " + title_list_new[i]);
+                debug((i+1) + ". " + title_list_old[i] + " :: " + title_list_new[i]);
 
                 if (title_list_old[i] != title_list_new[i]) {
                     diff_flag++;
@@ -731,12 +731,19 @@ describe("Check SortBy options", function () {
 describe("Check async widget discovery", function () {
   var $ = mkws.$;
   it("initialises a new widget", function() {
-    $("div.mkwsSearch").after('<div id="asyncSearch"><div id="asyncSearch" class="mkwsSearch mkwsTeam_async"></div></div>');
-    mkws.init("Another search box");
-    // mkws.init("Another search box", "#asyncSearch");
+    $("div.mkws-search").after('<div id="asyncSearch"><div class="mkws-search mkws-team-async"></div></div>');
+    mkws.init("Another search box", "#asyncSearch");
     waitsFor(function () {
       return $("#asyncSearch input").length >= 1 ? true : false;
-    }, "Call init() to build an .mkwsSearch", 750);
+    }, "Call init() to build an .mkws-search", 750);
+    runs(function () {
+      var numInput = $("div.mkws-search input").length;
+      debug("Input elements present: " + numInput);
+      expect(numInput).toBe(4);
+      var numRec = $("div.mkws-records > div.mkws-summary > a").length;
+      debug("Records should still be present. There are: " + numRec);
+      expect(numRec).toBeGreaterThan(0);
+    });
   });
 });
 
index 8979206..730f918 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
  *
  * jQuery sample from system documentation
  *
index b515c06..eba8a05 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
  *
  * dummy test
  *
diff --git a/test/widgets/Makefile b/test/widgets/Makefile
new file mode 100644 (file)
index 0000000..18a303c
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
+
+PHANTOMJS_TIMEOUT=30
+PHANTOMJS=     ../node_modules/phantomjs/bin/phantomjs
+IMAGES=                ./images
+SCREENSHOT_WIDTH_HEIGHT=       1000 1200
+PERL_SCRIPTS=  ../bin/bomb.pl
+PROG=  ../phantom/screenshot.js
+MD5=   $(shell which md5 md5sum)
+TESTS= koha demos mike # koha.url
+TIMEOUT=4
+PREFIX=        test
+
+PHANTOMJS_URL= http://cph.koha.indexdata.com/cgi-bin/koha/opac-search.pl?q=sushi
+PHANTOMJS_URL= http://www.indexdata.com/
+
+all: help
+
+clean:
+       rm -f index-*.html
+       rm -f ${IMAGES}/*.png
+
+distclean: clean
+       rm -f ${IMAGES}/*.png.tmp
+
+test: check
+
+screenshot:
+       file=${PREFIX}.$$(echo "${PHANTOMJS_URL}" | perl -npe 's,(\W),-,g; s/-$$//;'); \
+         ${PHANTOMJS} ${PROG} ${PHANTOMJS_URL} ${IMAGES}/tmp.$$file.png ${SCREENSHOT_WIDTH_HEIGHT} ${TIMEOUT}; \
+         mv -f  ${IMAGES}/tmp.$$file.png  ${IMAGES}/$$file.png
+
+screenshots: clean estimate-time
+       for t in ${TESTS}; do \
+           for i in $$(cat url.$$t); do \
+               ${MAKE} PHANTOMJS_URL="$$i" TIMEOUT=4 PREFIX=$$t screenshot; \
+           done; \
+           ${MAKE} PREFIX=$$t index; \
+       done
+
+estimate-time:
+       @wc -l url.* | tail -n1 | awk '{print "Estimeate run time: " $$1 * (1 + '${TIMEOUT}'), "seconds" }'
+       @echo ""
+
+index:
+       ( cd ${IMAGES}; ls -tr ${PREFIX}.*.png | perl -ne 'chomp; print qq{<h2>$$_</h2><img src="'${IMAGES}/'$$_"/><br/><br/><p/>\n}' ) > index-${PREFIX}.html
+
+help:
+       @echo "make [ all | clean | distclean ]"
+       @echo "     [ screenshots ]"
+       @echo "     [ screenshot | index ]"
+       @echo ""
+       @echo "Examples: "
+       @echo ""
+       @echo "make TESTS=mike screenshots"
+
diff --git a/test/widgets/images/.gitkeep b/test/widgets/images/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/widgets/url.demos b/test/widgets/url.demos
new file mode 100644 (file)
index 0000000..1087ee7
--- /dev/null
@@ -0,0 +1,9 @@
+http://example.indexdata.com/simple.html
+http://example.indexdata.com/minimal.html
+http://example.indexdata.com/language.html
+http://example.indexdata.com/mobile.html
+http://example.indexdata.com/lowlevel.html
+http://example.indexdata.com/dict.html
+http://example.indexdata.com/popup.html
+http://example.indexdata.com/auto.html
+http://example.indexdata.com/localauth.html
diff --git a/test/widgets/url.koha b/test/widgets/url.koha
new file mode 100644 (file)
index 0000000..c5b8207
--- /dev/null
@@ -0,0 +1,7 @@
+http://cph.koha.indexdata.com/cgi-bin/koha/opac-search.pl?q=sushi
+http://demo.koha.indexdata.com/cgi-bin/koha/opac-search.pl?q=sushi
+http://demo.koha.indexdata.com/cgi-bin/koha/opac-search.pl?q=sushi2
+http://boston.koha.indexdata.com/cgi-bin/koha/opac-search.pl?q=sushi
+http://example.indexdata.com/topic.html?q=sushi
+http://example.indexdata.com/simple.html
+
diff --git a/test/widgets/url.mike b/test/widgets/url.mike
new file mode 100644 (file)
index 0000000..8c8fc40
--- /dev/null
@@ -0,0 +1 @@
+http://zthes.z3950.org/
index acf7cf4..6ec427f 100644 (file)
@@ -7,6 +7,7 @@ User ${APACHE_RUN_USER}
 Group ${APACHE_RUN_GROUP}
 PidFile ${APACHE_PID_FILE}
 LockFile ${APACHE_LOCK_FILE}
+ErrorLog ${APACHE_LOG_DIR}/error-${APACHE_PORT}.log
 
 ServerName localhost
 ServerRoot ${APACHE_SERVER_ROOT}
@@ -16,7 +17,9 @@ Listen ${APACHE_PORT}
 Include ${APACHE_MODULES}
 
 <IfModule log_config_module>
-   LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
+   # %O only works if mod_logio is enabled, which it isn't on Mike's MacBook
+   # LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
+   LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s \"%{Referer}i\" \"%{User-Agent}i\"" combined
 </IfModule>
 
 # pazpar2 / service proxy config
@@ -25,12 +28,12 @@ Include ${APACHE_MODULES}
     ServerAlias mkws-dev a.mkws.indexdata.com a.mkws-dev.indexdata.com mkws-dev.indexdata.com 127.0.0.1
 
     ServerAdmin webmaster@indexdata.com
-    ErrorLog ${APACHE_LOG_DIR}/mkws-jasmine-error.log
-    CustomLog ${APACHE_LOG_DIR}/mkws-jasmine-access.log combined
+    ErrorLog ${APACHE_LOG_DIR}/mkws-jasmine-error-${APACHE_PORT}.log
+    CustomLog ${APACHE_LOG_DIR}/mkws-jasmine-access-${APACHE_PORT}.log combined
 
     RewriteEngine on
     RewriteLogLevel 1
-    RewriteLog ${APACHE_LOG_DIR}/mkws-jasmine-rewrite.log 
+    RewriteLog ${APACHE_LOG_DIR}/mkws-jasmine-rewrite-${APACHE_PORT}.log 
 
     DocumentRoot ${MKWS_ROOT}/examples/htdocs
     Alias /tools/htdocs ${MKWS_ROOT}/tools/htdocs
index 3c0f626..30a87b8 100644 (file)
@@ -7,6 +7,7 @@ User ${APACHE_RUN_USER}
 Group ${APACHE_RUN_GROUP}
 PidFile ${APACHE_PID_FILE}
 Mutex file:${APACHE_LOG_DIR}
+ErrorLog ${APACHE_LOG_DIR}/error-${APACHE_PORT}.log
 
 ServerName localhost
 ServerRoot ${APACHE_SERVER_ROOT}
@@ -24,8 +25,8 @@ Include ${APACHE_MODULES}
     ServerAlias mkws-dev a.mkws.indexdata.com a.mkws-dev.indexdata.com mkws-dev.indexdata.com 127.0.0.1
 
     ServerAdmin webmaster@indexdata.com
-    ErrorLog ${APACHE_LOG_DIR}/mkws-jasmine-error.log
-    CustomLog ${APACHE_LOG_DIR}/mkws-jasmine-access.log combined
+    ErrorLog ${APACHE_LOG_DIR}/mkws-jasmine-error-${APACHE_PORT}.log
+    CustomLog ${APACHE_LOG_DIR}/mkws-jasmine-access-${APACHE_PORT}.log combined
     LogLevel info rewrite:debug
 
     RewriteEngine on
index 582af95..9b426fb 100644 (file)
@@ -35,8 +35,8 @@
     # mkws devel account (e.g. memached testing)
     RewriteRule /service-proxy-auth(/)?(;jsessionid=.+)?  /service-proxy/$2?command=auth&action=login&username=mkwsdev&password=mkwsdev [P] # [NE,P]
 
-    ProxyPass        /service-proxy/ http://sp-mkc.indexdata.com/service-proxy/
-    ProxyPassReverse /service-proxy/ http://sp-mkc.indexdata.com/service-proxy/
+    ProxyPass        /service-proxy/ http://sp-mkws.indexdata.com/service-proxy/
+    ProxyPassReverse /service-proxy/ http://sp-mkws.indexdata.com/service-proxy/
 
     ProxyPass        /pazpar2/         http://localhost:8004/pazpar2/
     ProxyPassReverse /pazpar2/         http://localhost:8004/pazpar2/
index e0cfd60..74c384f 100644 (file)
     RewriteRule /service-proxy-kohaauth(/)?(;jsessionid=.+)?   /service-proxy/$2?command=auth&action=check,login&username=kohademo&password=kohademo&identity=demo_koha_mkws [P]
     RewriteRule /service-proxy-orexauth(/)?(;jsessionid=.+)?   /service-proxy/$2?command=auth&action=check,login&username=orex&password=orexmkc&identity=orex_digital2 [P]
 
-    # The following rule allows the server to accept service-proxy
-    # requests that begin with an escaped "%3F" rather than a literal
-    # "?". This is useful, as requests generated by ProxyPass
-    # elsewhere always have the leading "?" escaped for some reason.
-    RewriteRule /service-proxy/\?(.*) /service-proxy/?$1 [P] # [NE,P]
-
-    Header set Access-Control-Allow-Credentials true
-
-    # For MKC Service Proxy
-#    ProxyPreserveHost On
-    ProxyPass        /service-proxy/ http://sp-mkc.indexdata.com/service-proxy/
-    ProxyPassReverse /service-proxy/ http://sp-mkc.indexdata.com/service-proxy/
-    # Or use: sp-mkc-sansa.indexdata.com:8080 or sp-mkc-arya.indexdata.com:8080
-
-    PerlOptions +Parent
-    PerlSwitches -I/home/indexdata/mkws/tools/mod_perl
-    <Location /service-proxy>
-        PerlOutputFilterHandler MyApache2::SetACAO
-    </Location>
+    RewriteRule /service-proxy/        /no-service-proxy.html
 </VirtualHost>
index 02417a4..79c1d6d 100644 (file)
@@ -3,8 +3,16 @@
     ErrorLog /var/log/apache2/mkws-tools-error.log
     CustomLog /var/log/apache2/mkws-tools-access.log combined
 
-    DocumentRoot /usr/local/src/git/mkws/tools/htdocs/
+    DocumentRoot /home/mike/git/work/mkws/tools/htdocs/
 
-    Alias /libjs-pz2/ /usr/local/src/git/libjs-pz2/
-    Alias /pazpar2/ /usr/local/src/git/pazpar2/
+    Alias /libjs-pz2/ /home/mike/git/work/libjs-pz2/
+    Alias /pazpar2/ /home/mike/git/work/pazpar2/
+
+    <Directory />
+        Allow from all
+       Require all granted
+    </Directory>
+    <Location /releases/>
+       Options indexes
+    </Location>
 </VirtualHost>
index bcd9e81..f335d96 100644 (file)
     Header set Access-Control-Allow-Credentials true
 
     ProxyPreserveHost On
-    # We could use any of the following:
-    #  sp-mkc.indexdata.com/service-proxy/ -- multiplexer
-    #  sp-mkc-sansa.indexdata.com:8080/service-proxy/ -- 1st back-end server
-    #  sp-mkc-arya.indexdata.com:8080/service-proxy/ -- 2nd back-end server
-    ProxyPass        /service-proxy/ http://sp-mkc-sansa.indexdata.com:8080/service-proxy/
-    ProxyPassReverse /service-proxy/ http://sp-mkc-sansa.indexdata.com:8080/service-proxy/
+    ProxyPass        /service-proxy/ http://sp-mkws-backend.indexdata.com:8080/service-proxy/
+    ProxyPassReverse /service-proxy/ http://sp-mkws-backend.indexdata.com:8080/service-proxy/
 
     PerlOptions +Parent
     PerlSwitches -I/home/indexdata/mkws/tools/mod_perl
index 2904e85..0de766d 100755 (executable)
@@ -4,7 +4,7 @@
 # nagios test if the the service proxy is up and running
 
 set -e
-: ${mkws_host="http://mkws.indexdata.com/service-proxy/"}
+: ${mkws_host="http://sp-mkws.indexdata.com/service-proxy/"}
 : ${mkws_username="mkws"}
 : ${mkws_password="mkws"}
 : ${user_agent="nagios service-proxy v0.9"}
index b31bd88..b4c48d5 100644 (file)
@@ -1,15 +1,17 @@
+index.html
+mkws-manual.html
+mkws-developer.html
+index.pdf
+mkws-manual.pdf
+mkws-developer.pdf
+mkws-doc.css
 NEWS
-README.html
 VERSION
-handlebars-v1.1.2.js
+handlebars-v2.0.0.js
 jquery-1.10.0.min.js
 jquery.json-2.4.js
-mkws-complete.js
-mkws-complete.min.js
-mkws-doc.css
-mkws-jquery.js
+pz2.js
 mkws.js
+mkws-complete.js
 mkws.min.js
-pz2.js
-mkws-manual.html
-mkws-developer.html
+mkws-complete.min.js
diff --git a/tools/htdocs/Makefile b/tools/htdocs/Makefile
deleted file mode 100644 (file)
index 420bb49..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
-
-SRC=   ../../src
-
-HANDLEBARS_FILE = handlebars-v1.1.2.js
-JQUERY_FILE = jquery-1.10.0.min.js
-JQUERY_JSON_FILE = jquery.json-2.4.js
-PP2_FILE = pz2.js
-
-HANDLEBARS_URL = http://builds.handlebarsjs.com.s3.amazonaws.com/${HANDLEBARS_FILE}
-JQUERY_URL = http://code.jquery.com/${JQUERY_FILE}
-JQUERY_JSON_URL = https://jquery-json.googlecode.com/files/${JQUERY_JSON_FILE}
-PP2_URL = http://git.indexdata.com/?p=pazpar2.git;a=blob_plain;f=js/${PP2_FILE};hb=HEAD
-
-JQUERY_UI_URL =        http://code.jquery.com/ui/1.10.3/jquery-ui.js
-VERSION = $(shell tr -d '\012' < ${SRC}/VERSION)
-
-COMPONENTS = ${SRC}/mkws-handlebars.js \
-       ${SRC}/mkws-core.js \
-       ${SRC}/mkws-team.js \
-       ${SRC}/mkws-filter.js \
-       ${SRC}/mkws-popup.js \
-       ${SRC}/mkws-widget.js \
-       ${SRC}/mkws-widget-main.js \
-       ${SRC}/mkws-widget-termlists.js \
-       ${SRC}/mkws-widget-authname.js \
-       ${SRC}/mkws-widget-categories.js \
-       ${SRC}/mkws-widget-log.js \
-       ${SRC}/mkws-widget-record.js \
-       ${SRC}/mkws-widget-reference.js \
-       ${SRC}/mkws-widget-builder.js
-
-GENERATED = ${HANDLEBARS_FILE} ${JQUERY_FILE} ${JQUERY_JSON_FILE} ${PP2_FILE} \
-       mkws.js mkws.min.js mkws-complete.js mkws-complete.min.js
-
-**make-default**: all
-
-all: mkws.min.js mkws-complete.min.js
-
-mkws-js mkws-complete.js: Makefile mkws.js ${HANDLEBARS_FILE} ${JQUERY_FILE} ${JQUERY_JSON_FILE} ${PP2_FILE}
-       ( set -e; \
-         echo "/*! Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com"; \
-         echo "   Licence: GPL, http://www.indexdata.com/licences/gpl"; \
-         echo "   created at: $$(date)"; \
-         echo "   MKWS GIT id: $$(git show | head -n 1 | perl -npe 's,\S+\s+,,')"; \
-         echo "   pz2.js GIT id: $$(curl -sSf 'http://git.indexdata.com/?p=pazpar2.git;a=rss' | egrep '<guid' | head -1 | perl -ne 'print "$$1\n" if m,.*=([0-9a-f]+)</guid>,')"; \
-         echo "*/"; \
-         cat ${JQUERY_FILE}; \
-         cat ${JQUERY_JSON_FILE}; \
-         echo 'mkws_jQuery = jQuery.noConflict(true);'; \
-         cat ${HANDLEBARS_FILE}; \
-         cat ${PP2_FILE}; \
-         cat  mkws.js; \
-       ) > mkws-complete.js.tmp
-       mv -f mkws-complete.js.tmp mkws-complete.js
-
-%.min.js: %.js
-       yui-compressor $? > $@.tmp
-       mv -f $@.tmp $@
-
-mkws-syntax-check:
-       yui-compressor mkws.js >/dev/null
-
-${HANDLEBARS_FILE}:
-       curl -sSf ${HANDLEBARS_URL} -o $@.tmp
-       mv -f $@.tmp $@
-
-${JQUERY_FILE}:
-       curl -sSf ${JQUERY_URL} -o $@.tmp
-       perl -npe 's,sourceMappingURL=jquery.*map,,' $@.tmp > $@
-       rm -f $@.tmp
-
-${JQUERY_JSON_FILE}:
-       curl -sSf ${JQUERY_JSON_URL} -o $@.tmp
-       mv -f $@.tmp $@
-
-${PP2_FILE}:
-       curl -sSf "${PP2_URL}" -o $@.tmp
-       mv -f $@.tmp $@
-
-release: mkws.js mkws-complete.js mkws.min.js mkws-complete.min.js
-       @if [ -f ${SRC}/releases/mkws-$(VERSION).js ]; then \
-               echo "*** There is already a release $(VERSION)"; \
-       else \
-               cp -p mkws.js ${SRC}/releases/mkws-$(VERSION).js; \
-               cp -p mkws.min.js ${SRC}/releases/mkws-$(VERSION).min.js; \
-               cp -p mkws-complete.js ${SRC}/releases/mkws-complete-$(VERSION).js; \
-               cp -p mkws-complete.min.js ${SRC}/releases/mkws-complete-$(VERSION).min.js; \
-               echo "Made release $(VERSION)"; \
-       fi
-
-mkws.js: $(COMPONENTS) Makefile
-       rm -f $@
-       cat ${COMPONENTS} > $@.tmp
-       mv -f $@.tmp $@
-       chmod 444 $@
-
-mkws-html-includes: 
-       echo $(COMPONENTS) | perl -npe "s,${SRC},,g; s/\s+/\0/g" | \
-         perl -n0e 'chomp(); print qq{    <script type="text/javascript" src="src$$_"></script>\n}'
-
-distclean: clean
-       @echo "(No need for distclean, 'make clean' is fine)"
-
-clean:
-       rm -f ${GENERATED}
-
-help:
-       @echo "make [ all | release | clean | distclean ]"
-       @echo "     [ mkws-syntax-check ]"
index 414ada3..6d85773 100644 (file)
@@ -1,17 +1,5 @@
-OVERVIEW
-========
-
-The MasterKey Widget Set, or MKWS, is a project to create some very
-simple HTML/JS/CSS widgets that can be dropped into ANY website,
-irrespective of CMS or lack thereof, to enable MasterKey searching.
-
-
-WHAT'S WHAT
-===========
+Subdirectories:
 
 external -- CSS/JS files for external plugins, e.g. Koha
 releases -- released MKWS JS/CSS files, with version number
 images   -- MKWS images and logos
-
---
-https://mkws.indexdata.com
index 560545b..00edde1 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
 #
 # this makefile will generate CSS files for Koha MKWS widgets
 
index d52efb3..40e2edc 100644 (file)
@@ -1,4 +1,4 @@
-.mkwsReference {
+.mkws-reference {
     max-width: 40em;
     font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
     background: #f0f0e0;
@@ -9,31 +9,31 @@
     -webkit-border-radius: 1em;
 }
 
-.mkwsReference h1 a {
+.mkws-reference h1 a {
     color: #806020;
 }
 
-.mkwsReference a {
+.mkws-reference a {
     text-decoration: none;
 }
 
-.mkwsReference img {
+.mkws-reference img {
     float: right;
     margin: 0 0 1em 2em;
     border: 0.5em solid white;
 }
 
-.mkwsCredit {
+.mkws-credit {
     font-size: small;
     text-align: right;
 }
 
-.mkwsCredit::before {
+.mkws-credit::before {
     content: "Source: ";
     font-weight: bold;
 }
 /* original "ru" config
-.mkwsReferenceUniverse {
+.mkws-reference-universe {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   background: #FCFBFA; 
   padding: 0.5em 1em 0.25em;
 }
 */
 
-.mkwsReferenceUniverse {
+.mkws-reference-universe {
   padding: 0.5em 1em 0.25em;
 }
 
-.mkwsReferenceUniverse h2 {
+.mkws-reference-universe h2 {
   font-size: 100%;
   color: #4A5456;
   padding-bottom: .5em;
 }
 
-.mkwsReferenceUniverse ul {
+.mkws-reference-universe ul {
   margin: 0;
   padding: 0;
 }
 
-.mkwsReferenceUniverse li {
+.mkws-reference-universe li {
   margin: .95em .25em;
   padding-top: .75em;
   border-top: 1px dotted #BEC8CC;
   list-style: none;
 }
 
-.mkwsReferenceUniverse a {
+.mkws-reference-universe a {
   text-decoration: none;
   font-weight:bold;
   color: #2B77AF;
 }
-/*! Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+/*! Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
  * Licence: GPL, http://www.indexdata.com/licences/gpl
  *
  * Style sheet for MKWS plugin for Koha
 */
 
 /* submit button color */
-form[name=mkwsSearchForm] > input[type=submit].mkwsButton {
+form[name=mkws-searchform] > input[type=submit].mkws-button {
   background: #006dcc;
   border: 3px outset #006dcc;
   margin-bottom: 10px;
 }
 
-select.mkwsTeam_AUTO {
+select.mkws-team_auto {
   width: 10em;
   font-size: 11px;
   height: 25px;
 }
 
 /* facet links */
-div.mkwsFacet > div.term { background: none; }
+div.mkws-facet > div.term { background: none; }
 
 /* facet counter for a link */
-div.mkwsFacet > div.term > span { color: #000; }
+div.mkws-facet > div.term > span { color: #000; }
 
 /* sidebar */
 @media (min-width: 768px) and (max-width: 1199px) {
@@ -148,7 +148,7 @@ div.mkwsFacet > div.term > span { color: #000; }
   margin-bottom: 5px;
 }
 
-.mkws-autosearch div.mkwsRecords {
+.mkws-autosearch div.mkws-records {
   padding: 3px;
 }
 
@@ -165,30 +165,30 @@ div.mkwsFacet > div.term > span { color: #000; }
   text-decoration: none;
 }
 
-.mkwsSwitch a, .mkwsLang a, .mkwsFacet a, .mkwsRanking a, .mkwsPager a, .mkwsNavi a, .mkwsRecords a, .mkwsRecord a {
+.mkws-switch a, .mkws-lang a, .mkws-facet a, .mkws-ranking a, .mkws-pager a, .mkws-navi a, .mkws-records a, .mkws-record a {
   color: #0076b2;
 }
-.mkwsTargets table thead tr td {
+.mkws-targets table thead tr td {
   background-color: #0076b2;
 }
 
-.mkwsCurrentPage {
+.mkws-current-page {
   background: #0076b2;
 }
 
-input[type=submit].mkwsButton {
+input[type=submit].mkws-button {
   background: #006dcc;
 }
 
-.mkwsFacet {
+.mkws-facet {
   background: #fff;
 }
 
 /********************************************************************************
  * Koha + mkws-widget-reference.css
  */
-.mkwsReference h1 a { color: #0076b2; }
-.mkwsReference {
+.mkws-reference h1 a { color: #0076b2; }
+.mkws-reference {
     border: none;
     background: none;
     border-radius: none;
index 6f6139f..68cd04b 100644 (file)
@@ -1,5 +1,5 @@
 /* original "ru" config
-.mkwsReferenceUniverse {
+.mkws-reference-universe {
   font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
   background: #FCFBFA; 
   padding: 0.5em 1em 0.25em;
 }
 */
 
-.mkwsReferenceUniverse {
+.mkws-reference-universe {
   padding: 0.5em 1em 0.25em;
 }
 
-.mkwsReferenceUniverse h2 {
+.mkws-reference-universe h2 {
   font-size: 100%;
   color: #4A5456;
   padding-bottom: .5em;
 }
 
-.mkwsReferenceUniverse ul {
+.mkws-reference-universe ul {
   margin: 0;
   padding: 0;
 }
 
-.mkwsReferenceUniverse li {
+.mkws-reference-universe li {
   margin: .95em .25em;
   padding-top: .75em;
   border-top: 1px dotted #BEC8CC;
@@ -36,7 +36,7 @@
   list-style: none;
 }
 
-.mkwsReferenceUniverse a {
+.mkws-reference-universe a {
   text-decoration: none;
   font-weight:bold;
   color: #2B77AF;
index efde942..464a895 100644 (file)
@@ -1,4 +1,4 @@
-/*! Copyright (c) 2013-2014 IndexData ApS. http://indexdata.com
+/*! Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
  * Licence: GPL, http://www.indexdata.com/licences/gpl
  *
  * Style sheet for MKWS plugin for Koha
@@ -7,23 +7,23 @@
 */
 
 /* submit button color */
-form[name=mkwsSearchForm] > input[type=submit].mkwsButton {
+form[name=mkws-searchform] > input[type=submit].mkws-button {
   background: #006dcc;
   border: 3px outset #006dcc;
   margin-bottom: 10px;
 }
 
-select.mkwsTeam_AUTO {
+select.mkws-team_auto {
   width: 10em;
   font-size: 11px;
   height: 25px;
 }
 
 /* facet links */
-div.mkwsFacet > div.term { background: none; }
+div.mkws-facet > div.term { background: none; }
 
 /* facet counter for a link */
-div.mkwsFacet > div.term > span { color: #000; }
+div.mkws-facet > div.term > span { color: #000; }
 
 /* sidebar */
 @media (min-width: 768px) and (max-width: 1199px) {
@@ -71,7 +71,7 @@ div.mkwsFacet > div.term > span { color: #000; }
   margin-bottom: 5px;
 }
 
-.mkws-autosearch div.mkwsRecords {
+.mkws-autosearch div.mkws-records {
   padding: 3px;
 }
 
@@ -88,30 +88,30 @@ div.mkwsFacet > div.term > span { color: #000; }
   text-decoration: none;
 }
 
-.mkwsSwitch a, .mkwsLang a, .mkwsFacet a, .mkwsRanking a, .mkwsPager a, .mkwsNavi a, .mkwsRecords a, .mkwsRecord a {
+.mkws-switch a, .mkws-lang a, .mkws-facet a, .mkws-ranking a, .mkws-pager a, .mkws-navi a, .mkws-records a, .mkws-record a {
   color: #0076b2;
 }
-.mkwsTargets table thead tr td {
+.mkws-targets table thead tr td {
   background-color: #0076b2;
 }
 
-.mkwsCurrentPage {
+.mkws-current-page {
   background: #0076b2;
 }
 
-input[type=submit].mkwsButton {
+input[type=submit].mkws-button {
   background: #006dcc;
 }
 
-.mkwsFacet {
+.mkws-facet {
   background: #fff;
 }
 
 /********************************************************************************
  * Koha + mkws-widget-reference.css
  */
-.mkwsReference h1 a { color: #0076b2; }
-.mkwsReference {
+.mkws-reference h1 a { color: #0076b2; }
+.mkws-reference {
     border: none;
     background: none;
     border-radius: none;
diff --git a/tools/htdocs/index.html b/tools/htdocs/index.html
deleted file mode 100644 (file)
index 9835c66..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    <title>MKWS: the MasterKey Widget Set</title>
-    <style type="text/css">
-      body {
-      font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Sans-Serif;
-      }
-      h1, h3 { font-weight: normal; color: #606060 }
-      h2 { margin-top: 0.5em }
-      .pane { padding: 0em 1em; margin: 0.75em;
-              border: 0.5em solid #eee;
-              border-radius: 1em;
-              background-image: url('images/mkws-logo-48x48-light.png');
-              background-repeat: no-repeat;
-              background-position: right top;
-              background-color: #eee; 
-            }
-      .nologo { background-image: none }
-      pre { background: #ddd; padding: 0.5em; }
-    </style>
-  </head>
-  <body>
-    <img src="images/mkws-logo-300px.png" alt="MKWS logo" =
-        style="float:right; margin: 1.5em"/>
-    <h1>MKWS: the MasterKey Widget Set</h1>
-
-    <div class="pane nologo">
-      <h2>Add metasearching to your web-site painlessly</h2>
-      <p>
-       The MasterKey Widget Set provides the easiest possible way to
-       enhance an existing web-site with customised searching across
-       multiple sources, ranking and merging the results.
-      </p>
-      <p>
-       All you need to do is pull in our JavaScript and optional
-       stylesheet, then add <tt>&lt;div&gt;</tt>s to your page that
-       have special <tt>id</tt> attributes. We do the rest.
-      </p>
-    </div>
-
-    <div class="pane">
-      <h2>A minimal example</h2>
-      <p>
-       Here is a completely functional (though ugly) MKWS-based
-       searching application:
-      </p>
-      <blockquote>
-       <pre>
-&lt;script type="text/javascript"
-        src="http://mkws.indexdata.com/mkws-complete.js">&lt;/script>
-&lt;div id="mkwsSearch">&lt;/div>
-&lt;div id="mkwsResults">&lt;/div></pre>
-      </blockquote>
-      <p>
-       That's it. A complete metasearching application. Everything
-       else is refinement.
-      </p>
-    </div>
-
-    <div class="pane">
-      <h2>Documentation</h2>
-      <ul>
-       <li>
-          The <a href="README.html">README</a> -- mostly technical details.
-       </li>
-       <li>
-          The <a href="mkws-manual.html">MKWS manual, including a
-          reference section.</a>
-         This is a much better introduction.
-       </li>
-      </ul>
-    </div>
-
-    <div class="pane">
-      <h2>Tools</h2>
-      <p>
-       Here are the files that this web-site provides:
-      </p>
-      <ul>
-       <li>
-          <a href="mkws.js">mkws.js</a>
-          --
-          JavaScript code that powers the MasterKey Widget Set
-       </li>
-       <li>
-          <a href="pazpar2/js/pz2.js">pazpar2/js/pz2.js</a>
-          --
-          Low-level JavaScript library for access to the MasterKey web
-          service.
-       </li>
-       <li>
-         <a href="handlebars-v1.1.2.js">handlebars-v1.1.2.js</a>
-         --
-         A local copy of
-         <a href="http://handlebarsjs.com/"
-            >the Handlebars templating library</a>,
-         since it doesn't like to be hotlinked.
-       </li>
-       <li>
-          <a href="mkws-complete.js"
-             >mkws-complete.js</a>
-          --
-          A single large JavaScript file containing everything needed for
-          MKWS to work: the widget-set itself, the API library, and
-          the prerequisites jQuery and Handlebars.
-       </li>
-       <li>
-          <a href="mkws.css">mkws.css</a>
-          --
-          A stylesheet which styles only MasterKey widgets, and does not
-          otherwise interfere with application-site's styles.
-       </li>
-      </ul>
-      <p>
-       Minified versions of the MKWS JavaScript files are also available:
-      <p>
-      <ul>
-       <li>
-          <a href="mkws.min.js">mkws.min.js</a>
-       </li>
-       <li>
-          <a href="mkws-complete.min.js">mkws-complete.min.js</a>
-       </li>
-      </ul>
-      <p>
-       (This domain also hosts two web-service endpoints that are used by
-       running MKWS-based applications:
-       <tt>/service-proxy-auth</tt>
-       is used to authenticate new sessions and
-       <code>/service-proxy/</code>
-       is the main endpoint for searching and retrieval. But there is
-       no need to use these directly: the widgets take care of that.)
-       </li>
-      </ul>
-    </div>
-
-    <div class="pane">
-      <h2>Versions</h2>
-      <p>
-       The links above to the various forms of the widget-set JavaScript
-        (<a href="mkws.js">mkws.js</a>,
-        <a href="mkws-complete.js">mkws-complete.js</a>,
-        <a href="mkws.min.js">mkws.min.js</a>
-       and
-        <a href="mkws-complete.min.js">mkws-complete.min.js</a>)
-       are always to the current versions of those
-       files. Applications that rely on a particular version can
-       instead use the specific numbered versions in
-       <a href="releases/">the releases area</a>,
-       for example
-       <a href="releases/mkws-0.9.1.js">releases/mkws-0.9.1.js</a>.
-      </p>
-      <p>
-       The current version number is always in
-       <a href="VERSION">the VERSION file</a>.
-      </p>
-      <p>
-       Version history is in
-       <a href="NEWS">the NEWS file</a>.
-      </p>
-    </div>
-
-    <div class="pane">
-      <h2>Examples using the widget-set</h2>
-      <p>
-        It's worth viewing the source of these to see how small they
-        are and how various things are done.
-      </p>
-      <h3>Simple examples</h3>
-      <ul>
-       <li>
-          A very simple application at
-          <a href="//example.indexdata.com/simple.html"
-             >//example.indexdata.com/simple.html</a>.
-       </li>
-       <li>
-          <a href="//example.indexdata.com/minimal.html"
-             >The absolutely minimal application</a>
-         listed above.
-       </li>
-       <li>
-          <a href="//example.indexdata.com/language.html"
-             >A more detailed version</a>
-         that contains a configuration structure instead of accepting
-          the defaults. Includes a custom translation option to present
-          the application in Arabic.
-       </li>
-       <li>
-          <a href="//example.indexdata.com/mobile.html"
-             >A version suitable for mobile devices</a>,
-         with a responsive design that moves components around
-          depending on the screen size.
-       </li>
-      </ul>
-
-      <h3>Advanced examples</h3>
-      <ul>
-       <li>
-         An application that
-         <a href="//example.indexdata.com/lowlevel.html"
-            >uses lower-level MKWS components</a>
-         rather than the all-in-one <tt>#mkwsResults</tt> division,
-         allowing it to use a rather different layout.
-       </li>
-       <li>
-         An application that specifies how to display brief and full records
-         <a href="//example.indexdata.com/templates.html"
-            >using Handlebar templates</a>.
-         (Read about
-         <a href="http://handlebarsjs.com/"
-            >the templating language</a>.)
-       </li>
-       <li>
-         An application that
-         <a href="http://example.indexdata.com/images.html?q=portrait"
-            >displays thumbnail images</a>.
-       </li>
-       <li>
-         <a href="//example.indexdata.com/localauth.html"
-            >An application that uses a local authentication regime</a>,
-         and the corresponding
-         <a href="//example.indexdata.com/apache-config.txt"
-            >Apache2 configuration stanza</a>.
-       </li>
-       <li>
-          <a href="//example.indexdata.com/popup.html"
-             >A version that uses a jQuery popup</a>.
-       </li>
-      </ul>
-
-      <h3>Non-standard interfaces</h3>
-      <ul>
-       <li>
-          <a href="//example.indexdata.com/dict.html"
-             >An application that uses MKWS to find dictionary
-            definitions of words when you highlight them</a>.
-       </li>
-       <li>
-          <a href="//example.indexdata.com/auto.html"
-             >An application that runs an automatic search on load</a>.
-       </li>
-       <li>
-          An existing web-site,
-          <a href="http://sagp.miketaylor.org.uk/"
-             >The Self-Appointed Grammar Police</a>,
-          which has been fitted with an MKWS searching widget.
-          (See also the MKWS-widget customisations in
-          <a href="http://sagp.miketaylor.org.uk/style.css"
-             >that site's stylesheet</a>.)
-       </li>
-<!--
-       <li>
-         Another existing web-site,
-          <a href="http://zthes.z3950.org/"
-             >The Zthes specifications</a>,
-         which has been fitted with a popup MKWS search-box.
-       </li>
--->
-      </ul>
-    </div>
-
-    <div class="pane">
-      <h2>Target selection</h2>
-      <p>
-       MKWS comes pre-configured to search in a set of a dozen or so
-        open-access targets, as a proof of concept. But you'll want
-        to use it to search your own selection of targets -- some open
-       access, some subscription.
-      </p>
-      <p>
-       We can set that up for you: email us on
-       <a href="mailto:info@indexdata.com"
-                      >info@indexdata.com</a>.
-      </p>
-    </div>
-
-    <p style="text-align: right; font-size: small">
-      Copyright (&copy;) 2013-2014 IndexData ApS.
-      <a href="http://indexdata.com"><code>http://indexdata.com</code></a>
-    </p>
-  </body>
-</html>
index c21ed17..db7bffa 100644 (file)
@@ -1,87 +1,87 @@
-.mkwsLang,
-.mkwsSwitch,
-.mkwsSearch,
-.mkwsTermlists,
-.mkwsFacet,
-.mkwsRanking,
-.mkwsPager,
-.mkwsNavi,
-.mkwsRecords,
-.mkwsRecord,
-.mkwsTargets,
-.mkwsStat,
-.mkwsMOTD {
+.mkwsLang, .mkws-lang,
+.mkwsSwitch, .mkws-switch,
+.mkwsSearch, .mkws-search,
+.mkwsTermlists, .mkws-termlists,
+.mkwsFacet, .mkws-facet,
+.mkwsRanking, .mkws-ranking,
+.mkwsPager, .mkws-pager,
+.mkwsNavi, .mkws-navi,
+.mkwsRecords, .mkws-records,
+.mkwsRecord, .mkws-record,
+.mkwsTargets, .mkws-targets,
+.mkwsStat, .mkws-stat,
+.mkwsMOTD, .mkws-motd {
     font-family: Gill Sans, "Gillius ADF", Gillius, GilliusADF, Verdana, Sans-Serif;
 }
 
-.mkwsLang {
+.mkwsLang, .mkws-lang {
     float: left;
     padding-left: 1em;
     padding-top: 0.4em;
 }
 
-.mkwsLang a {
+.mkwsLang a, .mkws-lang a {
     background: #d0e0ff;
     padding: 1px 4px;
 }
 
-.mkwsLang span {
+.mkwsLang span, .mkws-lang span {
     border: solid 1px #d0e0ff;
     padding: 0px 3px;
 }
 
-.mkwsSearch {
+.mkwsSearch, .mkws-search {
     float: right;
 }
 
-.mkwsSwitch {
+.mkwsSwitch, .mkws-switch {
     float: right;
     padding-left: 1em;
     padding-top: 0.4em;
 }
 
-.mkwsTargets {
+.mkwsTargets, .mkws-targets {
     background-color: #fafafa;
 }
 
-.mkwsStat {
+.mkwsStat, .mkws-stat {
     margin-top: 10px;
     border-top: 1px solid  #156a16;
     padding-top: 5px;
     font-size: small;
 }
 
-.mkwsStat:before {
+.mkwsStat:before, .mkws-stat:before {
     content: "Status info";
     font-weight: bold;
 }
 
-.mkwsSwitch a,
-.mkwsLang a,
-.mkwsFacet a,
-.mkwsRanking a,
-.mkwsPager a,
-.mkwsNavi a,
-.mkwsRecords a,
-.mkwsRecord a {
+.mkwsSwitch a, .mkws-switch a,
+.mkwsLang a, .mkws-lang a,
+.mkwsFacet a, .mkws-facet a,
+.mkwsRanking a, .mkws-ranking a,
+.mkwsPager a, .mkws-pager a,
+.mkwsNavi a, .mkws-navi a,
+.mkwsRecords a, .mkws-records a,
+.mkwsRecord a, .mkws-record a {
     color: #005701;
     text-decoration: none;
 }
 
-.mkwsSwitch a:hover,
-.mkwsLang a:hover,
-.mkwsFacet a:hover,
-.mkwsPager a:hover,
-.mkwsRecords a:hover,
-.mkwsRecord a:hover {
+.mkwsSwitch a:hover, .mkws-switch a:hover,
+.mkwsLang a:hover, .mkws-lang a:hover,
+.mkwsFacet a:hover, .mkws-facet a:hover,
+.mkwsPager a:hover, .mkws-pager a:hover,
+.mkwsRecords a:hover, .mkws-records a:hover,
+.mkwsRecord a:hover, .mkws-record a:hover {
     text-decoration: underline;
 }
 
-.mkwsNavi a.mkwsRemovable:hover {
+.mkwsNavi a.mkwsRemovable:hover, .mkws-navi a.mkws-removable:hover {
     text-decoration: line-through;
 }
 
-.mkwsSearch input.mkwsButton {
+.mkwsSearch input.mkwsButton, .mkws-search input.mkws-button {
     border: 3px outset #132194;
     background-color: #132194;
     padding: 2px;
     cursor: pointer;
 }
 
-.mkwsSearch input.mkwsQuery {
+.mkwsSearch input.mkwsQuery, .mkws-search input.mkws-query {
     border: 2px inset #e0f0ff;
     padding: 3px;
     font-size: 12px;
     background: #f0f8ff;
 }
 
-.mkwsTermlistsTitle {
+.mkwsTermlistsTitle, .mkws-termlists-title {
     font-size: large;
     font-weight: bold;
     text-transform: uppercase;
 }
 
-.mkwsTermlists {
+.mkwsTermlists, .mkws-termlists {
     background: #d0e0ff;
     padding: 0.7em;
     font-size: small;
+    display: none;
 
     border-top-right-radius: 10px;
     -moz-border-top-right-radius: 10px;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsFacet {
+.mkwsTermlists.active, .mkws-termlists.active {
+    display: block;
+}
+
+.mkwsFacet, .mkws-facet {
     background: #e0f0ff;
     padding: 0.7em;
     margin-top: 0.7em;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsTerm {
+.mkwsTerm, .mkws-term {
     clear: both;
 }
 
-.mkwsTerm span {
+.mkwsTerm span, .mkws-term span {
     float: right;
 }
 
-.mkwsFacetTitle {
+.mkwsFacetTitle, .mkws-facet-title {
     font-weight: bold;
 }
 
-.mkwsSummary {
+.mkwsSummary, .mkws-summary {
     padding: 5px;
 }
 
-.mkwsDetails {
+.mkwsDetails, .mkws-details {
     border: 1px solid #404040;
     background: #e8e8e8;
     color: black;
     -webkit-border-top-right-radius: 10px;
 }
 
-.mkwsDetails th {
+.mkwsDetails th, .mkws-details th {
     text-align: right;
     vertical-align: top;
     padding-right: 0.6em;
 }
 
-.mkwsDetails th:after {
+.mkwsDetails th:after, .mkws-details th:after {
     content: ":";
 }
 
-.mkwsPager {
+.mkwsPager, .mkws-pager {
     background: #e0e0e0;
     padding: 0.3em;
 }
 
-.mkwsTargets table thead tr td {
+.mkwsTargets table thead tr td, .mkws-targets table thead tr td {
     background-color: #132194;
     color: white;
     font-weight: bold;
     padding: 0.2em 0.5em;
 }
 
-.mkwsTargets table tbody tr:nth-child(odd) {
+.mkwsTargets table tbody tr:nth-child(odd), .mkws-targets table tbody tr:nth-child(odd) {
     background-color: #e0f0ff;
 }
 
-.mkwsTargets table tbody tr:nth-child(even) {
+.mkwsTargets table tbody tr:nth-child(even), .mkws-targets table tbody tr:nth-child(even) {
     background-color: #d0e0ff;
 }
 
-.mkwsTargets table tbody tr td {
+.mkwsTargets table tbody tr td, .mkws-targets table tbody tr td {
     padding: 0.2em 0.5em;
 }
 
-.mkwsCurrentPage {
+.mkwsCurrentPage, .mkws-current-page {
     padding: 0.1em 0.5em;
     background: #508751;
     color: white;
 }
 
-.mkwsProgress {
+.mkwsProgress, .mkws-progress {
     border: 1px solid #c0c0c0;
     float: left;
     margin-left: 2em;
     padding: 0 0.3em;
 }
 
-.mkwsProgress .mkwsDone { color: #005701 }
-.mkwsProgress .mkwsWaiting { color: #c0c0c0 }
+.mkwsProgress .mkwsDone, .mkws-progress .mkws-done { color: #005701 }
+.mkwsProgress .mkwsWaiting, .mkws-progress .mkws-waiting { color: #c0c0c0 }
 
-.mkwsResults table {
+.mkwsResults table, .mkws-results table {
   display: inline-table /* only for Firefox! */
 }
 
diff --git a/tools/htdocs/no-service-proxy.html b/tools/htdocs/no-service-proxy.html
new file mode 100644 (file)
index 0000000..b1a5f15
--- /dev/null
@@ -0,0 +1,3 @@
+There is no /service-proxy/ on mkws.indexdata.com.
+<p>
+You probably want to use http://sp-mkws.indexdata.com/service-proxy/
index d6bd517..264adb0 100644 (file)
@@ -1,4 +1,4 @@
-/*! Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/*! Copyright (c) 2013 Index Data ApS. http://indexdata.com
    created at: Thu Dec 19 15:38:43 GMT 2013
    mkws.js GIT id: 54b1dadf3e529bd323661138eaf255192706ef50
    pz2.js GIT id: fcae86df04ab28f83b889ca873275f68551928df
index ad30b98..0a2541c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013 IndexData ApS. http://indexdata.com
+/* Copyright (c) 2013 Index Data ApS. http://indexdata.com
    created at: Thu Dec 19 15:38:43 GMT 2013
    mkws.js GIT id: 54b1dadf3e529bd323661138eaf255192706ef50
    pz2.js GIT id: fcae86df04ab28f83b889ca873275f68551928df
index f94de5d..ed81295 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2014 IndexData ApS. http://indexdata.com
+# Copyright (c) 2014 Index Data ApS. http://indexdata.com
 
 User-agent: *
 Disallow: /service-proxy
diff --git a/tools/service-proxy/service-proxy-mike-mac.properties b/tools/service-proxy/service-proxy-mike-mac.properties
new file mode 100644 (file)
index 0000000..dca9044
--- /dev/null
@@ -0,0 +1,49 @@
+# Service Proxy configuration for MKWS (host sp-mkws.indexdata.com)
+# Initially based on MKC's configuration
+
+# Register plugin classes with custom names
+plugins.relay      = com.indexdata.serviceproxy.plugins.Pazpar2RelayPlugin
+plugins.authn      = com.indexdata.serviceproxy.plugins.AuthNTorusPlugin
+plugins.categories = com.indexdata.serviceproxy.plugins.TargetCategoriesPlugin
+plugins.ils        = com.indexdata.serviceproxy.plugins.ILSPlugin
+
+
+# Configuration properties for individual plug-ins 
+
+# relay plugin, proxies commands through to Pazpar2
+relay.PROXY_MODE = 3
+relay.PAZPAR2_URL = http://localhost:8004
+relay.PAZPAR2_SERVICE_ID = mkc
+relay.TORUS_BASEURL = http://x.mkc-admin.indexdata.com:8181/torus2/
+relay.TORUS_REALM = *
+relay.TORUS_PARAMS = ?param1=value1
+relay.STREAMBUFF_SIZE = 4096
+relay.PARSE_RESPONSES = true
+relay.CF_ENGINE_ADDRESS = localhost:9003
+
+# authn plugin, for torus based authentication 
+authn.TORUS_URL        = http://x.mkc-admin.indexdata.com:8181/torus2/identity.USERS/records/
+authn.MASTER_TORUS_URL = http://x.mkc-admin.indexdata.com:8181/torus2/admin.admin/records/
+authn.ACTION_SEQUENCE = check,login,referrer,constraint,ipauth
+authn.SPECIFIC_CONSTRAINT = hostName=${thisHost} 
+
+# categories plugin, for Torus-based target categories
+categories.TORUS_BASEURL            = http://x.mkc-admin.indexdata.com:8181/torus2/
+categories.TORUS_BASEURL_SEARCHABLE = http://x.mkc-admin.indexdata.com:8181/torus2/
+categories.EXCLUDE_EMPTY_CATEGORIES = true
+
+# ils plugin, for ILS operations such as holds and renewals
+ils.CFWS_URL = http://localhost:9003/connector
+
+
+# Map SP commands to command-separated sequences of plugins
+chains.auth = authn
+chains.categories = categories
+chains.ils = ils
+# Map all other commands to the Pazpar2 relayer
+chains.* = relay
+
+
+# Just so I can check that this particular SP config is in use
+chains.mike = info
+plugins.info = com.indexdata.serviceproxy.plugins.InfoPlugin
index 1c67a04..a3b92e4 100644 (file)
@@ -6,6 +6,7 @@ plugins.relay      = com.indexdata.serviceproxy.plugins.Pazpar2RelayPlugin
 plugins.authn      = com.indexdata.serviceproxy.plugins.AuthNTorusPlugin
 plugins.categories = com.indexdata.serviceproxy.plugins.TargetCategoriesPlugin
 plugins.ils        = com.indexdata.serviceproxy.plugins.ILSPlugin
+plugins.statistics = com.indexdata.serviceproxy.plugins.StatisticsPlugin
 
 
 # Configuration properties for individual plug-ins 
@@ -41,7 +42,7 @@ chains.auth = authn
 chains.categories = categories
 chains.ils = ils
 # Map all other commands to the Pazpar2 relayer
-chains.* = relay
+chains.* = relay,statistics
 
 
 # Just so I can check that this particular SP config is in use