diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..c0bb7e6b5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' + labels: + - 'gh actions dependencies' diff --git a/.github/workflows/docker-ci.yml b/.github/workflows/docker-ci.yml index cc386f981..a46ad5129 100644 --- a/.github/workflows/docker-ci.yml +++ b/.github/workflows/docker-ci.yml @@ -1,10 +1,10 @@ -name: Docker build PR +name: Build on: -# push: -# branches: [ main ] + push: + branches: [ develop ] pull_request: - types: [opened, edited, reopened] + types: [ opened, synchronize, reopened ] branches: [ develop, main ] env: @@ -13,26 +13,29 @@ env: jobs: build: - + name: Build Edirom Online runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Build Edirom Online from ${{ GITHUB_REF }} - run: docker run --rm -v `pwd`:/app -w /app --entrypoint ./build.sh bwbohl/sencha-cmd - - uses: actions/upload-artifact@v2 + - name: Chekout repository + uses: actions/checkout@v4 + + - name: Get short sha + uses: benjlevesque/short-sha@v2.2 + id: short-sha with: - name: EdiromOnline_${{ GITHUB_REF }}.zip - path: build-xar/EdiromOnline*.xar - if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` + length: 7 + + - name: Build Edirom Online from ${{ github.ref }} at ${{ github.sha }} + run: docker run --rm -v $(pwd):/app -w /app --entrypoint ./build.sh bwbohl/sencha-cmd -# deploy: -# needs: build -# runs-on: ubuntu-latest -# steps: -# - name: deploy -# uses: jaapio/keelsh-deploy@master -# with: -# keelBaseUrl: http://keel.euryanthe.de -# image: 'bazga/existdb' -# tag: 'latest' + - name: Upload Artifacts to action run + if: github.repository == 'Edirom/Edirom-Online' + uses: actions/upload-artifact@v4.3.0 + with: + # The name that the artifact will be made available under + name: EdiromOnline_${{ steps.short-sha.outputs.sha }}.zip + # The path to retrieve the artifact + path: ${{ github.workspace }}/build-xar/Edirom-Online-*.xar + if-no-files-found: warn # 'warn' or 'ignore' are also available, defaults to `warn` + #optional retention-days: 1 to 90 diff --git a/.gitignore b/.gitignore index d5b603f5d..ef633cde5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Thumbs.db /tmp *.xpr local.properties +.idea/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..183f8d0ae --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,89 @@ +# Edirom Online Contributing Guidelines + +# General Guidelines + +* do not combine code-linting and content work in one commit + +## Whitespace handling + +1. Use whitespaces, not tabs to indent code +2. Close file with a newline character + + +# XQuery + +## xqDoc + +We use [xqDoc](https://xqdoc.org) for documenting the XQueries in this repository. Please refer to the section [xqDoc Comments](https://xqdoc.org/xqdoc_comments_doc.html) of the xqDoc-website for details on formatting the documentation comment blocks. + +* XQuery modules must have a library module xqDoc comment preceding the module declaration. +* Function declarations must have a library module xqDoc function comment preceding the function. + +## XQuery document structure + +### XQuery version + +```xquery +xquery version 3.1; +``` + +### License Statement + +```xquery +(: +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. +:) +``` + +### File Header + +1. `declare namespace` statements + * sort alphabetically by prefix +2. `import module namespace` statements of registered modules + * sort alphabetically by prefix +3. `import module namespace` statements of custom modules + * sort alphabetically by prefix + * Always use relative URIs for `import module namespace` statements that import for modules not registered with eXist-db. + +### Declare variables + +* Use `declare variable` statements for all required external parameters + +### Function declarations + +* functions have to be preceded by an xqDoc comment + +### XQuery body + +* Strings: escape with U+00027 APOSTROPHE: `'` + + +# Javascript + +## AJAX calls + +The class `EdiromOnline.controller.AJAXController` provides a central method `doAJAXRequest` for performing AJAX requests. The method is provided globally as `window.doAJAXRequest`. + +`doAJAXRequest` takes the following arguments: + +* `url`: The URL of the requestet site or end point. +* `method`: The HTTP method like `PUT`, `GET`, `POST`. +* `params`: An object containing key-value-pairs of parameters for the request. +* `successFn`: A callback function which is called when the AJAX request was successfull. +* `retryNo`: The number of retries, if the requests fails. Standard is 2 retries. +* `async`: Defines the async parameter for AJAX calls. Default is 'true'. + +An example of using the function would be: + +```javascript +window.doAJAXRequest('data/xql/getAnnotationMeta.xql', + 'GET', + { + uri: uri, + lang: lang + }, + Ext.bind(function(response){ + view.setMeta(response.responseText); + }, this) +); +``` diff --git a/README.md b/README.md index 77131a87e..49a4b0d66 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build](https://github.com/Edirom/Edirom-Online/actions/workflows/docker-ci.yml/badge.svg?branch=develop&event=push)](https://github.com/Edirom/Edirom-Online/actions/workflows/docker-ci.yml) + # Edirom Online Edirom Online is a web application written in XQuery and JavaScript, and designed for deployment in [eXist-db](https://exist-db.org/). It is based on the work of the [_Edirom_-Project](https://edirom.de/edirom-projekt/) that originally was funded by the German Research Foundation (DFG). This software brings paperbased historio-critical editions of music texts to the web. diff --git a/add/controller.xql b/add/controller.xql index acedaa4d7..41ce373cd 100755 --- a/add/controller.xql +++ b/add/controller.xql @@ -1,5 +1,6 @@ -xquery version "1.0"; +xquery version "3.1"; +import module namespace edition="http://www.edirom.de/xquery/edition" at "data/xqm/edition.xqm"; import module namespace eutil = "http://www.edirom.de/xquery/util" at "data/xqm/util.xqm"; declare variable $exist:path external; @@ -20,12 +21,13 @@ return else if ($exist:path eq "/") then (: redirect root path to index.html :) - + else if ($exist:path eq "/index.html") then (: forward index.html to index.xql :) + diff --git a/add/data/locale/edirom-lang-de.xml b/add/data/locale/edirom-lang-de.xml index 21f3437ee..943934a3d 100644 --- a/add/data/locale/edirom-lang-de.xml +++ b/add/data/locale/edirom-lang-de.xml @@ -176,5 +176,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/add/data/locale/edirom-lang-en.xml b/add/data/locale/edirom-lang-en.xml index 8e39ac716..44d568e4a 100644 --- a/add/data/locale/edirom-lang-en.xml +++ b/add/data/locale/edirom-lang-en.xml @@ -176,5 +176,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/add/data/xql/getAnnotationInfos.xql b/add/data/xql/getAnnotationInfos.xql index a3dbe0f7d..4b5775baf 100644 --- a/add/data/xql/getAnnotationInfos.xql +++ b/add/data/xql/getAnnotationInfos.xql @@ -1,102 +1,85 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online 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. - - Edirom Online 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 Edirom Online. If not, see . - - ID: $Id: getAnnotationInfos.xql 1261 2012-02-28 15:50:45Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) - -import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -import module namespace annotation = "http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; - -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace xlink="http://www.w3.org/1999/xlink"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; +declare namespace request = "http://exist-db.org/xquery/request"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +import module namespace annotation = "http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; +declare option output:method "json"; +declare option output:media-type "application/json"; -declare variable $lang := request:get-parameter('lang', ''); +declare variable $uri := request:get-parameter('uri', ''); +declare variable $edition := request:get-parameter('edition', ''); +declare variable $edition_path := eutil:getPreference('edition_path', $edition); +(:~ + : Returns distinct list of catagories + :) declare function local:getDistinctCategories($annots as element()*) as xs:string* { - - let $oldCats := distinct-values($annots/mei:ptr[@type="categories"]/replace(@target, '#', '')) - let $newCats := distinct-values(for $annot in $annots return tokenize(replace(normalize-space($annot/@class),'#',''),' '))[contains(., 'annotation.category')] - - return distinct-values(($oldCats, $newCats)[string-length() gt 0]) + + let $oldCats := distinct-values($annots/mei:ptr[@type = "categories"]/replace(@target, '#', '')) + let $newCats := distinct-values(for $annot in $annots + return + tokenize(replace(normalize-space($annot/@class), '#', ''), ' '))[contains(., 'annotation.category')] + + return + distinct-values(($oldCats, $newCats)[string-length() gt 0]) }; +(:~ + : Returns distinct list of annotation priorities + :) declare function local:getDistinctPriorities($annots as element()*) as xs:string* { - - distinct-values( - for $annot in $annots - let $oldLink := $annot/mei:ptr[@type="priority"]/replace(@target, '#', '') - let $classes := tokenize(replace(normalize-space($annot/@class),'#',''),' ') - let $newLink := $classes[starts-with(.,'ediromAnnotPrio')] - return - distinct-values(($oldLink, $newLink))[string-length(.) gt 0] - ) + + distinct-values( + for $annot in $annots + let $oldLink := $annot/mei:ptr[@type = "priority"]/replace(@target, '#', '') + let $classes := tokenize(replace(normalize-space($annot/@class), '#', ''), ' ') + let $newLink := $classes[starts-with(., 'ediromAnnotPrio')] + return + distinct-values(($oldLink, $newLink))[string-length(.) gt 0] + ) }; -let $uri := request:get-parameter('uri', '') -let $edition := request:get-parameter('edition', '') let $mei := doc($uri)/root() -let $edition_path := eutil:getPreference('edition_path', $edition) let $annots := collection($edition_path)//mei:annot[matches(@plist, $uri)] | $mei//mei:annot - -let $categories := - for $category in local:getDistinctCategories($annots) - let $categoryElement := (collection($edition_path)/id($category)[mei:label or mei:name])[1] - let $name := annotation:category_getName($categoryElement, eutil:getLanguage($edition)) - order by $name - return map { - 'id': $category, - 'name': $name - } - -let $prios := - for $priority in local:getDistinctPriorities($annots) - let $name := annotation:getPriorityLabel((collection($edition_path)//id($priority)[mei:label or mei:name])[1]) - order by $name - return map { - 'id': $priority, - 'name': $name - } - -let $map := - map { - 'categories': array { $categories }, - 'priorities': array { $prios }, - 'count': count($annots) - } - -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } - -return serialize($map, $options) - -(: +let $categories := +for $category in local:getDistinctCategories($annots) +let $categoryElement := (collection($edition_path)/id($category)[mei:label or mei:name])[1] +let $name := annotation:category_getName($categoryElement, eutil:getLanguage($edition)) + order by $name +return + map { + 'id': $category, + 'name': $name + } + +let $prios := +for $priority in local:getDistinctPriorities($annots) +let $name := annotation:getPriorityLabel((collection($edition_path)//id($priority)[mei:label or mei:name])[1]) + order by $name +return + map { + 'id': $priority, + 'name': $name + } + +let $map := +map { + 'categories': array {$categories}, + 'priorities': array {$prios}, + 'count': count($annots) +} + +return + $map + + (: return concat('{categories: [', string-join( diff --git a/add/data/xql/getAnnotationPreviews.xql b/add/data/xql/getAnnotationPreviews.xql index 1d4992018..577b3e3ea 100644 --- a/add/data/xql/getAnnotationPreviews.xql +++ b/add/data/xql/getAnnotationPreviews.xql @@ -1,74 +1,58 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online 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. - - Edirom Online 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 Edirom Online. If not, see . - - ID: $Id: getAnnotationPreviews.xql 1455 2012-10-11 10:42:55Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) (:~ Returns the HTML for a specific annotation for an AnnotationView. - + @author Daniel Röwenstrunk @author Benjamin W. Bohl :) -import module namespace annotation="http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; -import module namespace source="http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; -import module namespace teitext="http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; -import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -import module namespace edition="http://www.edirom.de/xquery/edition" at "../xqm/edition.xqm"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; -declare namespace exist="http://exist.sourceforge.net/NS/exist"; -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace edirom_image="http://www.edirom.de/ns/image"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; +declare namespace request = "http://exist-db.org/xquery/request"; +declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; +import module namespace source = "http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; +import module namespace teitext = "http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +declare option output:method "json"; +declare option output:media-type "application/json"; declare variable $lang := request:get-parameter('lang', ''); -declare variable $imageWidth := 600; - declare variable $edition := request:get-parameter('edition', ''); -declare variable $imageserver := eutil:getPreference('image_server', $edition); -declare variable $imageBasePath := if($imageserver = 'leaflet') - then(eutil:getPreference('leaflet_prefix', $edition)) - else(eutil:getPreference('image_prefix', $edition)); +declare variable $imageserver := eutil:getPreference('image_server', $edition); +declare variable $uri := request:get-parameter('uri', ''); +declare variable $imageBasePath := if ($imageserver = 'leaflet') +then + (eutil:getPreference('leaflet_prefix', $edition)) +else + (eutil:getPreference('image_prefix', $edition)); declare function local:getParticipants($annot as element()) as map(*)* { - + let $participants := tokenize($annot/string(@plist), ' ') - let $docs := distinct-values(for $p in $participants return substring-before($p, '#')) + let $docs := distinct-values(for $p in $participants + return + substring-before($p, '#')) return for $doc in $docs - order by $doc + order by $doc return - if(source:isSource($doc)) - then(local:getSourceParticipants($participants[starts-with(., $doc)], $doc)) - - else if(teitext:isText($doc)) - then(local:getTextParticipants($participants[starts-with(., $doc)], $doc)) - - else() + if (source:isSource($doc)) + then + (local:getSourceParticipants($participants[starts-with(., $doc)], $doc)) + + else + if (teitext:isText($doc)) + then + (local:getTextParticipants($participants[starts-with(., $doc)], $doc)) + + else + () }; declare function local:getTextParticipants($participants as xs:string*, $doc as xs:string) as map(*)* { @@ -76,82 +60,95 @@ declare function local:getTextParticipants($participants as xs:string*, $doc as for $participant in $participants let $id := substring-after($participant, '#') let $hiddenData := concat('uri:', $doc, '__$$__participantId:', $id) - return map { - 'type': 'text', - 'label': 'Textstelle', - 'mdiv': '', - 'part': '', - 'page': '', - 'source': teitext:getLabel($doc, $edition), - 'siglum': '', - 'digilibBaseParams': '', - 'digilibSizeParams': '', - 'hiddenData': $hiddenData, - 'content': normalize-space(local:getTextNoteContent($doc, $id)), - 'linkUri': $participant - } + return + map { + 'type': 'text', + 'label': 'Textstelle', + 'mdiv': '', + 'part': '', + 'page': '', + 'source': teitext:getLabel($doc, $edition), + 'siglum': '', + 'digilibBaseParams': '', + 'digilibSizeParams': '', + 'hiddenData': $hiddenData, + 'content': normalize-space(local:getTextNoteContent($doc, $id)), + 'linkUri': $participant + } }; declare function local:getTextNoteContent($doc as xs:string, $id as xs:string) as xs:string { let $elem := doc($doc)/id($id) let $content := data($elem) return - if(string-length($content) gt 0) - then($content) - else(local:getTextNotePrecedingContent($elem)) + if (string-length($content) gt 0) + then + ($content) + else + (local:getTextNotePrecedingContent($elem)) }; declare function local:getTextNotePrecedingContent($elem as element()) as xs:string { let $preceding := $elem/preceding-sibling::*[1] let $content := data($preceding) return - if(string-length($content) gt 0) - then($content) - else(local:getTextNotePrecedingContent($preceding)) + if (string-length($content) gt 0) + then + ($content) + else + (local:getTextNotePrecedingContent($preceding)) }; declare function local:getSourceParticipants($participants as xs:string*, $doc as xs:string) as map(*)* { - + let $combs := local:groupParticipants($participants, $doc) - - return - + + return + for $comb in distinct-values($combs) - let $partIndices := tokenize($comb,'-') - - let $elems := - for $p in distinct-values($partIndices) - let $relevant.participant := $participants[starts-with(., $doc)][number($p)] - let $element.id := substring-after($relevant.participant,'#') - let $elem := local:getElement($relevant.participant) - (:return if(exists($elem)) then(local-name($elem)) else($relevant.participant):) + let $partIndices := tokenize($comb, '-') + + let $elems := + for $p in distinct-values($partIndices) + let $relevant.participant := $participants[starts-with(., $doc)][number($p)] + let $element.id := substring-after($relevant.participant, '#') + let $elem := local:getElement($relevant.participant) + (:return if(exists($elem)) then(local-name($elem)) else($relevant.participant):) where exists($elem) order by count($elem/preceding::*) - return $elem - - where count($elems) gt 0 - - let $zones := for $elem in $elems return local:getZone($elem) - + return + $elem + + where count($elems) gt 0 + + let $zones := for $elem in $elems + return + local:getZone($elem) + let $type := local:getType($zones) let $label := local:getItemLabel($elems) - - let $mdiv := ''(: TODO if($elem/ancestor-or-self::mei:mdiv) then($elem/ancestor-or-self::mei:mdiv/@label) else(''):) - let $page := if($zones[1]/parent::mei:surface/@label != '') then($zones[1]/parent::mei:surface/string(@label)) else($zones[1]/parent::mei:surface/string(@n)) + + let $mdiv := '' (: TODO if($elem/ancestor-or-self::mei:mdiv) then($elem/ancestor-or-self::mei:mdiv/@label) else(''):) + let $page := if ($zones[1]/parent::mei:surface/@label != '') then + ($zones[1]/parent::mei:surface/string(@label)) + else + ($zones[1]/parent::mei:surface/string(@n)) let $sourceLabel := source:getLabel($doc, $edition) let $siglum := ($elems[1]/root()//mei:*[@type eq 'siglum'])[1]/text() - - let $part := string-join(distinct-values(for $e in $elems return $e/ancestor::mei:part/string(@label)),'-') - + + let $part := string-join(distinct-values(for $e in $elems + return + $e/ancestor::mei:part/string(@label)), '-') + let $graphic := $zones[1]/../mei:graphic[@type = 'facsimile'] let $imgWidth := number($graphic/@width) let $imgHeight := number($graphic/@height) - + let $digilibBaseParams := local:getImageAreaPath($imageBasePath, $graphic) let $rect := local:getBoundingZone($zones) - + let $digilibSizeParams := local:getImageAreaParams($rect, $imgWidth, $imgHeight) - + let $hiddenData := map { 'width': number($rect/@lrx) - number($rect/@ulx), 'height': number($rect/@lry) - number($rect/@uly), @@ -160,86 +157,103 @@ declare function local:getSourceParticipants($participants as xs:string*, $doc a 'origH': $imgHeight, 'origW': $imgWidth } - + let $linkUri := concat('xmldb:exist://', document-uri($graphic/root()), '#', local:getSourceLinkTarget($elems, $zones)) - - return map { - 'type': $type, - 'label': $label, - 'mdiv': $mdiv, - 'part': $part, - 'page': $page, - 'source': $sourceLabel, - 'siglum': $siglum, - 'digilibBaseParams': $digilibBaseParams, - 'digilibSizeParams': $digilibSizeParams, - 'hiddenData': $hiddenData, - 'content': '', - 'linkUri': $linkUri - } + + return + map { + 'type': $type, + 'label': $label, + 'mdiv': $mdiv, + 'part': $part, + 'page': $page, + 'source': $sourceLabel, + 'siglum': $siglum, + 'digilibBaseParams': $digilibBaseParams, + 'digilibSizeParams': $digilibSizeParams, + 'hiddenData': $hiddenData, + 'content': '', + 'linkUri': $linkUri + } }; declare function local:getSourceLinkTarget($elems as node()*, $zones as node()*) as xs:string { - if(local-name($elems[1]) eq 'zone') - then($elems[1]/string(@xml:id)) - else if(count($elems) > 1) - then( - let $elemsSorted := for $elem in $elems - order by count($elem/preceding::*) - return $elem - return concat($elemsSorted[1]/@xml:id, '?tstamp2=', (count($elems) -1), 'm+0') - ) - else($elems[1]/string(@xml:id)) - + if (local-name($elems[1]) eq 'zone') + then + ($elems[1]/string(@xml:id)) + else + if (count($elems) > 1) + then + ( + let $elemsSorted := for $elem in $elems + order by count($elem/preceding::*) + return + $elem + return + concat($elemsSorted[1]/@xml:id, '?tstamp2=', (count($elems) - 1), 'm+0') + ) + else + ($elems[1]/string(@xml:id)) + }; declare function local:groupParticipants($participants as xs:string*, $doc as xs:string) as xs:string* { let $elems := for $p in $participants - let $id := substring-after($p, '#') - return doc($doc)/id($id) - + let $id := substring-after($p, '#') + return + doc($doc)/id($id) + let $zones := for $elem in $elems - return local:getZone($elem) - + return + local:getZone($elem) + let $combs := for $p at $i in $participants - return - local:getCombinations($elems, $zones, $i, count($zones)) - + return + local:getCombinations($elems, $zones, $i, count($zones)) + return reverse( - for $comb at $i in reverse($combs) - let $contained := for $n in (1 to count($combs) - $i) - return - if(contains($combs[$n], $comb)) - then(1) - else(0) - return - if(exists(index-of($contained, 1))) - then() - else($comb) + for $comb at $i in reverse($combs) + let $contained := for $n in (1 to count($combs) - $i) + return + if (contains($combs[$n], $comb)) + then + (1) + else + (0) + return + if (exists(index-of($contained, 1))) + then + () + else + ($comb) ) }; declare function local:getCombinations($elems as element()*, $zones as element()*, $i as xs:int, $total as xs:int) as xs:string { - + let $currentZone := $zones[$i] let $currentElem := $elems[$i] return - if(local-name($currentElem) eq 'measure' or local-name($currentElem) eq 'staff') - then( + if (local-name($currentElem) eq 'measure' or local-name($currentElem) eq 'staff') + then + ( string-join(( - string($i), - for $n in ($i + 1 to $total) - return - if((local-name($elems[$n]) eq 'measure' or local-name($elems[$n]) eq 'staff') and local:compareZones($currentZone, $zones[$n])) - then(local:getCombinations($elems, $zones, $n, $total)) - else() - ),'-') - ) - else( + string($i), + for $n in ($i + 1 to $total) + return + if ((local-name($elems[$n]) eq 'measure' or local-name($elems[$n]) eq 'staff') and local:compareZones($currentZone, $zones[$n])) + then + (local:getCombinations($elems, $zones, $n, $total)) + else + () + ), '-') + ) + else + ( string($i) - ) + ) }; declare function local:compareZones($zone1 as element(), $zone2 as element()) as xs:boolean { @@ -253,85 +267,105 @@ declare function local:compareZones($zone1 as element(), $zone2 as element()) as declare function local:getElement($uri as xs:string) as element()? { let $doc := substring-before($uri, '#') let $id := substring-after($uri, '#') - - return doc($doc)/id($id) + + return + doc($doc)/id($id) }; (: TODO: in Modul auslagern :) (:~ Gets the zone holding the graphical representation of an element - + @param $elem The element for which the graphical representation shall be found - + @return The zone element :) declare function local:getZone($elem as element()) as element()? { - if($elem/@facs) - then( + if ($elem/@facs) + then + ( let $zoneId := replace($elem/@facs, '^#', '') - return $elem/root()/id($zoneId) - ) - else( + return + $elem/root()/id($zoneId) + ) + else + ( $elem - ) + ) }; +(:~ + : Returns type of a zone + :) declare function local:getType($zones as element()*) as xs:string { $zones[1]/@type (: TODO: besser machen :) }; declare function local:getBoundingZone($zones as element()*) as element() { - + }; (: TODO: in Modul auslagern :) (:~ - + :) declare function local:getImageAreaPath($basePath as xs:string, $graphic as element()?) as xs:string { - + let $imagePath := string($graphic/@target) let $imgWidth := number($graphic/@width) let $imgHeight := number($graphic/@height) let $isAbsolute := starts-with($imagePath, 'http') - - let $fields := if($imageserver = 'leaflet')then(substring-before($imagePath, '.') )else() - + + let $fields := if ($imageserver = 'leaflet') then + (substring-before($imagePath, '.')) + else + () + return if ($isAbsolute) - then $imagePath + then + $imagePath else switch ($imageserver) - case 'leaflet' return concat($basePath,$fields) - case 'openseadragon' return concat($basePath,translate($imagePath, '/', '!')) - default return concat($basePath, $imagePath, '?') - + case 'leaflet' + return + concat($basePath, $fields) + case 'openseadragon' + return + concat($basePath, translate($imagePath, '/', '!')) + default return + concat($basePath, $imagePath, '?') + }; (: TODO: in Modul auslagern :) (:~ This function generates an image path for a specific zone on an image. Based on a path prefix and a width. - + @param $basePath The base path prefix for the image databse @param $zone The zone with coordiantes on the image @param $width The width the image should be loaded with - + @return A URL pointing to an image based as xs:string :) declare function local:getImageAreaParams($zone as element()?, $imgWidth as xs:int, $imgHeight as xs:int) as xs:string { let $graphic := $zone/../mei:graphic[@type = 'facsimile'] - + let $imgX := number($zone/@ulx) let $imgY := number($zone/@uly) let $w := number($zone/@lrx) - number($zone/@ulx) let $h := number($zone/@lry) - number($zone/@uly) - + let $wx := $imgX div $imgWidth let $wy := $imgY div $imgHeight let $ww := $w div $imgWidth let $wh := $h div $imgHeight - + return concat('&amp;wx=', $wx, '&amp;wy=', $wy, '&amp;ww=', $ww, '&amp;wh=', $wh, '&amp;mo=fit') }; @@ -339,50 +373,78 @@ declare function local:getImageAreaParams($zone as element()?, $imgWidth as xs:i declare function local:getItemLabel($elems as element()*) as xs:string { let $language := eutil:getLanguage($edition) return - string-join( - for $type in distinct-values(for $elem in $elems return local-name($elem)) - let $items := for $elem in $elems return if(local-name($elem) eq $type) then($elem) else() - let $itemLabelMultiRestSensitive := if($items[1]//mei:multiRest) - then ($items[1]/@n || '–' || number($items[1]/@n) + number($items[1]//mei:multiRest/@num) - 1) - else ($items[1]/@n) - return - if(local-name($items[1]) eq 'measure') - then( - if(count($items) gt 1) - then(eutil:getLanguageString('Bars_from_to', ($items[1]/@n, $items[last()]/@n), $language)) - else(eutil:getLanguageString('Bar_n', $itemLabelMultiRestSensitive, $language)) - ) - else if(local-name($items[1]) eq 'staff') - (: TODO: $itemLabelMultiRestSensitive also for staffs? :) - then( - if(count($items) gt 1) - then( - - let $measureNs := distinct-values($items/ancestor::mei:measure/@n) - - let $label := if ($lang = 'de') - then (if(count($measureNs) gt 1) then (concat('Takte ',$measureNs[1], '-', $measureNs[last()])) else (concat('Takt ', $measureNs[1]))) - else (if(count($measureNs) gt 1) then (concat('Bars ',$measureNs[1], '-', $measureNs[last()])) else (concat('Bar ', $measureNs[1]))) - - return - - concat($label, ' (', string-join($items/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr,', '),')') - + string-join( + for $type in distinct-values(for $elem in $elems + return + local-name($elem)) + let $items := for $elem in $elems + return + if (local-name($elem) eq $type) then + ($elem) + else + () + let $itemLabelMultiRestSensitive := if ($items[1]//mei:multiRest) + then + ($items[1]/@n || '–' || number($items[1]/@n) + number($items[1]//mei:multiRest/@num) - 1) + else + ($items[1]/@n) + return + if (local-name($items[1]) eq 'measure') + then + ( + if (count($items) gt 1) + then + (eutil:getLanguageString('Bars_from_to', ($items[1]/@n, $items[last()]/@n), $language)) + else + (eutil:getLanguageString('Bar_n', $itemLabelMultiRestSensitive, $language)) ) - else(concat('Takt ',$items[1]/ancestor::mei:measure/@n, ' (', $items[1]/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr,')')) - ) - else if(local-name($items[1]) eq 'zone') - then( - if(count($items) gt 1) - then((:Dieser Fall sollte nicht vorkommen, da freie zones nicht zusammengefasst werden dürfen:)) - else(concat('Ausschnitt (S. ',$items[1]/parent::mei:surface/@n,')')) - ) - else() - ,' ') - + else + if (local-name($items[1]) eq 'staff') + (: TODO: $itemLabelMultiRestSensitive also for staffs? :) + then + ( + if (count($items) gt 1) + then + ( + + let $measureNs := distinct-values($items/ancestor::mei:measure/@n) + + let $label := if ($lang = 'de') + then + (if (count($measureNs) gt 1) then + (concat('Takte ', $measureNs[1], '-', $measureNs[last()])) + else + (concat('Takt ', $measureNs[1]))) + else + (if (count($measureNs) gt 1) then + (concat('Bars ', $measureNs[1], '-', $measureNs[last()])) + else + (concat('Bar ', $measureNs[1]))) + + return + + concat($label, ' (', string-join($items/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr, ', '), ')') + + ) + else + (concat('Takt ', $items[1]/ancestor::mei:measure/@n, ' (', $items[1]/preceding::mei:staffDef[@n = $items[1]/@n][1]/@label.abbr, ')')) + ) + else + if (local-name($items[1]) eq 'zone') + then + ( + if (count($items) gt 1) + then + ((:Dieser Fall sollte nicht vorkommen, da freie zones nicht zusammengefasst werden dürfen:) ) + else + (concat('Ausschnitt (S. ', $items[1]/parent::mei:surface/@n, ')')) + ) + else + () + , ' ') + }; -let $uri := request:get-parameter('uri', '') let $docUri := substring-before($uri, '#') let $internalId := substring-after($uri, '#') let $doc := doc($docUri) @@ -390,13 +452,8 @@ let $annot := $doc/id($internalId) let $map := map { 'success': true(), - 'participants': array { local:getParticipants($annot)} + 'participants': array {local:getParticipants($annot)} } -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } - -return serialize($map, $options) +return + $map diff --git a/add/data/xql/getAnnotationsInRendering.xql b/add/data/xql/getAnnotationsInRendering.xql index 75d9127af..78d744e85 100644 --- a/add/data/xql/getAnnotationsInRendering.xql +++ b/add/data/xql/getAnnotationsInRendering.xql @@ -26,7 +26,7 @@ xquery version "3.0"; @author Daniel Röwenstrunk :) -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; diff --git a/add/data/xql/getAnnotationsOnPage.xql b/add/data/xql/getAnnotationsOnPage.xql index 18a4c2fe5..0dbba5837 100644 --- a/add/data/xql/getAnnotationsOnPage.xql +++ b/add/data/xql/getAnnotationsOnPage.xql @@ -27,7 +27,7 @@ xquery version "3.1"; : @author Benjamin W. Bohl :) -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; diff --git a/add/data/xql/getInternalIdType.xql b/add/data/xql/getInternalIdType.xql index 64d185c0c..43cd7314b 100644 --- a/add/data/xql/getInternalIdType.xql +++ b/add/data/xql/getInternalIdType.xql @@ -23,7 +23,7 @@ xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; declare namespace mei="http://www.music-encoding.org/ns/mei"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; diff --git a/add/data/xql/getLinkTarget.xql b/add/data/xql/getLinkTarget.xql index 84e516561..86dcbca9a 100644 --- a/add/data/xql/getLinkTarget.xql +++ b/add/data/xql/getLinkTarget.xql @@ -1,190 +1,266 @@ xquery version "3.1"; (: - Edirom Online - Copyright (C) 2011 The Edirom Project - http://www.edirom.de - - Edirom Online 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. - - Edirom Online 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 Edirom Online. If not, see . - - ID: $Id: getLinkTarget.xql 1334 2012-06-14 12:40:33Z daniel $ +For LICENSE-Details please refer to the LICENSE file in the root directory of this repository. :) -import module namespace source="http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; -import module namespace work="http://www.edirom.de/xquery/work" at "../xqm/work.xqm"; -import module namespace teitext="http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; -import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; - -declare namespace request="http://exist-db.org/xquery/request"; -declare namespace mei="http://www.music-encoding.org/ns/mei"; -declare namespace tei="http://www.tei-c.org/ns/1.0"; -declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -declare namespace html="http://www.w3.org/1999/xhtml"; +declare namespace html = "http://www.w3.org/1999/xhtml"; +declare namespace map = "http://www.w3.org/2005/xpath-functions/map"; +declare namespace mei = "http://www.music-encoding.org/ns/mei"; declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; -declare namespace map="http://www.w3.org/2005/xpath-functions/map"; -declare namespace f="http://local.link"; +declare namespace tei = "http://www.tei-c.org/ns/1.0"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; +import module namespace request = "http://exist-db.org/xquery/request"; +import module namespace xmldb = "http://exist-db.org/xquery/xmldb"; -declare option output:method "text"; -declare option output:media-type "text/plain"; +import module namespace eutil = "http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; +import module namespace source = "http://www.edirom.de/xquery/source" at "../xqm/source.xqm"; +import module namespace teitext = "http://www.edirom.de/xquery/teitext" at "../xqm/teitext.xqm"; +import module namespace work = "http://www.edirom.de/xquery/work" at "../xqm/work.xqm"; + +declare option output:method "json"; +declare option output:media-type "application/json"; declare variable $lang := request:get-parameter('lang', ''); +declare variable $uri := request:get-parameter('uri', ''); +(:~ + : Returns a view for an edirom object + :) declare function local:getView($type as xs:string, $docUri as xs:string, $doc as node()+) as map(*)? { let $baseMap := map { - 'type': substring-after($type,'_'), - 'uri': if($type = ('mei_textView', 'desc_xmlView')) then string(($doc//mei:annot[@type='descLink'])[1]/@plist) else $docUri + 'type': substring-after($type, '_'), + 'uri': if ($type = ('mei_textView', 'desc_xmlView')) then + string(($doc//mei:annot[@type = 'descLink'])[1]/@plist) + else + $docUri } (: optionally set label for some views:) let $labeled.map := - if($type = 'mei_textView') - then(map:put($baseMap, 'label', 'Quellenbeschreibung')) - else if($type = 'desc_xmlView') - then(map:put($baseMap, 'label', 'XML Quellenbeschreibung')) - else($baseMap) - - (: whether to set the view as default view:) - let $defaultViewed.map := - if($type = ('mei_sourceView', - 'mei_audioView', - 'tei_textView', - 'tei_facsimileView', - 'tei_textFacsimileSplitView', - 'mei_annotationView', - 'mei_verovioView')) - then(map:put($labeled.map, 'defaultView', true())) - else($labeled.map) + if ($type = 'mei_textView') + then + (map:put($baseMap, 'label', 'Quellenbeschreibung')) + else + if ($type = 'desc_xmlView') + then + (map:put($baseMap, 'label', 'XML Quellenbeschreibung')) + else + ($baseMap) + + (: whether to set the view as default view:) + let $defaultViewed.map := + if ($type = ('mei_sourceView', + 'mei_audioView', + 'tei_textView', + 'tei_facsimileView', + 'tei_textFacsimileSplitView', + 'mei_annotationView', + 'mei_verovioView')) + then + (map:put($labeled.map, 'defaultView', true())) + else + ($labeled.map) - (: xpath check whether any given view is supported :) + (: xpath check whether any given view is supported :) let $hasView := - if($type = 'desc_summaryView') - then(true()) - - else if($type = 'desc_headerView') - then(exists($doc//mei:meiHead or $doc//tei:teiHeader)) - - else if($type = 'mei_textView') - then(exists($doc//mei:annot[@type='descLink'])) - - else if($type = 'mei_sourceView') - then(exists($doc//mei:facsimile//mei:graphic[@type='facsimile'])) - - else if($type = 'mei_audioView') - then(exists($doc//mei:recording)) - - else if($type = 'mei_verovioView') - then(exists($doc//mei:body//mei:measure) and exists($doc//mei:body//mei:note)) - - else if($type = 'tei_textView') - then(exists($doc//tei:body[matches(.//text(), '[^\s]+')])) - - else if($type = 'tei_facsimileView') - then(exists($doc//tei:facsimile//tei:graphic)) - - else if($type = 'tei_textFacsimileSplitView') - then(exists($doc//tei:facsimile//tei:graphic) and exists($doc//tei:pb[@facs])) - - else if($type = 'mei_annotationView') - then(exists($doc//mei:annot[@type='editorialComment'])) - - else if($type = 'xml_xmlView') - then(true()) - - else if($type = 'desc_xmlView') - then(exists($doc//mei:annot[@type='descLink'])) + if ($type = 'desc_summaryView') + then + (true()) + + else + if ($type = 'desc_headerView') + then + (exists($doc//mei:meiHead or $doc//tei:teiHeader)) - else(false()) + else + if ($type = 'mei_textView') + then + (exists($doc//mei:annot[@type = 'descLink'])) + + else + if ($type = 'mei_sourceView') + then + (exists($doc//mei:facsimile//mei:graphic[@type = 'facsimile'])) + + else + if ($type = 'mei_audioView') + then + (exists($doc//mei:recording)) + + else + if ($type = 'mei_verovioView') + then + (exists($doc//mei:body//mei:measure) and exists($doc//mei:body//mei:note)) + + else + if ($type = 'tei_textView') + then + (exists($doc//tei:body[matches(.//text(), '[^\s]+')])) + + else + if ($type = 'tei_facsimileView') + then + (exists($doc//tei:facsimile//tei:graphic)) + + else + if ($type = 'tei_textFacsimileSplitView') + then + (exists($doc//tei:facsimile//tei:graphic) and exists($doc//tei:pb[@facs])) + + else + if ($type = 'mei_annotationView') + then + (exists($doc//mei:annot[@type = 'editorialComment'])) + + else + if ($type = 'xml_xmlView') + then + (true()) + + else + if ($type = 'desc_xmlView') + then + (exists($doc//mei:annot[@type = 'descLink'])) + + else + (false()) return - if($hasView) - then($defaultViewed.map) - else() + if ($hasView) + then + ($defaultViewed.map) + else + () }; +(:~ + : Returns the views for an edirom object + :) declare function local:getViews($type as xs:string, $docUri as xs:string, $doc as node()+) as map(*)* { let $views := ( - (:'desc_summaryView',:) - (:'desc_headerView',:) - 'mei_textView', - 'mei_sourceView', - 'mei_audioView', - 'mei_verovioView', - 'tei_textView', - 'tei_facsimileView', - 'tei_textFacsimileSplitView', - 'mei_annotationView', - 'xml_xmlView', - 'desc_xmlView' + (:'desc_summaryView',:) + (:'desc_headerView',:) + 'mei_textView', + 'mei_sourceView', + 'mei_audioView', + 'mei_verovioView', + 'tei_textView', + 'tei_facsimileView', + 'tei_textFacsimileSplitView', + 'mei_annotationView', + 'xml_xmlView', + 'desc_xmlView' ) let $maps := - for $view in $views - return local:getView($view, $docUri, $doc) - - return $maps + for $view in $views + return + local:getView($view, $docUri, $doc) + + return + $maps }; +(:~ + : Returns the window title for an edirom-object + :) declare function local:getWindowTitle($doc as node()+, $type as xs:string) as xs:string { - (: Work :) - if(exists($doc//mei:mei) and exists($doc//mei:workDesc/mei:work) and not(exists($doc//mei:perfMedium))) - then(eutil:getLocalizedTitle(($doc//mei:work)[1]/mei:titleStmt[1], $lang)) - - (: Recording :) - else if(exists($doc//mei:mei) and exists($doc//mei:recording)) - then(eutil:getLocalizedTitle($doc//mei:fileDesc/mei:titleStmt[1], $lang)) - - (: Source / Score :) - else if($type = 'source' and exists($doc//mei:manifestation/mei:titleStmt)) - then(string-join((eutil:getLocalizedTitle(($doc//mei:manifestation)[1]/mei:titleStmt[1], $lang), - ($doc//mei:manifestation)[1]//mei:identifier[lower-case(@type)='shelfmark'][1]), ' | ') - => normalize-space()) - else if($type = 'source' and exists($doc//mei:source/mei:titleStmt)) - then(string-join((eutil:getLocalizedTitle(($doc//mei:source)[1]/mei:titleStmt[1], $lang), - ($doc//mei:source)[1]//mei:identifier[lower-case(@type)='shelfmark'][1]), ' | ') - => normalize-space()) - - (: MEI fallback if no title is found :) - else if(exists($doc//mei:mei) and exists(($doc//mei:titleStmt)[1])) - then(eutil:getLocalizedTitle(($doc//mei:titleStmt)[1], $lang)) - - (: Text :) - else if(exists($doc/tei:TEI)) - then(eutil:getLocalizedTitle($doc//tei:fileDesc/tei:titleStmt[1], $lang)) - - (: HTML :) - else if($type = 'html') - then($doc//head/data(title)) - - else(string('unknown')) + (: Work :) + if (exists($doc//mei:mei) and exists($doc//mei:workDesc/mei:work) and not(exists($doc//mei:perfMedium))) + then + (eutil:getLocalizedTitle(($doc//mei:work)[1]/mei:titleStmt[1], $lang)) + else + if (exists($doc/root()/mei:work)) + then + (eutil:getLocalizedTitle($doc/root()/mei:work, $lang)) + + (: Recording :) + else + if (exists($doc//mei:mei) and exists($doc//mei:recording)) + then + (eutil:getLocalizedTitle($doc//mei:fileDesc/mei:titleStmt[1], $lang)) + + (: Source / Score :) + else + if ($type = 'source' and exists($doc//mei:manifestation/mei:titleStmt)) + then + (string-join((eutil:getLocalizedTitle(($doc//mei:manifestation)[1]/mei:titleStmt[1], $lang), + ($doc//mei:manifestation)[1]//mei:identifier[lower-case(@type) = 'shelfmark'][1]), ' | ') + => normalize-space()) + else + if ($type = 'source' and exists($doc//mei:source/mei:titleStmt)) + then + (string-join((eutil:getLocalizedTitle(($doc//mei:source)[1]/mei:titleStmt[1], $lang), + ($doc//mei:source)[1]//mei:identifier[lower-case(@type) = 'shelfmark'][1]), ' | ') + => normalize-space()) + + (: MEI fallback if no title is found :) + else + if (exists($doc//mei:mei) and exists(($doc//mei:titleStmt)[1])) + then + (eutil:getLocalizedTitle(($doc//mei:titleStmt)[1], $lang)) + + (: Text :) + else + if (exists($doc/tei:TEI)) + then + (eutil:getLocalizedTitle($doc//tei:fileDesc/tei:titleStmt[1], $lang)) + + (: HTML :) + else + if ($type = 'html') + then + ($doc//head/data(title)) + + else + (string('unknown')) }; -let $uri := request:get-parameter('uri', '') -let $uriParams := if(contains($uri, '?')) then(substring-after($uri, '?')) else('') -let $uri := if(contains($uri, '?')) then(replace($uri, '[?&](term|path)=[^&]*', '')) else($uri) -let $docUri := if(contains($uri, '#')) then(substring-before($uri, '#')) else($uri) -let $internalId := if(contains($uri, '#')) then(substring-after($uri, '#')) else() -let $internalIdParam := if(contains($internalId, '?')) then(concat('?', substring-after($internalId, '?'))) else('') -let $internalId := if(contains($internalId, '?')) then(substring-before($internalId, '?')) else($internalId) +let $uriParams := if (contains($uri, '?')) then + (substring-after($uri, '?')) +else + ('') +let $uri := if (contains($uri, '?')) then + (replace($uri, '[?&](term|path)=[^&]*', '')) +else + ($uri) +let $docUri := if (contains($uri, '#')) then + (substring-before($uri, '#')) +else + ($uri) +let $internalId := if (contains($uri, '#')) then + (substring-after($uri, '#')) +else + () +let $internalIdParam := if (contains($internalId, '?')) then + (concat('?', substring-after($internalId, '?'))) +else + ('') +let $internalId := if (contains($internalId, '?')) then + (substring-before($internalId, '?')) +else + ($internalId) -let $term := if(contains($uriParams, 'term='))then(substring-after($uriParams, 'term='))else() -let $term := if(contains($term, '&'))then(substring-before($term, '&'))else($term) +let $term := if (contains($uriParams, 'term=')) then + (substring-after($uriParams, 'term=')) +else + () +let $term := if (contains($term, '&')) then + (substring-before($term, '&')) +else + ($term) -let $path := if(contains($uriParams, 'path='))then(substring-after($uriParams, 'path='))else() -let $path := if(contains($path, '&'))then(substring-before($path, '&'))else($path) +let $path := if (contains($uriParams, 'path=')) then + (substring-after($uriParams, 'path=')) +else + () +let $path := if (contains($path, '&')) then + (substring-before($path, '&')) +else + ($path) let $doc := eutil:getDoc($docUri) let $internal := $doc/id($internalId) @@ -193,65 +269,78 @@ let $edition := request:get-parameter('edition', '') (: Specific handling of virtual measure IDs for parts in OPERA project :) let $internal := - if(exists($internal)) - then($internal) - else( - if(starts-with($internalId, 'measure_') and $doc//mei:parts) - then( - - let $mdivId := functx:substring-before-last(substring-after($internalId, 'measure_'), '_') - let $measureN := functx:substring-after-last($internalId, '_') - return - ($doc/id($mdivId)//mei:measure[@n eq $measureN])[1] +if (exists($internal)) +then + ($internal) +else + ( + if (starts-with($internalId, 'measure_') and $doc//mei:parts) + then + ( + + let $mdivId := functx:substring-before-last(substring-after($internalId, 'measure_'), '_') + let $measureN := functx:substring-after-last($internalId, '_') + return + ($doc/id($mdivId)//mei:measure[@n eq $measureN])[1] ) - else($internal) + else + ($internal) ) let $type := (: Work :) - if(exists($doc//mei:mei) and exists($doc//mei:work) and not(exists($doc//mei:perfMedium))) - then(string('work')) - - (: Recording :) - else if(exists($doc//mei:mei) and exists($doc//mei:recording)) - then(string('recording')) - - (: Source / Score :) - else if(source:isSource($docUri)) - then(string('source')) - - (: Text :) - else if(exists($doc/tei:TEI)) - then(string('text')) - - (: HTML :) - else if(exists($doc/html) or exists($doc/html:html)) - then(string('html')) - - else if(contains($docUri, '.html')) - then(string('html')) - - else(string('unknown')) - -let $internalIdType := if(exists($internal)) - then(local-name($internal)) - else('unknown') +if (exists($doc//mei:mei) and exists($doc//mei:work) and not(exists($doc//mei:perfMedium))) +then + (string('work')) + + (: Recording :) +else + if (exists($doc//mei:mei) and exists($doc//mei:recording)) + then + (string('recording')) + + (: Source / Score :) + else + if (source:isSource($docUri)) + then + (string('source')) + + (: Text :) + else + if (exists($doc/tei:TEI)) + then + (string('text')) + + (: HTML :) + else + if (exists($doc/html) or exists($doc/html:html)) + then + (string('html')) + + else + if (contains($docUri, '.html')) + then + (string('html')) + + else + (string('unknown')) -let $map := - map { - 'type': $type, - 'title': local:getWindowTitle($doc, $type), - 'doc': $docUri, - 'views': array {local:getViews($type, $docUri, $doc)}, - 'internalId': $internalId || $internalIdParam, - 'term': $term, - 'path': $path, - 'internalIdType': $internalIdType - } +let $internalIdType := if (exists($internal)) +then + (local-name($internal)) +else + ('unknown') -let $options := - map { - 'method': 'json', - 'media-type': 'text/plain' - } +let $map := +map { + 'type': $type, + 'title': local:getWindowTitle($doc, $type), + 'doc': $docUri, + 'views': array {local:getViews($type, $docUri, $doc)}, + 'internalId': $internalId || $internalIdParam, + 'term': $term, + 'path': $path, + 'internalIdType': $internalIdType +} -return serialize($map, $options) +return + $map diff --git a/add/data/xql/getMeasure.xql b/add/data/xql/getMeasure.xql index ffca1c8e6..99e592b6f 100644 --- a/add/data/xql/getMeasure.xql +++ b/add/data/xql/getMeasure.xql @@ -26,7 +26,7 @@ declare namespace xlink="http://www.w3.org/1999/xlink"; declare namespace xmldb="http://exist-db.org/xquery/xmldb"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; diff --git a/add/data/xql/getParts.xql b/add/data/xql/getParts.xql index 6cf9572b1..4b041881f 100644 --- a/add/data/xql/getParts.xql +++ b/add/data/xql/getParts.xql @@ -1,4 +1,4 @@ -xquery version "1.0"; +xquery version "3.1"; (: Edirom Online Copyright (C) 2011 The Edirom Project @@ -21,15 +21,23 @@ xquery version "1.0"; declare namespace request="http://exist-db.org/xquery/request"; declare namespace mei="http://www.music-encoding.org/ns/mei"; - declare namespace xmldb="http://exist-db.org/xquery/xmldb"; +import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util.xqm"; + declare option exist:serialize "method=text media-type=text/plain omit-xml-declaration=yes"; let $uri := request:get-parameter('uri', '') let $mei := doc($uri)/root() let $ret := for $part in ($mei//mei:instrumentation/mei:instrVoice | $mei//mei:perfMedium//mei:perfRes) - return concat('{label: "', $part/@label, '", id:"', $part/@xml:id, '", selectedByDefault:true, selected:true}') + let $hasNoAttrSameas := not(exists($part/@sameas)) + return + concat( + '{label: "', eutil:getPartLabel($part, 'perfRes'), + '", id:"', $part/@xml:id, + '", selectedByDefault:', $hasNoAttrSameas, + ', selected:', $hasNoAttrSameas, '}' + ) return concat('[', string-join($ret, ','), ']') \ No newline at end of file diff --git a/add/data/xql/getText.xql b/add/data/xql/getText.xql index b8be575e7..781b5d382 100644 --- a/add/data/xql/getText.xql +++ b/add/data/xql/getText.xql @@ -92,5 +92,5 @@ let $body := $doc//xhtml:body return element div { for $attribute in $body/@* return $attribute, - for $node in $body/node() return $node - } \ No newline at end of file + for $node in $body/node() return $node + } diff --git a/add/data/xqm/annotation.xqm b/add/data/xqm/annotation.xqm index 4123ceb50..7d70812f5 100644 --- a/add/data/xqm/annotation.xqm +++ b/add/data/xqm/annotation.xqm @@ -80,26 +80,28 @@ declare function annotation:toJSON($anno as element(), $edition as xs:string) as let $id := $anno/string(@xml:id) let $lang := request:get-parameter('lang', '') let $genericTitle := eutil:getLocalizedTitle($anno, $lang) - let $title := + let $title := if(exists($genericTitle) and string-length($genericTitle) gt 0) then($genericTitle) else(annotation:generateTitle($anno)) let $doc := $anno/root() let $prio := annotation:getPriorityLabel($anno) let $pList.raw := distinct-values(tokenize(normalize-space($anno/@plist), ' ')) - let $pList := for $p in $pList.raw + let $pList := for $p in $pList.raw return if ( contains($p, '#')) then (substring-before($p, '#')) else $p - let $sigla := + let $sigla := for $p in distinct-values($pList) - let $pDoc := + let $pDoc := if(doc-available($p)) then(doc($p)) else(collection(eutil:getPreference('edition_path', $edition))//id($p)/root()) - return + return if ($pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']) - then $pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']/text() + then ($pDoc//mei:sourceDesc/mei:source/mei:identifier[@type = 'siglum']/text()) + else if ($pDoc//mei:manifestationList/mei:manifestation/mei:identifier[@type = 'siglum']) + then ($pDoc//mei:manifestationList/mei:manifestation/mei:identifier[@type = 'siglum']/text()) else ($pDoc//mei:title[@type = 'siglum']/text()) let $classes := tokenize(replace(normalize-space($anno/@class),'#',''),' ') @@ -107,7 +109,7 @@ declare function annotation:toJSON($anno as element(), $edition as xs:string) as let $cats := string-join( for $u in $catURIs - return annotation:category_getName($doc/id($u), eutil:getLanguage($edition)) + return annotation:category_getName($doc/id($u), eutil:getLanguage($edition)) , ', ') let $count := count($anno/preceding::mei:annot[@type = 'editorialComment']) + 1 @@ -156,7 +158,7 @@ declare function annotation:getContent($anno as element(), $idPrefix as xs:strin let $p := $anno/mei:p[not(@xml:lang) or @xml:lang = $language] let $html := transform:transform($p,concat($xsltBase,'meiP2html.xsl'),) - return + return $html }; @@ -216,7 +218,7 @@ declare function annotation:getPriorityLabel($anno) as xs:string* { let $labels := for $uri in $classBasedUri - let $doc := + let $doc := if(starts-with($uri,'#')) then($anno/root()) else(doc(substring-before($uri,'#'))) @@ -253,14 +255,14 @@ declare function annotation:getCategoriesAsArray($anno as element()) as xs:strin let $classes := tokenize(replace(normalize-space($anno/@class),'#',''),' ') let $catURIs := distinct-values((tokenize(replace($anno/mei:ptr[@type = 'categories']/@target,'#',''),' '), $classes[contains(.,'annotation.category.')])) - let $cats := + let $cats := for $u in $catURIs - return annotation:category_getName($doc/id($u),'') + return annotation:category_getName($doc/id($u),'') (:let $uris := tokenize($anno/mei:ptr[@type eq 'categories']/string(@target),' ') - let $string := for $uri in $uris + let $string := for $uri in $uris let $doc := if(starts-with($uri,'#')) then($anno/root()) else(doc(substring-before($uri,'#'))) @@ -301,4 +303,4 @@ declare function annotation:category_getName($category as element(), $language a switch (count($names[@xml:lang = $language])) case 1 return $names[@xml:lang = $language] default return $names[1]:) -}; \ No newline at end of file +}; diff --git a/add/data/xqm/edition.xqm b/add/data/xqm/edition.xqm index a96aa1416..0e9b3bc27 100644 --- a/add/data/xqm/edition.xqm +++ b/add/data/xqm/edition.xqm @@ -1,4 +1,4 @@ -xquery version "3.0"; +xquery version "3.1"; (: Edirom Online Copyright (C) 2011 The Edirom Project @@ -28,10 +28,10 @@ xquery version "3.0"; :) module namespace edition = "http://www.edirom.de/xquery/edition"; -declare namespace edirom="http://www.edirom.de/ns/1.3"; -declare namespace xlink="http://www.w3.org/1999/xlink"; +declare namespace edirom = "http://www.edirom.de/ns/1.3"; +declare namespace xlink = "http://www.w3.org/1999/xlink"; -import module namespace functx="http://www.functx.com"; +import module namespace functx = "http://www.functx.com"; (:~ : Returns a JSON representation of an Edition : @@ -44,10 +44,10 @@ declare function edition:toJSON($uri as xs:string) as xs:string { return concat(' {', - 'id: "', $edition/string(@xml:id), '", ', - 'doc: "', $uri, '", ', - 'name: "', $edition/edirom:editionName, '"', - '}') + 'id: "', $edition/string(@xml:id), '", ', + 'doc: "', $uri, '", ', + 'name: "', $edition/edirom:editionName, '"', + '}') }; (:~ @@ -58,7 +58,8 @@ declare function edition:toJSON($uri as xs:string) as xs:string { declare function edition:getUris() as xs:string* { for $edition in collection('/db/apps')//edirom:edition - return 'xmldb:exist://' || document-uri($edition/root()) + return + 'xmldb:exist://' || document-uri($edition/root()) }; (:~ @@ -69,7 +70,7 @@ declare function edition:getUris() as xs:string* { :) declare function edition:getWorkUris($uri as xs:string) as xs:string* { - doc($uri)//edirom:work/string(@xlink:href) + doc($uri)//edirom:work/@xlink:href ! string(.) }; (:~ @@ -80,39 +81,85 @@ declare function edition:getWorkUris($uri as xs:string) as xs:string* { : @return The URI :) declare function edition:getLanguageFileURI($uri as xs:string, $lang as xs:string) as xs:string { + + let $doc := ( + if(doc-available($uri)) + then + doc($uri) + else + doc(edition:findEdition($uri)) + ) + return + if ($doc//edirom:language[@xml:lang eq $lang]/@xlink:href => string() != "") + then + $doc//edirom:language[@xml:lang eq $lang]/@xlink:href => string() + else + "" +}; + +(:~ +: Returns the URI for a specific language file +: +: @param $uri The URI of the Edition's document to process +: @return the edition's languages as defined in the edition file sorted as +: complete languages in document-order followed by incomplete langauges in document-order +:) +declare function edition:getLanguageCodesSorted($uri as xs:string) as xs:string { - doc($uri)//edirom:language[@xml:lang eq $lang]/string(@xlink:href) + let $editionDoc := doc($uri) + let $languagesComplete := ( + for $lang in $editionDoc//edirom:language + let $langCode := $lang/@xml:lang + let $langComplete := xs:boolean($lang/@complete) + where $langComplete = true() + return + $langCode + ) + let $languagesIncomplete := ( + for $lang in $editionDoc//edirom:language + let $langCode := $lang/@xml:lang + let $langComplete := xs:boolean($lang/@complete) + where $langComplete = false() + return + $langCode + ) + return + ($languagesComplete, $languagesIncomplete) }; (:~ : Returns the URI for the preferences file : : @param $uri The URI of the Edition's document to process -: @return The URI +: @return The URI of the preference file :) declare function edition:getPreferencesURI($uri as xs:string) as xs:string { - doc($uri)//edirom:preferences/string(@xlink:href) + doc($uri)//edirom:preferences/@xlink:href => string() }; (:~ : Returns the URI of the edition specified by the submitted $editionID parameter. -: Only succeeds if the supplied id is the @xml:id of a edirom:edition element in '/db/apps'. : If $editionID is the empty string, returns the URI of the first edition found in '/db/apps'. +: If the submitted $editionID already qualifies to read a document, return $editionID unaltered. : : @param $editionID The '@xml:id' of the edirom:edition document to process : @return The URI of the Edition file :) -declare function edition:findEdition($editionID as xs:string) as xs:string { - if($editionID eq '') +declare function edition:findEdition($editionID as xs:string?) as xs:string { + if(not($editionID) or $editionID eq '') then( let $edition := (collection('/db/apps')//edirom:edition)[1] return 'xmldb:exist://' || document-uri($edition/root()) ) + else if(doc-available($editionID)) (:already a qualified URI :) + then + $editionID else ( let $edition := collection('/db/apps')//edirom:edition/id($editionID) - return 'xmldb:exist://' || document-uri($edition/root()) - ) + return + 'xmldb:exist://' || document-uri($edition/root()) + ) }; (:~ @@ -122,7 +169,7 @@ declare function edition:findEdition($editionID as xs:string) as xs:string { : @return the text contents of edirom:edition/edirom:editionName :) declare function edition:getName($uri as xs:string) as xs:string { - doc($uri)/edirom:edition/edirom:editionName/text() + doc($uri)/edirom:edition/edirom:editionName => fn:normalize-space() }; (:~ diff --git a/add/data/xqm/functx-1.0-nodoc-2007-01.xq b/add/data/xqm/functx-1.0-nodoc-2007-01.xq deleted file mode 100644 index dd8ca2a68..000000000 --- a/add/data/xqm/functx-1.0-nodoc-2007-01.xq +++ /dev/null @@ -1,1410 +0,0 @@ - -(:~ - - : -------------------------------- - : The FunctX XQuery Function Library - : -------------------------------- - - : Copyright (C) 2007 Datypic - - : This library is free software; you can redistribute it and/or - : modify it under the terms of the GNU Lesser General Public - : License as published by the Free Software Foundation; either - : version 2.1 of the License. - - : This library is distributed in the hope that it will be useful, - : but WITHOUT ANY WARRANTY; without even the implied warranty of - : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - : Lesser General Public License for more details. - - : You should have received a copy of the GNU Lesser General Public - : License along with this library; if not, write to the Free Software - : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - - : For more information on the FunctX XQuery library, contact contrib@functx.com. - - : @version 1.0 - : @see http://www.xqueryfunctions.com - :) -module namespace functx = "http://www.functx.com" ; - -declare function functx:add-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return if ($element/@*[node-name(.) = $attrName]) - then () - else attribute {$attrName} - {$attrValues[$seq]}, - $element/@*, - $element/node() } - } ; - -declare function functx:add-months - ( $date as xs:anyAtomicType? , - $months as xs:integer ) as xs:date? { - - xs:date($date) + functx:yearMonthDuration(0,$months) - } ; - -declare function functx:add-or-update-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return attribute {$attrName} - {$attrValues[$seq]}, - $element/@*[not(node-name(.) = $attrNames)], - $element/node() } - } ; - -declare function functx:all-whitespace - ( $arg as xs:string? ) as xs:boolean { - - normalize-space($arg) = '' - } ; - -declare function functx:are-distinct-values - ( $seq as xs:anyAtomicType* ) as xs:boolean { - - count(distinct-values($seq)) = count($seq) - } ; - -declare function functx:atomic-type - ( $values as xs:anyAtomicType* ) as xs:string* { - - for $val in $values - return - (if ($val instance of xs:untypedAtomic) then 'xs:untypedAtomic' - else if ($val instance of xs:anyURI) then 'xs:anyURI' - else if ($val instance of xs:ENTITY) then 'xs:ENTITY' - else if ($val instance of xs:ID) then 'xs:ID' - else if ($val instance of xs:NMTOKEN) then 'xs:NMTOKEN' - else if ($val instance of xs:language) then 'xs:language' - else if ($val instance of xs:NCName) then 'xs:NCName' - else if ($val instance of xs:Name) then 'xs:Name' - else if ($val instance of xs:token) then 'xs:token' - else if ($val instance of xs:normalizedString) - then 'xs:normalizedString' - else if ($val instance of xs:string) then 'xs:string' - else if ($val instance of xs:QName) then 'xs:QName' - else if ($val instance of xs:boolean) then 'xs:boolean' - else if ($val instance of xs:base64Binary) then 'xs:base64Binary' - else if ($val instance of xs:hexBinary) then 'xs:hexBinary' - else if ($val instance of xs:byte) then 'xs:byte' - else if ($val instance of xs:short) then 'xs:short' - else if ($val instance of xs:int) then 'xs:int' - else if ($val instance of xs:long) then 'xs:long' - else if ($val instance of xs:unsignedByte) then 'xs:unsignedByte' - else if ($val instance of xs:unsignedShort) then 'xs:unsignedShort' - else if ($val instance of xs:unsignedInt) then 'xs:unsignedInt' - else if ($val instance of xs:unsignedLong) then 'xs:unsignedLong' - else if ($val instance of xs:positiveInteger) - then 'xs:positiveInteger' - else if ($val instance of xs:nonNegativeInteger) - then 'xs:nonNegativeInteger' - else if ($val instance of xs:negativeInteger) - then 'xs:negativeInteger' - else if ($val instance of xs:nonPositiveInteger) - then 'xs:nonPositiveInteger' - else if ($val instance of xs:integer) then 'xs:integer' - else if ($val instance of xs:decimal) then 'xs:decimal' - else if ($val instance of xs:float) then 'xs:float' - else if ($val instance of xs:double) then 'xs:double' - else if ($val instance of xs:date) then 'xs:date' - else if ($val instance of xs:time) then 'xs:time' - else if ($val instance of xs:dateTime) then 'xs:dateTime' - else if ($val instance of xs:dayTimeDuration) - then 'xs:dayTimeDuration' - else if ($val instance of xs:yearMonthDuration) - then 'xs:yearMonthDuration' - else if ($val instance of xs:duration) then 'xs:duration' - else if ($val instance of xs:gMonth) then 'xs:gMonth' - else if ($val instance of xs:gYear) then 'xs:gYear' - else if ($val instance of xs:gYearMonth) then 'xs:gYearMonth' - else if ($val instance of xs:gDay) then 'xs:gDay' - else if ($val instance of xs:gMonthDay) then 'xs:gMonthDay' - else 'unknown') - } ; - -declare function functx:avg-empty-is-zero - ( $values as xs:anyAtomicType* , - $allNodes as node()* ) as xs:double { - - if (empty($allNodes)) - then 0 - else sum($values[string(.) != '']) div count($allNodes) - } ; - -declare function functx:between-exclusive - ( $value as xs:anyAtomicType? , - $minValue as xs:anyAtomicType , - $maxValue as xs:anyAtomicType ) as xs:boolean { - - $value > $minValue and $value < $maxValue - } ; - -declare function functx:between-inclusive - ( $value as xs:anyAtomicType? , - $minValue as xs:anyAtomicType , - $maxValue as xs:anyAtomicType ) as xs:boolean { - - $value >= $minValue and $value <= $maxValue - } ; - -declare function functx:camel-case-to-words - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - concat(substring($arg,1,1), - replace(substring($arg,2),'(\p{Lu})', - concat($delim, '$1'))) - } ; - -declare function functx:capitalize-first - ( $arg as xs:string? ) as xs:string? { - - concat(upper-case(substring($arg,1,1)), - substring($arg,2)) - } ; - -declare function functx:change-element-names-deep - ( $nodes as node()* , - $oldNames as xs:QName* , - $newNames as xs:QName* ) as node()* { - - if (count($oldNames) != count($newNames)) - then error(xs:QName('functx:Different_number_of_names')) - else - for $node in $nodes - return if ($node instance of element()) - then element - {functx:if-empty - ($newNames[index-of($oldNames, - node-name($node))], - node-name($node)) } - {$node/@*, - functx:change-element-names-deep($node/node(), - $oldNames, $newNames)} - else if ($node instance of document-node()) - then functx:change-element-names-deep($node/node(), - $oldNames, $newNames) - else $node - } ; - -declare function functx:change-element-ns-deep - ( $nodes as node()* , - $newns as xs:string , - $prefix as xs:string ) as node()* { - - for $node in $nodes - return if ($node instance of element()) - then (element - {QName ($newns, - concat($prefix, - if ($prefix = '') - then '' - else ':', - local-name($node)))} - {$node/@*, - functx:change-element-ns-deep($node/node(), - $newns, $prefix)}) - else if ($node instance of document-node()) - then functx:change-element-ns-deep($node/node(), - $newns, $prefix) - else $node - } ; - -declare function functx:change-element-ns - ( $elements as element()* , - $newns as xs:string , - $prefix as xs:string ) as element()? { - - for $element in $elements - return - element {QName ($newns, - concat($prefix, - if ($prefix = '') - then '' - else ':', - local-name($element)))} - {$element/@*, $element/node()} - } ; - -declare function functx:chars - ( $arg as xs:string? ) as xs:string* { - - for $ch in string-to-codepoints($arg) - return codepoints-to-string($ch) - } ; - -declare function functx:contains-any-of - ( $arg as xs:string? , - $searchStrings as xs:string* ) as xs:boolean { - - some $searchString in $searchStrings - satisfies contains($arg,$searchString) - } ; - -declare function functx:contains-case-insensitive - ( $arg as xs:string? , - $substring as xs:string ) as xs:boolean? { - - contains(upper-case($arg), upper-case($substring)) - } ; - -declare function functx:contains-word - ( $arg as xs:string? , - $word as xs:string ) as xs:boolean { - - matches(upper-case($arg), - concat('^(.*\W)?', - upper-case(functx:escape-for-regex($word)), - '(\W.*)?$')) - } ; - -declare function functx:copy-attributes - ( $copyTo as element() , - $copyFrom as element() ) as element() { - - element { node-name($copyTo)} - { $copyTo/@*[not(node-name(.) = $copyFrom/@*/node-name(.))], - $copyFrom/@*, - $copyTo/node() } - - } ; - -declare function functx:date - ( $year as xs:anyAtomicType , - $month as xs:anyAtomicType , - $day as xs:anyAtomicType ) as xs:date { - - xs:date( - concat( - functx:pad-integer-to-length(xs:integer($year),4),'-', - functx:pad-integer-to-length(xs:integer($month),2),'-', - functx:pad-integer-to-length(xs:integer($day),2))) - } ; - -declare function functx:dateTime - ( $year as xs:anyAtomicType , - $month as xs:anyAtomicType , - $day as xs:anyAtomicType , - $hour as xs:anyAtomicType , - $minute as xs:anyAtomicType , - $second as xs:anyAtomicType ) as xs:dateTime { - - xs:dateTime( - concat(functx:date($year,$month,$day),'T', - functx:time($hour,$minute,$second))) - } ; - -declare function functx:day-in-year - ( $date as xs:anyAtomicType? ) as xs:integer? { - - days-from-duration( - xs:date($date) - functx:first-day-of-year($date)) + 1 - } ; - -declare function functx:day-of-week-abbrev-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat') - [functx:day-of-week($date) + 1] - } ; - -declare function functx:day-of-week-name-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Sunday', 'Monday', 'Tuesday', 'Wednesday', - 'Thursday', 'Friday', 'Saturday') - [functx:day-of-week($date) + 1] - } ; - -declare function functx:day-of-week - ( $date as xs:anyAtomicType? ) as xs:integer? { - - if (empty($date)) - then () - else xs:integer((xs:date($date) - xs:date('1901-01-06')) - div xs:dayTimeDuration('P1D')) mod 7 - } ; - -declare function functx:dayTimeDuration - ( $days as xs:decimal? , - $hours as xs:decimal? , - $minutes as xs:decimal? , - $seconds as xs:decimal? ) as xs:dayTimeDuration { - - (xs:dayTimeDuration('P1D') * functx:if-empty($days,0)) + - (xs:dayTimeDuration('PT1H') * functx:if-empty($hours,0)) + - (xs:dayTimeDuration('PT1M') * functx:if-empty($minutes,0)) + - (xs:dayTimeDuration('PT1S') * functx:if-empty($seconds,0)) - } ; - -declare function functx:days-in-month - ( $date as xs:anyAtomicType? ) as xs:integer? { - - if (month-from-date(xs:date($date)) = 2 and - functx:is-leap-year($date)) - then 29 - else - (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) - [month-from-date(xs:date($date))] - } ; - -declare function functx:depth-of-node - ( $node as node()? ) as xs:integer { - - count($node/ancestor-or-self::node()) - } ; - -declare function functx:distinct-attribute-names - ( $nodes as node()* ) as xs:string* { - - distinct-values($nodes//@*/name(.)) - } ; - -declare function functx:distinct-deep - ( $nodes as node()* ) as node()* { - - for $seq in (1 to count($nodes)) - return $nodes[$seq][not(functx:is-node-in-sequence-deep-equal( - .,$nodes[position() < $seq]))] - } ; - -declare function functx:distinct-element-names - ( $nodes as node()* ) as xs:string* { - - distinct-values($nodes/descendant-or-self::*/name(.)) - } ; - -declare function functx:distinct-element-paths - ( $nodes as node()* ) as xs:string* { - - distinct-values(functx:path-to-node($nodes/descendant-or-self::*)) - } ; - -declare function functx:distinct-nodes - ( $nodes as node()* ) as node()* { - - for $seq in (1 to count($nodes)) - return $nodes[$seq][not(functx:is-node-in-sequence( - .,$nodes[position() < $seq]))] - } ; - -declare function functx:duration-from-timezone - ( $timezone as xs:string ) as xs:dayTimeDuration { - - xs:dayTimeDuration( - if (not(matches($timezone,'Z|[\+\-]\d{2}:\d{2}'))) - then error(xs:QName('functx:Invalid_Timezone_Value')) - else if ($timezone = 'Z') - then 'PT0S' - else replace($timezone,'\+?(\d{2}):\d{2}','PT$1H') - ) - } ; - -declare function functx:dynamic-path - ( $parent as node() , - $path as xs:string ) as item()* { - - let $nextStep := functx:substring-before-if-contains($path,'/') - let $restOfSteps := substring-after($path,'/') - for $child in - ($parent/*[functx:name-test(name(),$nextStep)], - $parent/@*[functx:name-test(name(), - substring-after($nextStep,'@'))]) - return if ($restOfSteps) - then functx:dynamic-path($child, $restOfSteps) - else $child - } ; - -declare function functx:escape-for-regex - ( $arg as xs:string? ) as xs:string { - - replace($arg, - '(\.|\[|\]|\\|\||\-|\^|\$|\?|\*|\+|\{|\}|\(|\))','\\$1') - } ; - -declare function functx:exclusive-or - ( $arg1 as xs:boolean? , - $arg2 as xs:boolean? ) as xs:boolean? { - - $arg1 != $arg2 - } ; - -declare function functx:first-day-of-month - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), - month-from-date(xs:date($date)), - 1) - } ; - -declare function functx:first-day-of-year - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), 1, 1) - } ; - -declare function functx:first-node - ( $nodes as node()* ) as node()? { - - ($nodes/.)[1] - } ; - -declare function functx:follows-not-descendant - ( $a as node()? , - $b as node()? ) as xs:boolean { - - $a >> $b and empty($b intersect $a/ancestor::node()) - } ; - -declare function functx:format-as-title-en - ( $titles as xs:string* ) as xs:string* { - - let $wordsToMoveToEnd := ('A', 'An', 'The') - for $title in $titles - let $firstWord := functx:substring-before-match($title,'\W') - return if ($firstWord = $wordsToMoveToEnd) - then replace($title,'(.*?)\W(.*)', '$2, $1') - else $title - } ; - -declare function functx:fragment-from-uri - ( $uri as xs:string? ) as xs:string? { - - substring-after($uri,'#') - } ; - -declare function functx:get-matches-and-non-matches - ( $string as xs:string? , - $regex as xs:string ) as element()* { - - let $iomf := functx:index-of-match-first($string, $regex) - return - if (empty($iomf)) - then {$string} - else - if ($iomf > 1) - then ({substring($string,1,$iomf - 1)}, - functx:get-matches-and-non-matches( - substring($string,$iomf),$regex)) - else - let $length := - string-length($string) - - string-length(functx:replace-first($string, $regex,'')) - return ({substring($string,1,$length)}, - if (string-length($string) > $length) - then functx:get-matches-and-non-matches( - substring($string,$length + 1),$regex) - else ()) - } ; - -declare function functx:get-matches - ( $string as xs:string? , - $regex as xs:string ) as xs:string* { - - functx:get-matches-and-non-matches($string,$regex)/ - string(self::match) - } ; - -declare function functx:has-element-only-content - ( $element as element() ) as xs:boolean { - - not($element/text()[normalize-space(.) != '']) and $element/* - } ; - -declare function functx:has-empty-content - ( $element as element() ) as xs:boolean { - - not($element/node()) - } ; - -declare function functx:has-mixed-content - ( $element as element() ) as xs:boolean { - - $element/text()[normalize-space(.) != ''] and $element/* - } ; - -declare function functx:has-simple-content - ( $element as element() ) as xs:boolean { - - $element/text() and not($element/*) - } ; - -declare function functx:id-from-element - ( $element as element()? ) as xs:string? { - - data(($element/@*[id(.) is ..])[1]) - } ; - -declare function functx:id-untyped - ( $node as node()* , - $id as xs:anyAtomicType ) as element()* { - - $node//*[@* = $id] - } ; - -declare function functx:if-absent - ( $arg as item()* , - $value as item()* ) as item()* { - - if (exists($arg)) - then $arg - else $value - } ; - -declare function functx:if-empty - ( $arg as item()? , - $value as item()* ) as item()* { - - if (string($arg) != '') - then data($arg) - else $value - } ; - -declare function functx:index-of-deep-equal-node - ( $nodes as node()* , - $nodeToFind as node() ) as xs:integer* { - - for $seq in (1 to count($nodes)) - return $seq[deep-equal($nodes[$seq],$nodeToFind)] - } ; - -declare function functx:index-of-match-first - ( $arg as xs:string? , - $pattern as xs:string ) as xs:integer? { - - if (matches($arg,$pattern)) - then string-length(tokenize($arg, $pattern)[1]) + 1 - else () - } ; - -declare function functx:index-of-node - ( $nodes as node()* , - $nodeToFind as node() ) as xs:integer* { - - for $seq in (1 to count($nodes)) - return $seq[$nodes[$seq] is $nodeToFind] - } ; - -declare function functx:index-of-string-first - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer? { - - if (contains($arg, $substring)) - then string-length(substring-before($arg, $substring))+1 - else () - } ; - -declare function functx:index-of-string-last - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer? { - - functx:index-of-string($arg, $substring)[last()] - } ; - -declare function functx:index-of-string - ( $arg as xs:string? , - $substring as xs:string ) as xs:integer* { - - if (contains($arg, $substring)) - then (string-length(substring-before($arg, $substring))+1, - for $other in - functx:index-of-string(substring-after($arg, $substring), - $substring) - return - $other + - string-length(substring-before($arg, $substring)) + - string-length($substring)) - else () - } ; - -declare function functx:insert-string - ( $originalString as xs:string? , - $stringToInsert as xs:string? , - $pos as xs:integer ) as xs:string { - - concat(substring($originalString,1,$pos - 1), - $stringToInsert, - substring($originalString,$pos)) - } ; - -declare function functx:is-a-number - ( $value as xs:anyAtomicType? ) as xs:boolean { - - string(number($value)) != 'NaN' - } ; - -declare function functx:is-absolute-uri - ( $uri as xs:string? ) as xs:boolean { - - matches($uri,'^[a-z]+:') - } ; - -declare function functx:is-ancestor - ( $node1 as node() , - $node2 as node() ) as xs:boolean { - - exists($node1 intersect $node2/ancestor::node()) - } ; - -declare function functx:is-descendant - ( $node1 as node() , - $node2 as node() ) as xs:boolean { - - boolean($node2 intersect $node1/ancestor::node()) - } ; - -declare function functx:is-leap-year - ( $date as xs:anyAtomicType? ) as xs:boolean { - - for $year in xs:integer(substring(string($date),1,4)) - return ($year mod 4 = 0 and - $year mod 100 != 0) or - $year mod 400 = 0 - } ; - -declare function functx:is-node-among-descendants-deep-equal - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq/descendant-or-self::*/(.|@*) - satisfies deep-equal($nodeInSeq,$node) - } ; - -declare function functx:is-node-among-descendants - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq/descendant-or-self::*/(.|@*) - satisfies $nodeInSeq is $node - } ; - -declare function functx:is-node-in-sequence-deep-equal - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq satisfies deep-equal($nodeInSeq,$node) - } ; - -declare function functx:is-node-in-sequence - ( $node as node()? , - $seq as node()* ) as xs:boolean { - - some $nodeInSeq in $seq satisfies $nodeInSeq is $node - } ; - -declare function functx:is-value-in-sequence - ( $value as xs:anyAtomicType? , - $seq as xs:anyAtomicType* ) as xs:boolean { - - $value = $seq - } ; - -declare function functx:last-day-of-month - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), - month-from-date(xs:date($date)), - functx:days-in-month($date)) - } ; - -declare function functx:last-day-of-year - ( $date as xs:anyAtomicType? ) as xs:date? { - - functx:date(year-from-date(xs:date($date)), 12, 31) - } ; - -declare function functx:last-node - ( $nodes as node()* ) as node()? { - - ($nodes/.)[last()] - } ; - -declare function functx:leaf-elements - ( $root as node()? ) as element()* { - - $root/descendant-or-self::*[not(*)] - } ; - -declare function functx:left-trim - ( $arg as xs:string? ) as xs:string { - - replace($arg,'^\s+','') - } ; - -declare function functx:line-count - ( $arg as xs:string? ) as xs:integer { - - count(functx:lines($arg)) - } ; - -declare function functx:lines - ( $arg as xs:string? ) as xs:string* { - - tokenize($arg, '(\r\n?|\n\r?)') - } ; - -declare function functx:max-depth - ( $root as node()? ) as xs:integer? { - - if ($root/*) - then max($root/*/functx:max-depth(.)) + 1 - else 1 - } ; - -declare function functx:max-determine-type - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType? { - - if (every $value in $seq satisfies ($value castable as xs:double)) - then max(for $value in $seq return xs:double($value)) - else max(for $value in $seq return xs:string($value)) - } ; - -declare function functx:max-line-length - ( $arg as xs:string? ) as xs:integer { - - max( - for $line in functx:lines($arg) - return string-length($line)) - } ; - -declare function functx:max-node - ( $nodes as node()* ) as node()* { - - $nodes[. = max($nodes)] - } ; - -declare function functx:max-string - ( $strings as xs:anyAtomicType* ) as xs:string? { - - max(for $string in $strings return string($string)) - } ; - -declare function functx:min-determine-type - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType? { - - if (every $value in $seq satisfies ($value castable as xs:double)) - then min(for $value in $seq return xs:double($value)) - else min(for $value in $seq return xs:string($value)) - } ; - -declare function functx:min-node - ( $nodes as node()* ) as node()* { - - $nodes[. = min($nodes)] - } ; - -declare function functx:min-non-empty-string - ( $strings as xs:string* ) as xs:string? { - - min($strings[. != '']) - } ; - -declare function functx:min-string - ( $strings as xs:anyAtomicType* ) as xs:string? { - - min(for $string in $strings return string($string)) - } ; - -declare function functx:mmddyyyy-to-date - ( $dateString as xs:string? ) as xs:date? { - - if (empty($dateString)) - then () - else if (not(matches($dateString, - '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$'))) - then error(xs:QName('functx:Invalid_Date_Format')) - else xs:date(replace($dateString, - '^\D*(\d{2})\D*(\d{2})\D*(\d{4})\D*$', - '$3-$1-$2')) - } ; - -declare function functx:month-abbrev-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') - [month-from-date(xs:date($date))] - } ; - -declare function functx:month-name-en - ( $date as xs:anyAtomicType? ) as xs:string? { - - ('January', 'February', 'March', 'April', 'May', 'June', - 'July', 'August', 'September', 'October', 'November', 'December') - [month-from-date(xs:date($date))] - } ; - -declare function functx:name-test - ( $testname as xs:string? , - $names as xs:string* ) as xs:boolean { - -$testname = $names -or -$names = '*' -or -functx:substring-after-if-contains($testname,':') = - (for $name in $names - return substring-after($name,'*:')) -or -substring-before($testname,':') = - (for $name in $names[contains(.,':*')] - return substring-before($name,':*')) - } ; - -declare function functx:namespaces-in-use - ( $root as node()? ) as xs:anyURI* { - - distinct-values( - $root/descendant-or-self::*/(.|@*)/namespace-uri(.)) - } ; - -declare function functx:next-day - ( $date as xs:anyAtomicType? ) as xs:date? { - - xs:date($date) + xs:dayTimeDuration('P1D') - } ; - -declare function functx:node-kind - ( $nodes as node()* ) as xs:string* { - - for $node in $nodes - return - if ($node instance of element()) then 'element' - else if ($node instance of attribute()) then 'attribute' - else if ($node instance of text()) then 'text' - else if ($node instance of document-node()) then 'document-node' - else if ($node instance of comment()) then 'comment' - else if ($node instance of processing-instruction()) - then 'processing-instruction' - else 'unknown' - } ; - -declare function functx:non-distinct-values - ( $seq as xs:anyAtomicType* ) as xs:anyAtomicType* { - - for $val in distinct-values($seq) - return $val[count($seq[. = $val]) > 1] - } ; - -declare function functx:number-of-matches - ( $arg as xs:string? , - $pattern as xs:string ) as xs:integer { - - count(tokenize($arg,$pattern)) - 1 - } ; - -declare function functx:open-ref-document - ( $refNode as node() ) as document-node() { - - if (base-uri($refNode)) - then doc(resolve-uri($refNode, base-uri($refNode))) - else doc(resolve-uri($refNode)) - } ; - -declare function functx:ordinal-number-en - ( $num as xs:integer? ) as xs:string { - - concat(xs:string($num), - if (matches(xs:string($num),'[04-9]$|1[1-3]$')) then 'th' - else if (ends-with(xs:string($num),'1')) then 'st' - else if (ends-with(xs:string($num),'2')) then 'nd' - else if (ends-with(xs:string($num),'3')) then 'rd' - else '') - } ; - -declare function functx:pad-integer-to-length - ( $integerToPad as xs:anyAtomicType? , - $length as xs:integer ) as xs:string { - - if ($length < string-length(string($integerToPad))) - then error(xs:QName('functx:Integer_Longer_Than_Length')) - else concat - (functx:repeat-string( - '0',$length - string-length(string($integerToPad))), - string($integerToPad)) - } ; - -declare function functx:pad-string-to-length - ( $stringToPad as xs:string? , - $padChar as xs:string , - $length as xs:integer ) as xs:string { - - substring( - string-join ( - ($stringToPad, for $i in (1 to $length) return $padChar) - ,'') - ,1,$length) - } ; - -declare function functx:path-to-node-with-pos - ( $node as node()? ) as xs:string { - -string-join( - for $ancestor in $node/ancestor-or-self::* - let $sibsOfSameName := $ancestor/../*[name() = name($ancestor)] - return concat(name($ancestor), - if (count($sibsOfSameName) <= 1) - then '' - else concat( - '[',functx:index-of-node($sibsOfSameName,$ancestor),']')) - , '/') - } ; - -declare function functx:path-to-node - ( $nodes as node()* ) as xs:string* { - -$nodes/string-join(ancestor-or-self::*/name(.), '/') - } ; - -declare function functx:precedes-not-ancestor - ( $a as node()? , - $b as node()? ) as xs:boolean { - - $a << $b and empty($a intersect $b/ancestor::node()) - } ; - -declare function functx:previous-day - ( $date as xs:anyAtomicType? ) as xs:date? { - - xs:date($date) - xs:dayTimeDuration('P1D') - } ; - -declare function functx:remove-attributes-deep - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return if ($node instance of element()) - then element { node-name($node)} - { $node/@*[not(functx:name-test(name(),$names))], - functx:remove-attributes-deep($node/node(), $names)} - else if ($node instance of document-node()) - then functx:remove-attributes-deep($node/node(), $names) - else $node - } ; - -declare function functx:remove-attributes - ( $elements as element()* , - $names as xs:string* ) as element() { - - for $element in $elements - return element - {node-name($element)} - {$element/@*[not(functx:name-test(name(),$names))], - $element/node() } - } ; - -declare function functx:remove-elements-deep - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return - if ($node instance of element()) - then if (functx:name-test(name($node),$names)) - then () - else element { node-name($node)} - { $node/@*, - functx:remove-elements-deep($node/node(), $names)} - else if ($node instance of document-node()) - then functx:remove-elements-deep($node/node(), $names) - else $node - } ; - -declare function functx:remove-elements-not-contents - ( $nodes as node()* , - $names as xs:string* ) as node()* { - - for $node in $nodes - return - if ($node instance of element()) - then if (functx:name-test(name($node),$names)) - then functx:remove-elements-not-contents($node/node(), $names) - else element {node-name($node)} - {$node/@*, - functx:remove-elements-not-contents($node/node(),$names)} - else if ($node instance of document-node()) - then functx:remove-elements-not-contents($node/node(), $names) - else $node - } ; - -declare function functx:remove-elements - ( $elements as element()* , - $names as xs:string* ) as element()* { - - for $element in $elements - return element - {node-name($element)} - {$element/@*, - $element/node()[not(functx:name-test(name(),$names))] } - } ; - -declare function functx:repeat-string - ( $stringToRepeat as xs:string? , - $count as xs:integer ) as xs:string { - - string-join((for $i in 1 to $count return $stringToRepeat), - '') - } ; - -declare function functx:replace-beginning - ( $arg as xs:string? , - $pattern as xs:string , - $replacement as xs:string ) as xs:string { - - replace($arg, concat('^.*?', $pattern), $replacement) - } ; - -declare function functx:replace-element-values - ( $elements as element()* , - $values as xs:anyAtomicType* ) as element()* { - - for $element at $seq in $elements - return element { node-name($element)} - { $element/@*, - $values[$seq] } - } ; - -declare function functx:replace-first - ( $arg as xs:string? , - $pattern as xs:string , - $replacement as xs:string ) as xs:string { - - replace($arg, concat('(^.*?)', $pattern), - concat('$1',$replacement)) - } ; - -declare function functx:replace-multi - ( $arg as xs:string? , - $changeFrom as xs:string* , - $changeTo as xs:string* ) as xs:string? { - - if (count($changeFrom) > 0) - then functx:replace-multi( - replace($arg, $changeFrom[1], - functx:if-absent($changeTo[1],'')), - $changeFrom[position() > 1], - $changeTo[position() > 1]) - else $arg - } ; - -declare function functx:reverse-string - ( $arg as xs:string? ) as xs:string { - - codepoints-to-string(reverse(string-to-codepoints($arg))) - } ; - -declare function functx:right-trim - ( $arg as xs:string? ) as xs:string { - - replace($arg,'\s+$','') - } ; - -declare function functx:scheme-from-uri - ( $uri as xs:string? ) as xs:string? { - - substring-before($uri,':') - } ; - -declare function functx:sequence-deep-equal - ( $seq1 as item()* , - $seq2 as item()* ) as xs:boolean { - - every $i in 1 to max((count($seq1),count($seq2))) - satisfies deep-equal($seq1[$i],$seq2[$i]) - } ; - -declare function functx:sequence-node-equal-any-order - ( $seq1 as node()* , - $seq2 as node()* ) as xs:boolean { - - not( ($seq1 except $seq2, $seq2 except $seq1)) - } ; - -declare function functx:sequence-node-equal - ( $seq1 as node()* , - $seq2 as node()* ) as xs:boolean { - - every $i in 1 to max((count($seq1),count($seq2))) - satisfies $seq1[$i] is $seq2[$i] - } ; - -declare function functx:sequence-type - ( $items as item()* ) as xs:string { - -concat( - if (empty($items)) - then 'empty-sequence()' - else if (every $val in $items - satisfies $val instance of xs:anyAtomicType) - then if (count(distinct-values(functx:atomic-type($items))) - > 1) - then 'xs:anyAtomicType' - else functx:atomic-type($items[1]) - else if (some $val in $items - satisfies $val instance of xs:anyAtomicType) - then 'item()' - else if (count(distinct-values(functx:node-kind($items))) > 1) - then 'node()' - else concat(functx:node-kind($items[1]),'()') - , - if (count($items) > 1) - then '+' else '') - } ; - -declare function functx:siblings-same-name - ( $element as element()? ) as element()* { - - $element/../*[node-name(.) = node-name($element)] - except $element - } ; - -declare function functx:siblings - ( $node as node()? ) as node()* { - - $node/../node() except $node - } ; - -declare function functx:sort-as-numeric - ( $seq as item()* ) as item()* { - - for $item in $seq - order by number($item) - return $item - } ; - -declare function functx:sort-case-insensitive - ( $seq as item()* ) as item()* { - - for $item in $seq - order by upper-case(string($item)) - return $item - } ; - -declare function functx:sort-document-order - ( $seq as node()* ) as node()* { - - $seq/. - } ; - -declare function functx:sort - ( $seq as item()* ) as item()* { - - for $item in $seq - order by $item - return $item - } ; - -declare function functx:substring-after-if-contains - ( $arg as xs:string? , - $delim as xs:string ) as xs:string? { - - if (contains($arg,$delim)) - then substring-after($arg,$delim) - else $arg - } ; - -declare function functx:substring-after-last-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string { - - replace($arg,concat('^.*',$regex),'') - } ; - -declare function functx:substring-after-last - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - replace ($arg,concat('^.*',functx:escape-for-regex($delim)),'') - } ; - -declare function functx:substring-after-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string? { - - replace($arg,concat('^.*?',$regex),'') - } ; - -declare function functx:substring-before-if-contains - ( $arg as xs:string? , - $delim as xs:string ) as xs:string? { - - if (contains($arg,$delim)) - then substring-before($arg,$delim) - else $arg - } ; - -declare function functx:substring-before-last-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string? { - - replace($arg,concat('^(.*)',$regex,'.*'),'$1') - } ; - -declare function functx:substring-before-last - ( $arg as xs:string? , - $delim as xs:string ) as xs:string { - - if (matches($arg, functx:escape-for-regex($delim))) - then replace($arg, - concat('^(.*)', functx:escape-for-regex($delim),'.*'), - '$1') - else '' - } ; - -declare function functx:substring-before-match - ( $arg as xs:string? , - $regex as xs:string ) as xs:string { - - tokenize($arg,$regex)[1] - } ; - -declare function functx:time - ( $hour as xs:anyAtomicType , - $minute as xs:anyAtomicType , - $second as xs:anyAtomicType ) as xs:time { - - xs:time( - concat( - functx:pad-integer-to-length(xs:integer($hour),2),':', - functx:pad-integer-to-length(xs:integer($minute),2),':', - functx:pad-integer-to-length(xs:integer($second),2))) - } ; - -declare function functx:timezone-from-duration - ( $duration as xs:dayTimeDuration ) as xs:string { - - if (string($duration) = ('PT0S','-PT0S')) - then 'Z' - else if (matches(string($duration),'-PT[1-9]H')) - then replace(string($duration),'PT([1-9])H','0$1:00') - else if (matches(string($duration),'PT[1-9]H')) - then replace(string($duration),'PT([1-9])H','+0$1:00') - else if (matches(string($duration),'-PT1[0-4]H')) - then replace(string($duration),'PT(1[0-4])H','$1:00') - else if (matches(string($duration),'PT1[0-4]H')) - then replace(string($duration),'PT(1[0-4])H','+$1:00') - else error(xs:QName('functx:Invalid_Duration_Value')) - } ; - -declare function functx:total-days-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('P1D') - } ; - -declare function functx:total-hours-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1H') - } ; - -declare function functx:total-minutes-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1M') - } ; - -declare function functx:total-months-from-duration - ( $duration as xs:yearMonthDuration? ) as xs:decimal? { - - $duration div xs:yearMonthDuration('P1M') - } ; - -declare function functx:total-seconds-from-duration - ( $duration as xs:dayTimeDuration? ) as xs:decimal? { - - $duration div xs:dayTimeDuration('PT1S') - } ; - -declare function functx:total-years-from-duration - ( $duration as xs:yearMonthDuration? ) as xs:decimal? { - - $duration div xs:yearMonthDuration('P1Y') - } ; - -declare function functx:trim - ( $arg as xs:string? ) as xs:string { - - replace(replace($arg,'\s+$',''),'^\s+','') - } ; - -declare function functx:update-attributes - ( $elements as element()* , - $attrNames as xs:QName* , - $attrValues as xs:anyAtomicType* ) as element()? { - - for $element in $elements - return element { node-name($element)} - { for $attrName at $seq in $attrNames - return if ($element/@*[node-name(.) = $attrName]) - then attribute {$attrName} - {$attrValues[$seq]} - else (), - $element/@*[not(node-name(.) = $attrNames)], - $element/node() } - } ; - -declare function functx:value-except - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values($arg1[not(.=$arg2)]) - } ; - -declare function functx:value-intersect - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values($arg1[.=$arg2]) - } ; - -declare function functx:value-union - ( $arg1 as xs:anyAtomicType* , - $arg2 as xs:anyAtomicType* ) as xs:anyAtomicType* { - - distinct-values(($arg1, $arg2)) - } ; - -declare function functx:word-count - ( $arg as xs:string? ) as xs:integer { - - count(tokenize($arg, '\W+')[. != '']) - } ; - -declare function functx:words-to-camel-case - ( $arg as xs:string? ) as xs:string { - - string-join((tokenize($arg,'\s+')[1], - for $word in tokenize($arg,'\s+')[position() > 1] - return functx:capitalize-first($word)) - ,'') - } ; - -declare function functx:wrap-values-in-elements - ( $values as xs:anyAtomicType* , - $elementName as xs:QName ) as element()* { - - for $value in $values - return element {$elementName} {$value} - } ; - -declare function functx:yearMonthDuration - ( $years as xs:decimal? , - $months as xs:integer? ) as xs:yearMonthDuration { - - (xs:yearMonthDuration('P1M') * functx:if-empty($months,0)) + - (xs:yearMonthDuration('P1Y') * functx:if-empty($years,0)) - } ; diff --git a/add/data/xqm/source.xqm b/add/data/xqm/source.xqm index 08c8ccd78..001ab77cb 100644 --- a/add/data/xqm/source.xqm +++ b/add/data/xqm/source.xqm @@ -41,9 +41,13 @@ import module namespace eutil="http://www.edirom.de/xquery/util" at "../xqm/util :) declare function source:isSource($uri as xs:string) as xs:boolean { let $doc := eutil:getDoc($uri) + let $meiVersionRegex := '(([4-9])|(\d+[0-9]))\.\d+\.\d+(-dev)?' return - exists($doc//mei:mei) and exists($doc//mei:source) (:mei2 and ?3 :) - or ($doc//mei:mei/@meiversion = ("4.0.0", "4.0.1") and exists($doc//mei:manifestation[@singleton='true'])) (:mei4 :) + (exists($doc//mei:mei) and exists($doc//mei:source)) (:mei2 and ?3 :) + or + (matches($doc//mei:mei/@meiversion, $meiVersionRegex) and exists($doc//mei:manifestation[@singleton='true'])) (:mei4+ for manuscripts:) + or + (matches($doc//mei:mei/@meiversion, $meiVersionRegex) and exists($doc//mei:manifestation//mei:item)) (: mei4+ for prints :) }; (:~ diff --git a/add/data/xqm/util.xqm b/add/data/xqm/util.xqm index 38102f194..d05b1a962 100644 --- a/add/data/xqm/util.xqm +++ b/add/data/xqm/util.xqm @@ -34,7 +34,7 @@ import module namespace work="http://www.edirom.de/xquery/work" at "work.xqm"; import module namespace source="http://www.edirom.de/xquery/source" at "source.xqm"; import module namespace teitext="http://www.edirom.de/xquery/teitext" at "teitext.xqm"; import module namespace edition="http://www.edirom.de/xquery/edition" at "../xqm/edition.xqm"; -import module namespace functx = "http://www.functx.com" at "../xqm/functx-1.0-nodoc-2007-01.xq"; +import module namespace functx = "http://www.functx.com"; import module namespace annotation="http://www.edirom.de/xquery/annotation" at "../xqm/annotation.xqm"; declare namespace request="http://exist-db.org/xquery/request"; @@ -108,8 +108,10 @@ declare function eutil:getLocalizedTitle($node as node(), $lang as xs:string?) a let $namespace := eutil:getNamespace($node) - let $titleMEI := if ($lang != '' and $lang = $node/mei:title/@xml:lang) + let $titleMEI := if ($lang != '' and $lang = $node/mei:title/@xml:lang and not($node/mei:title/mei:titlePart)) then ($node/mei:title[@xml:lang = $lang]//text() => string-join() => normalize-space()) + else if ($lang != '' and $lang = $node/mei:title/@xml:lang and $node/mei:title/mei:titlePart) + then ($node/mei:title[@xml:lang = $lang]/mei:titlePart[1]//text() => string-join() => normalize-space()) else (($node//mei:title)[1]//text() => string-join() => normalize-space()) let $titleTEI := if ($lang != '' and $lang = $node/tei:title/@xml:lang) @@ -189,6 +191,37 @@ declare function eutil:getDocumentLabel($doc as xs:string, $edition as xs:string else('') }; +(:~ +: Returns a part's label (translated if available) +: +: @author Dennis Ried +: @param $partID The xml:id of the Part's node() to process +: @return The label (translated if available) +:) +declare function eutil:getPartLabel($measureOrPerfRes as node(), $type as xs:string) as xs:string { + (: request:get-parameter('lang', '') doesn't work?? [DeRi]:) +let $lang := if(request:get-parameter('lang', '') = '') + then('de') + else(request:get-parameter('lang', '')) +let $part := $measureOrPerfRes/ancestor::mei:part +let $voiceRef := $part//mei:staffDef/@decls +let $voiceID := substring-after($voiceRef, '#') + +let $perfResLabel := if($type eq 'measure') + then($measureOrPerfRes/ancestor::mei:mei/id($voiceID)/@label) + else($measureOrPerfRes/@label) +let $dictKey := 'perfMedium.perfRes.' || functx:substring-before-if-contains($perfResLabel,'.') +let $label := if(eutil:getLanguageString($dictKey, (), $lang)) + then(eutil:getLanguageString($dictKey, (), $lang)) + else($perfResLabel) +let $numbering := for $i in subsequence(tokenize($perfResLabel,'\.'),2) + where matches($i, '([0-9])|([ivxIVX])') + return + upper-case($i) +return + normalize-space(string-join(($label, $numbering),' ')) +}; + (:~ : Returns a language specific string : @@ -206,7 +239,7 @@ declare function eutil:getLanguageString($key as xs:string, $values as xs:string : : @param $key The key to search for : @param $values The values to include into the string -: @param $lang The language +: @param $lang The language : @return The string :) declare function eutil:getLanguageString($key as xs:string, $values as xs:string*, $lang as xs:string) as xs:string { @@ -222,7 +255,7 @@ declare function eutil:getLanguageString($key as xs:string, $values as xs:string }; (:~ -: Return a value of preference to key +: Return a value of preference to key : : @param $key The key to search for : @return The string @@ -232,26 +265,24 @@ declare function eutil:getPreference($key as xs:string, $edition as xs:string?) let $file := doc('../prefs/edirom-prefs.xml') let $projectFile := doc(edition:getPreferencesURI($edition)) - return + return if($projectFile != 'null' and $projectFile//entry[@key = $key]) then ($projectFile//entry[@key = $key]/string(@value)) else ($file//entry[@key = $key]/string(@value)) }; (:~ -: Return the application and content language +: Return the application and content language : : @param $edition The edition's path : @return The language key :) declare function eutil:getLanguage($edition as xs:string?) as xs:string { - if(request:get-cookie-names() = 'edirom-language') - then( - request:get-cookie-value('edirom-language') - ) - else( - eutil:getPreference('application_language', $edition) - ) + if (request:get-parameter("lang", "") != "") + then request:get-parameter("lang", "") + else if(request:get-cookie-names() = 'edirom-language') + then request:get-cookie-value('edirom-language') + else eutil:getPreference('application_language', edition:findEdition($edition)) }; (:~ @@ -259,10 +290,10 @@ declare function eutil:getLanguage($edition as xs:string?) as xs:string { : : NB, this is a relative path on the server, missing the scheme, : as well as the server address and port. - : This function simply concats the current context path with the - : eXist variables `$exist:prefix` and `$exist:controller` + : This function simply concats the current context path with the + : eXist variables `$exist:prefix` and `$exist:controller` : (see https://exist-db.org/exist/apps/doc/urlrewrite) - : + : : @return a relative path on the server :) declare function eutil:get-app-base-url() as xs:string? { @@ -281,9 +312,51 @@ declare function eutil:get-app-base-url() as xs:string? { :) declare function eutil:sort-as-numeric-alpha($seq as item()* ) as item()* { for $item in $seq - let $itemPart1 := functx:get-matches($item, '\d+') + let $itemPart1 := (functx:get-matches($item, '\d+'))[1] let $itemPart2 := substring-after($item, $itemPart1) order by number($itemPart1), $itemPart2 return $item } ; + +(:~ + : Extracts an ISO 639 language code from a given ISO 3166-1 language code + : + : @author Benjamin W. Bohl + : @param $iso3166-1 xs:string the given ISO 3166-1 language code, e.g., en-US + : @return xs:string ISO 639 language code, e.g., en + :) +declare function eutil:iso3166-1-to-iso639($iso3166-1 as xs:string) as xs:string { + tokenize($iso3166-1, "-")[1] +}; + +(:~ + : Returns the ISO 639 language code with the highest 'quality' (none cosidered as 1) from + : the HTTP-request Accept-Language header + : + : @author Benjamin W. Bohl + : @return xs:string ISO 639 language code + :) +declare function eutil:request-lang-preferred-iso639() as xs:string { +let $request.accept-language := request:get-header("Accept-Language") +return +if($request.accept-language) +then + let $tokens := tokenize($request.accept-language, ";") + let $tokens.qless.ordered := ( + for $token in $tokens + let $q := substring-after(string-join((analyze-string($token, "(q=\d(\.\d)?)")//fn:match)[1], ""), "q=") + let $q.decimal := if($q = "") then xs:decimal(1) else xs:decimal($q) + let $token.qless := replace($token,",?q=\d(\.\d)?,?", "") + order by $q.decimal descending + return + $token.qless + ) + let $tokens.qmax := $tokens.qless.ordered[1] + let $tokens.qmax.first := tokenize($tokens.qmax, ",")[1] + return + eutil:iso3166-1-to-iso639($tokens.qmax.first) + +else + "en" +}; diff --git a/add/data/xqm/work.xqm b/add/data/xqm/work.xqm index 7e384ec8a..d167c8468 100644 --- a/add/data/xqm/work.xqm +++ b/add/data/xqm/work.xqm @@ -41,14 +41,14 @@ declare namespace edirom="http://www.edirom.de/ns/1.3"; :) declare function work:toJSON($uri as xs:string, $edition as xs:string) as xs:string { - let $work := doc($uri)/mei:mei + let $work := doc($uri)/mei:mei | doc($uri)/mei:work let $lang := request:get-parameter('lang', '') return concat(' {', 'id: "', $work/string(@xml:id), '", ', 'doc: "', $uri, '", ', - 'title: "', replace(eutil:getLocalizedTitle($work//mei:work, $lang), '"', '\\"'), '"', + 'title: "', replace(eutil:getLocalizedTitle((($work/descendant-or-self::mei:work)[1]), $lang), '"', '\\"'), '"', '}') }; @@ -60,7 +60,7 @@ declare function work:toJSON($uri as xs:string, $edition as xs:string) as xs:str :) declare function work:isWork($uri as xs:string) as xs:boolean { - exists(doc($uri)//mei:mei) and exists(doc($uri)//mei:work) and not(doc($uri)//mei:source) + (exists(doc($uri)//mei:mei) and exists(doc($uri)//mei:work) and not(doc($uri)//mei:source)) or exists(doc($uri)/mei:work) }; (:~ @@ -72,7 +72,7 @@ declare function work:isWork($uri as xs:string) as xs:boolean { :) declare function work:getLabel($work as xs:string, $edition as xs:string) as xs:string { - eutil:getLocalizedTitle(doc($work)//mei:work, request:get-parameter('lang', '')) + eutil:getLocalizedTitle(doc($work)/root()//mei:work, request:get-parameter('lang', '')) }; (:~ diff --git a/add/data/xslt/ediromOnline_functions.xsl b/add/data/xslt/ediromOnline_functions.xsl index 961d59306..1f4b00481 100644 --- a/add/data/xslt/ediromOnline_functions.xsl +++ b/add/data/xslt/ediromOnline_functions.xsl @@ -14,7 +14,7 @@ - + diff --git a/add/data/xslt/functx-1.0-nodoc-2007-01.xsl b/add/data/xslt/functx-1.0-nodoc-2007-01.xsl deleted file mode 100644 index c5048f89a..000000000 --- a/add/data/xslt/functx-1.0-nodoc-2007-01.xsl +++ /dev/null @@ -1,1488 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/add/data/xslt/teiBody2HTML.xsl b/add/data/xslt/teiBody2HTML.xsl index a01b527c3..7088b1507 100644 --- a/add/data/xslt/teiBody2HTML.xsl +++ b/add/data/xslt/teiBody2HTML.xsl @@ -3,7 +3,7 @@ xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:exist="http://exist.sourceforge.net/NS/exist" xmlns:functx="http://www.functx.com" exclude-result-prefixes="#default xs tei xhtml" version="2.0"> - + @@ -199,7 +199,7 @@ - + @@ -1085,7 +1085,7 @@ ', {useExisting:true}); return false; - + @@ -1291,4 +1291,4 @@ - \ No newline at end of file + diff --git a/add/expath-pkg.xml b/add/expath-pkg.xml index 266f4fd42..c6e477f8d 100755 --- a/add/expath-pkg.xml +++ b/add/expath-pkg.xml @@ -5,4 +5,5 @@ version="@project.version@" spec="1.0"> @project.title@ + \ No newline at end of file diff --git a/add/index.xql b/add/index.xql index 8f8902b62..ddcbf00e9 100755 --- a/add/index.xql +++ b/add/index.xql @@ -126,12 +126,19 @@ let $eoEditionFileMulti :=
    { for $eoEditionFile in $eoEditionFiles + let $editionUri := document-uri($eoEditionFile/root()) let $editionID := $eoEditionFile/string(@xml:id) let $editionName := $eoEditionFile/edirom:editionName/text() => normalize-space() - return + let $editionLanguages := edition:getLanguageCodesSorted($editionUri) + return ( + ) }
diff --git a/add/modules/config.xqm b/add/modules/config.xqm deleted file mode 100755 index 2b14f4213..000000000 --- a/add/modules/config.xqm +++ /dev/null @@ -1,64 +0,0 @@ -(:~ - : A set of helper functions to access the application context from - : within a module. - :) -module namespace config="http://exist-db.org/xquery/apps/config"; - -declare namespace repo="http://exist-db.org/xquery/repo"; -declare namespace expath="http://expath.org/ns/pkg"; - -(: - Determine the application root collection from the current module load path. -:) -declare variable $config:app-root := - let $rawPath := system:get-module-load-path() - let $modulePath := - (: strip the xmldb: part :) - if (starts-with($rawPath, "xmldb:exist://")) then - if (starts-with($rawPath, "xmldb:exist://embedded-eXist-server")) then - substring($rawPath, 36) - else - substring($rawPath, 15) - else - $rawPath - return - substring-before($modulePath, "/modules") -; - -(:~ - : Returns the repo.xml descriptor for the current application. - :) -declare function config:repo-descriptor() as element(repo:meta) { - doc(concat($config:app-root, "/repo.xml"))/repo:meta -}; - -(:~ - : Returns the expath-pkg.xml descriptor for the current application. - :) -declare function config:expath-descriptor() as element(expath:package) { - doc(concat($config:app-root, "/expath-pkg.xml"))/expath:package -}; - -(:~ - : For debugging: generates a table showing all properties defined - : in the application descriptors. - :) -declare function config:app-info($node) { - let $expath := config:expath-descriptor() - let $repo := config:repo-descriptor() - return - - - - - - { - for $attr in ($expath/@*, $expath/*, $repo/*) - return - - - - - } -
app collection:{$config:app-root}
{node-name($attr)}:{$attr/string()}
-}; \ No newline at end of file diff --git a/app/Application.js b/app/Application.js index 2d340823f..f28a016e4 100644 --- a/app/Application.js +++ b/app/Application.js @@ -75,34 +75,34 @@ Ext.define('EdiromOnline.Application', { if(editionParam !== null) me.activeEdition = editionParam; - Ext.Ajax.request({ - url: 'data/xql/getEditionURI.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getEditionURI.xql', + 'GET', + { uri: me.activeEdition - },success: function(response){ - this.activeEdition = response.responseText; }, - scope: this - }); - + Ext.bind(function(response){ + this.activeEdition = response.responseText; + }, this), + 2, // retries + false // async + ); + var workParam = me.getURLParameter('work'); if(workParam !== null) me.activeWork = workParam; - Ext.Ajax.request({ - url: 'data/xql/getWorkID.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getWorkID.xql', + 'GET', + { uri: me.activeEdition, workId: me.activeWork - },success: function(response){ - this.activeWork = response.responseText; }, - scope: this - }); + Ext.bind(function(response){ + this.activeWork = response.responseText; + }, this), + 2, // retries + false // async + ); me.getController('PreferenceController').initPreferences(me.activeEdition); me.getController('LanguageController').initLangFile(me.activeEdition, 'de'); diff --git a/app/controller/AJAXController.js b/app/controller/AJAXController.js index 6db90970b..94573d820 100644 --- a/app/controller/AJAXController.js +++ b/app/controller/AJAXController.js @@ -27,19 +27,45 @@ Ext.define('EdiromOnline.controller.AJAXController', { window.doAJAXRequest = Ext.bind(this.doAJAXRequest, this); }, - doAJAXRequest: function(url, method, params, successFn, retryNo) { + /** + * Performs an AJAX request. + * + * @param {String} url The URL of the requestet site or end point. + * @param {String} method The HTTP method like 'PUT', 'GET', 'POST'. + * @param {Object} params An object containing key-value-pairs of parameters for the request. + * @param {Function} successFn A callback function which is called when the AJAX request was successfull. + * @param {Number} retryNo The number of retries, if the requests fails. Standard is 2 retries. + * @param {Boolean} async Defines the async parameter for AJAX calls. Default is 'true'. + */ + doAJAXRequest: function(url, method, params, successFn, retryNo, async) { var me = this; var editionId = this.application.activeEdition; params = Ext.applyIf(params, {edition: editionId}); - var override = window.getPreference(url, true); + var lang = window.getLanguage(); + params = Ext.applyIf(params, {lang: lang}); + + // define some requests that will make Edirom Online fail if it looks for an override + var doNotOverride = [ + 'data/xql/getEditionURI.xql', + 'data/xql/getPreferences.xql', + 'data/xql/getWorkID.xql', + ]; + + var override = null; + + if(doNotOverride.indexOf(url) == -1) + override = window.getPreference(url, true); if(override != null) url = override; - if(typeof(retryNo) === 'undefined') + if(typeof retryNo === 'undefined') retryNo = 2; + + if(typeof async === 'undefined') + async = true; var fn = Ext.bind(function(response, options, retryNoInt) { @@ -58,7 +84,8 @@ Ext.define('EdiromOnline.controller.AJAXController', { url: url, method: method, params: params, - success: fn + success: fn, + async: async }); } }); \ No newline at end of file diff --git a/app/controller/LanguageController.js b/app/controller/LanguageController.js index 14741d0ae..6df3c0039 100644 --- a/app/controller/LanguageController.js +++ b/app/controller/LanguageController.js @@ -35,20 +35,19 @@ Ext.define('EdiromOnline.controller.LanguageController', { initLangFile: function(editionURI, lang) { - Ext.Ajax.request({ - url: 'data/xql/getLanguageFile.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getLanguageFile.xql', + 'GET', + { lang: lang, mode: 'json', edition: editionURI - },success: function(response){ - - this.langFiles.add(lang, Ext.JSON.decode(response.responseText)); }, - scope: this - }); + Ext.bind(function(response){ + this.langFiles.add(lang, Ext.JSON.decode(response.responseText)); + }, this), + 2, // retries + false // async + ); }, getLanguageString: function(key) { diff --git a/app/controller/LinkController.js b/app/controller/LinkController.js index 23cbc0d53..794818d98 100644 --- a/app/controller/LinkController.js +++ b/app/controller/LinkController.js @@ -156,18 +156,16 @@ Ext.define('EdiromOnline.controller.LinkController', { if(singleUri.indexOf('#') != -1) { - Ext.Ajax.request({ - url: 'data/xql/getInternalIdType.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getInternalIdType.xql', + 'GET', + { uri: singleUri }, - success: function(response){ + Ext.bind(function(response){ win.loadInternalId(singleUri.split('#')[1], response.responseText.trim()); win.show(); - }, - scope: this - }); + }, this) + ); }else win.showView('summaryView'); diff --git a/app/controller/PreferenceController.js b/app/controller/PreferenceController.js index 5669b75e7..c4e5d86a9 100644 --- a/app/controller/PreferenceController.js +++ b/app/controller/PreferenceController.js @@ -30,18 +30,18 @@ Ext.define('EdiromOnline.controller.PreferenceController', { initPreferences: function(editionURI) { - Ext.Ajax.request({ - url: 'data/xql/getPreferences.xql', - async: false, - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPreferences.xql', + 'GET', + { mode: 'json', edition: editionURI - },success: function(response){ - this.setPreferences(Ext.JSON.decode(response.responseText)); }, - scope: this - }); + Ext.bind(function(response){ + this.setPreferences(Ext.JSON.decode(response.responseText)); + }, this), + 2, // retries + false // async + ); }, setPreferences: function(preferences) { @@ -50,14 +50,14 @@ Ext.define('EdiromOnline.controller.PreferenceController', { for(var key in me.preferences) { if(key.indexOf('plugin_') == 0) - Ext.Ajax.request({ - url: me.preferences[key], - method: 'GET', - success: function(response){ + + window.doAJAXRequest(me.preferences[key], + 'GET', + {}, + Ext.bind(function(response){ eval(response.responseText); - }, - scope: this - }); + }, this) + ); } }, diff --git a/app/controller/navigator/Navigator.js b/app/controller/navigator/Navigator.js index 784f86de0..52e645973 100644 --- a/app/controller/navigator/Navigator.js +++ b/app/controller/navigator/Navigator.js @@ -47,24 +47,22 @@ Ext.define('EdiromOnline.controller.navigator.Navigator', { var editionId = this.application.activeEdition; var lang = window.getLanguage('application_language'); - Ext.Ajax.request({ - url: 'data/xql/getNavigatorConfig.xql', - params: { + window.doAJAXRequest('data/xql/getNavigatorConfig.xql', + 'GET', + { editionId: editionId, workId: workId, lang: lang }, - success: function(response){ - + Ext.bind(function(response){ this.navigatorContents.add(workId, response.responseText); Ext.Array.each(this.navigators, function(navigator) { navigator.body.update(this.getNavigatorContent(workId)); navigator.setLoading(false); }, this); - }, - scope: this - }); + }, this) + ); }, getNavigatorContent: function(workId) { diff --git a/app/controller/window/HeaderView.js b/app/controller/window/HeaderView.js index e08ee87f6..e48adac7f 100644 --- a/app/controller/window/HeaderView.js +++ b/app/controller/window/HeaderView.js @@ -42,17 +42,15 @@ Ext.define('EdiromOnline.controller.window.HeaderView', { var uri = view.uri; var type = view.type; - Ext.Ajax.request({ - url: 'data/xql/getHeader.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getHeader.xql', + 'GET', + { uri: uri, type: type }, - success: function(response){ + Ext.bind(function(response){ view.setContent(response.responseText); - }, - scope: this - }); + }, this) + ); } }); diff --git a/app/controller/window/SummaryView.js b/app/controller/window/SummaryView.js index e60519c8b..e7c911e27 100644 --- a/app/controller/window/SummaryView.js +++ b/app/controller/window/SummaryView.js @@ -43,20 +43,18 @@ Ext.define('EdiromOnline.controller.window.SummaryView', { var app = EdiromOnline.getApplication(); var activeEdition = app.activeEdition - Ext.Ajax.request({ - url: 'data/xql/getSummary.xql', - method: 'GET', - params: { - uri: uri, + window.doAJAXRequest('data/xql/getSummary.xql', + 'GET', + { + uri: uri, type: type, edition: activeEdition - }, - success: function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; view.setContent(data); - }, - scope: this - }); + }, this) + ); } }); \ No newline at end of file diff --git a/app/controller/window/XmlView.js b/app/controller/window/XmlView.js index f8d4b03f3..c1bf4bd4a 100644 --- a/app/controller/window/XmlView.js +++ b/app/controller/window/XmlView.js @@ -47,18 +47,16 @@ Ext.define('EdiromOnline.controller.window.XmlView', { var uri = xmlview.uri; var internalId = xmlview.internalId; - Ext.Ajax.request({ - url: 'data/xql/getXml.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getXml.xql', + 'GET', + { uri: uri, internalId: internalId }, - success: function(response){ + Ext.bind(function(response){ xmlview.setXmlContent(response.responseText); - }, - scope: this - }); + }, this) + ); }, resize: function(xmlview, width, height){ diff --git a/app/controller/window/iFrameView.js b/app/controller/window/iFrameView.js index a8bba086f..b0c4a0e85 100644 --- a/app/controller/window/iFrameView.js +++ b/app/controller/window/iFrameView.js @@ -41,16 +41,14 @@ Ext.define('EdiromOnline.controller.window.iFrameView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getiFrameURL.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getiFrameURL.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ view.setContent(response.responseText); - }, - scope: this - }); + }, this) + ); } }); diff --git a/app/controller/window/source/MeasureBasedView.js b/app/controller/window/source/MeasureBasedView.js index d9f69fb8d..dd051b7e9 100644 --- a/app/controller/window/source/MeasureBasedView.js +++ b/app/controller/window/source/MeasureBasedView.js @@ -68,14 +68,13 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { onMdivSelected: function(mdiv, view) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasures.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasures.xql', + 'GET', + { uri: view.owner.uri, mdiv: mdiv }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -83,8 +82,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { data: Ext.JSON.decode(data) }); me.measuresLoaded(measures, view); - } - }); + }, this) + ); }, measuresLoaded: function(measures, view) { @@ -98,19 +97,18 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { onShowMeasure: function(view, uri, measureId, count) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { id: uri, measure: measureId, measureCount: count }, - success: Ext.bind(function(response){ + Ext.bind(function(response){ var data = response.responseText; this.showMeasure(view, uri, measureId, Ext.JSON.decode(data)); }, me) - }); + ); }, showMeasure: function(view, uri, measureId, data) { @@ -128,14 +126,13 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { }, fetchMeasures: function(uri, pageId, fn) { - Ext.Ajax.request({ - url: 'data/xql/getMeasuresOnPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasuresOnPage.xql', + 'GET', + { uri: uri, pageId: pageId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -145,8 +142,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { if(typeof fn == 'function') fn(measures); - } - }); + }, this) + ); }, measuresOnPageLoaded: function(measures, viewer, pageId) { @@ -198,16 +195,15 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { if(overlays[overlayId]) { - Ext.Ajax.request({ - url: 'data/xql/getOverlayOnPage.xql', - method: 'GET', - params: { - uri: uri, - pageId: pageId, - overlayId: overlayId - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getOverlayOnPage.xql', + 'GET', + { + uri: uri, + pageId: pageId, + overlayId: overlayId + }, + Ext.bind(function(response){ + var data = response.responseText; if (data.trim() == '') return; @@ -218,8 +214,8 @@ Ext.define('EdiromOnline.controller.window.source.MeasureBasedView', { me.overlayLoaded(viewer, pageId, overlayId, overlay, sourceView); - } - }); + }, this) + ); }else { viewer.removeSVGOverlay(overlayId); } diff --git a/app/controller/window/source/PageBasedView.js b/app/controller/window/source/PageBasedView.js index 0101cd168..7835cf120 100644 --- a/app/controller/window/source/PageBasedView.js +++ b/app/controller/window/source/PageBasedView.js @@ -40,14 +40,13 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { if (view.initialized) return; view.initialized = true; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { - uri: view.owner.uri - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { + uri: view.owner.uri + }, + Ext.bind(function(response){ + var data = response.responseText; var pages = Ext.create('Ext.data.Store', { fields:[ 'id', 'name', 'path', 'width', 'height', 'measures', 'annotations'], @@ -55,8 +54,8 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { }); me.pagesLoaded(pages, view); - } - }); + }, this) + ); }, pagesLoaded: function (pages, view) { @@ -70,16 +69,15 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { if(overlays[overlayId]) { // if visible - Ext.Ajax.request({ - url: 'data/xql/getOverlayOnPage.xql', - method: 'GET', - params: { - uri: uri, - pageId: pageId, - overlayId: overlayId - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getOverlayOnPage.xql', + 'GET', + { + uri: uri, + pageId: pageId, + overlayId: overlayId + }, + Ext.bind(function(response){ + var data = response.responseText; if (data.trim() == '') return; @@ -89,8 +87,8 @@ Ext.define('EdiromOnline.controller.window.source.PageBasedView', { }); me.overlayLoaded(viewer, pageId, overlayId, overlay, sourceView); - } - }); + }, this) + ); }else { viewer.imageViewer.removeSVGOverlay(overlayId); } diff --git a/app/controller/window/source/SourceView.js b/app/controller/window/source/SourceView.js index 6d6281169..a5a7b1606 100644 --- a/app/controller/window/source/SourceView.js +++ b/app/controller/window/source/SourceView.js @@ -53,14 +53,12 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { ToolsController.addAnnotationVisibilityListener(view.id, Ext.bind(view.checkGlobalAnnotationVisibility, view)); view.checkGlobalAnnotationVisibility(ToolsController.areAnnotationsVisible()); - - Ext.Ajax.request({ - url: 'data/xql/getMovements.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMovements.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var movements = Ext.create('Ext.data.Store', { @@ -69,8 +67,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }); me.movementsLoaded(movements, view); - } - }); + }, this) + ); window.doAJAXRequest('data/xql/getAnnotationInfos.xql', 'GET', @@ -97,13 +95,12 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }, this) ); - Ext.Ajax.request({ - url: 'data/xql/getOverlays.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getOverlays.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var overlays = Ext.create('Ext.data.Store', { @@ -112,8 +109,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }); me.overlaysLoaded(overlays, view); - } - }); + }, this) + ); }, movementsLoaded: function(movements, view) { @@ -131,18 +128,17 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { onGotoMovement: function(view, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMovementsFirstPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMovementsFirstPage.xql', + 'GET', + { uri: view.uri, movementId: movementId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; me.gotoMovement(Ext.String.trim(data), view); - } - }); + }, this) + ); }, gotoMovement: function(pageId, view) { @@ -167,14 +163,13 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { }, fetchMeasures: function(uri, pageId, fn) { - Ext.Ajax.request({ - url: 'data/xql/getMeasuresOnPage.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getMeasuresOnPage.xql', + 'GET', + { uri: uri, pageId: pageId }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var measures = Ext.create('Ext.data.Store', { @@ -184,8 +179,8 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { if(typeof fn == 'function') fn(measures); - } - }); + }, this) + ); }, measuresOnPageLoaded: function(measures, view, pageId) { @@ -242,39 +237,35 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { onGotoMeasureByName: function (view, measure, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { + id: view.uri, measure: measure, movementId: movementId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data)[0], view); - }, - me) - }); + }, me) + ); }, onGotoMeasure: function (view, measureId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasure.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasure.xql', + 'GET', + { + id: view.uri, measureId: measureId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data), view); - }, - me) - }); + }, me) + ); }, gotoMeasure: function (result, view) { @@ -293,19 +284,17 @@ Ext.define('EdiromOnline.controller.window.source.SourceView', { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getZone.xql', - method: 'GET', - params: { - uri: view.uri, + window.doAJAXRequest('data/xql/getZone.xql', + 'GET', + { + uri: view.uri, zoneId: zoneId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoZone(Ext.JSON.decode(data), view); - }, - me) - }); + }, this) + ); }, gotoZone: function (result, view) { diff --git a/app/controller/window/source/VerovioView.js b/app/controller/window/source/VerovioView.js index e0fd376c7..fb79c506d 100644 --- a/app/controller/window/source/VerovioView.js +++ b/app/controller/window/source/VerovioView.js @@ -44,14 +44,13 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { view.on('gotoMeasureByName', me.onGotoMeasureByName, me); view.on('gotoMeasure', me.onGotoMeasure, me); - Ext.Ajax.request({ - url: 'data/xql/getMovements.xql', - method: 'GET', - params: { - uri: view.uri - }, - success: function (response) { - var data = response.responseText; + window.doAJAXRequest('data/xql/getMovements.xql', + 'GET', + { + uri: view.uri + }, + Ext.bind(function(response){ + var data = response.responseText; var movements = Ext.create('Ext.data.Store', { fields:[ 'id', 'name'], @@ -59,8 +58,8 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { }); me.movementsLoaded(movements, view); - } - }); + }, this) + ); }, movementsLoaded: function (movements, view) { @@ -70,39 +69,35 @@ Ext.define('EdiromOnline.controller.window.source.VerovioView', { onGotoMeasureByName: function (view, measure, movementId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasurePage.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasurePage.xql', + 'GET', + { + id: view.uri, measure: measure, movementId: movementId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data)[0], view); - }, - me) - }); + }, me) + ); }, onGotoMeasure: function (view, measureId) { var me = this; - Ext.Ajax.request({ - url: 'data/xql/getMeasure.xql', - method: 'GET', - params: { - id: view.uri, + window.doAJAXRequest('data/xql/getMeasure.xql', + 'GET', + { + id: view.uri, measureId: measureId - }, - success: Ext.bind(function (response) { - var data = response.responseText; + }, + Ext.bind(function(response){ + var data = response.responseText; this.gotoMeasure(Ext.JSON.decode(data), view); - }, - me) - }); + }, me) + ); }, gotoMeasure: function (result, view) { diff --git a/app/controller/window/text/FacsimileView.js b/app/controller/window/text/FacsimileView.js index b15bb7a47..642fc00d3 100644 --- a/app/controller/window/text/FacsimileView.js +++ b/app/controller/window/text/FacsimileView.js @@ -44,13 +44,12 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var pages = Ext.create('Ext.data.Store', { @@ -59,17 +58,16 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { }); view.setImageSet(pages); - } - }); + }, this) + ); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri, mode: 'pageMode' }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -78,8 +76,8 @@ Ext.define('EdiromOnline.controller.window.text.FacsimileView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); }, chaptersLoaded: function(chapters, view) { diff --git a/app/controller/window/text/TextFacsimileSplitView.js b/app/controller/window/text/TextFacsimileSplitView.js index 1d47b36d4..e05b08aae 100644 --- a/app/controller/window/text/TextFacsimileSplitView.js +++ b/app/controller/window/text/TextFacsimileSplitView.js @@ -50,13 +50,12 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { var uri = view.uri; - Ext.Ajax.request({ - url: 'data/xql/getPages.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getPages.xql', + 'GET', + { uri: uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var pages = Ext.create('Ext.data.Store', { @@ -65,17 +64,16 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); view.setImageSet(pages); - } - }); + }, this) + ); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri, mode: 'pageMode' }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -84,8 +82,8 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); }, onAfterImageChanged: function(view) { @@ -148,14 +146,13 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { var me = this; if(visible) - Ext.Ajax.request({ - url: 'data/xql/getAnnotationsInText.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotationsInText.xql', + 'GET', + { uri: view.uri, page: view.getActivePage() }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var annotations = Ext.create('Ext.data.Store', { @@ -164,9 +161,8 @@ Ext.define('EdiromOnline.controller.window.text.TextFacsimileSplitView', { }); me.annotationsLoaded(annotations, view); - } - }); - + }, this) + ); else view.hideAnnotations(); }, diff --git a/app/controller/window/text/TextView.js b/app/controller/window/text/TextView.js index f780d1851..d40bae8e5 100644 --- a/app/controller/window/text/TextView.js +++ b/app/controller/window/text/TextView.js @@ -69,13 +69,12 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { view.setContent(content); - Ext.Ajax.request({ - url: 'data/xql/getChapters.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getChapters.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var chapters = Ext.create('Ext.data.Store', { @@ -84,8 +83,8 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { }); me.chaptersLoaded(chapters, view); - } - }); + }, this) + ); window.doAJAXRequest('data/xql/getAnnotationInfos.xql', 'GET', @@ -121,13 +120,12 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { var me = this; if(visible) - Ext.Ajax.request({ - url: 'data/xql/getAnnotationsInText.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotationsInText.xql', + 'GET', + { uri: view.uri }, - success: function(response){ + Ext.bind(function(response){ var data = response.responseText; var annotations = Ext.create('Ext.data.Store', { @@ -136,9 +134,8 @@ Ext.define('EdiromOnline.controller.window.text.TextView', { }); me.annotationsLoaded(annotations, view); - } - }); - + }, this) + ); else view.hideAnnotations(); }, diff --git a/app/view/window/AnnotationView.js b/app/view/window/AnnotationView.js index 97f18033a..74d95e4c0 100644 --- a/app/view/window/AnnotationView.js +++ b/app/view/window/AnnotationView.js @@ -753,17 +753,17 @@ Ext.define('EdiromOnline.view.window.AnnotationView', { var uri = txtData.match(/uri:(.*)__\$\$__/)[1]; var id = txtData.match(/__\$\$__participantId:(.*)/)[1]; - Ext.Ajax.request({ - url: 'data/xql/getReducedDocument.xql?uri=' + uri + '&selectionId=' + id + '&subtreeRoot=div&idPrefix=' + me.id + '_', - success: function(response){ + window.doAJAXRequest('data/xql/getReducedDocument.xql?uri=' + uri + '&selectionId=' + id + '&subtreeRoot=div&idPrefix=' + me.id + '_', + 'GET', + {}, + Ext.bind(function(response){ var contEl = this.el.getById(me.id + '_annotationParticipantsSingle'); var txtBox = new Ext.Element(contEl.query('div.txtBox')[0]); txtBox.update(response.responseText); contEl.query('#' + this.id + '_' + id)[0].scrollIntoView(txtBox); - }, - scope: me - }); + }, me) + ); }, previousParticipantSingle: function() { diff --git a/app/view/window/image/LeafletFacsimile.js b/app/view/window/image/LeafletFacsimile.js index ffb198a72..ed933f676 100644 --- a/app/view/window/image/LeafletFacsimile.js +++ b/app/view/window/image/LeafletFacsimile.js @@ -303,32 +303,28 @@ Ext.define('EdiromOnline.view.window.image.LeafletFacsimile', { var me = this; rectangleCenter.on('mouseover', function (e) { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { - uri: annotURI, - target: 'tip', - edition: EdiromOnline.getApplication().activeEdition - }, - success: function(response){ - //this.update(response.responseText); - me.facsimileTile.disableRectangle(); - me.facsimileTile.enableRectangle(ulx, uly, lrx, lry, true); - //rect_tmp = me.facsimileTile.createPupup(ulx, uly, lrx, lry, rectangleCenter , response.responseText); - var overview = response.responseText; - var test = $(overview).html(); - tooltip.setHtml(test); + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { + uri: annotURI, + target: 'tip', + edition: EdiromOnline.getApplication().activeEdition + }, + Ext.bind(function(response){ + //this.update(response.responseText); + me.facsimileTile.disableRectangle(); + me.facsimileTile.enableRectangle(ulx, uly, lrx, lry, true); + //rect_tmp = me.facsimileTile.createPupup(ulx, uly, lrx, lry, rectangleCenter , response.responseText); + var overview = response.responseText; + var test = $(overview).html(); + tooltip.setHtml(test); /*var tooltip = L.tooltip({ target: rectangleCenter, map: me.getMap(), html: response.responseText });*/ - - - } - // scope: this - }); + }, this) + ); }); diff --git a/app/view/window/image/OpenSeaDragonViewer.js b/app/view/window/image/OpenSeaDragonViewer.js index 7bb6d4594..0c6fa75f0 100644 --- a/app/view/window/image/OpenSeaDragonViewer.js +++ b/app/view/window/image/OpenSeaDragonViewer.js @@ -35,6 +35,7 @@ Ext.define('EdiromOnline.view.window.image.OpenSeaDragonViewer', { imagePrefix: null, shapes: null, + partLabel: null, annotTipWidth: 220, annotTipMaxWidth: 300, @@ -49,11 +50,25 @@ Ext.define('EdiromOnline.view.window.image.OpenSeaDragonViewer', { me.addEvents('zoomChanged', 'imageChanged'); - - me.html = '
'; + + var openseadragonEvents; + + if (me.partLabel != null) { + openseadragonEvents = '
' + + '
' + + '' + + me.partLabel + '' + + '
' + + '
'; + } + else { + openseadragonEvents = '
'; + }; + + me.html = '
' + openseadragonEvents; me.shapes = new Ext.util.MixedCollection(); - + me.callParent(); me.on('afterrender', me.initSurface, me, {single: true}); diff --git a/app/view/window/image/VerovioImage.js b/app/view/window/image/VerovioImage.js index 77a0cee90..d22b01b91 100644 --- a/app/view/window/image/VerovioImage.js +++ b/app/view/window/image/VerovioImage.js @@ -18,36 +18,36 @@ */ Ext.define('EdiromOnline.view.window.image.VerovioImage', { extend: 'Ext.panel.Panel', - + layout: 'fit', - + initComponent: function () { - + var me = this; - + me.html = '
'; - + '_rendContIFrame">'; + me.callParent(); }, - + setIFrameURL: function (url) { var me = this; var contEl = me.el.getById(me.id + '_rendContIFrame'); contEl.set({ 'src': url }); - + }, - + showMovement: function (movementId) { var me = this; - + var iframe = Ext.fly(me.id + '_rendContIFrame').dom.contentWindow; iframe.showMovement(movementId); }, - - /* + + /* * Call showMeasure of corresponding iframe. * @param {string} movementId - The XML-ID of the selected movement. * @param {string} measureId - The XML-ID of the selected measure. diff --git a/app/view/window/text/TextFacsimileSplitView.js b/app/view/window/text/TextFacsimileSplitView.js index 325e3ca09..d0605307c 100644 --- a/app/view/window/text/TextFacsimileSplitView.js +++ b/app/view/window/text/TextFacsimileSplitView.js @@ -205,18 +205,16 @@ Ext.define('EdiromOnline.view.window.text.TextFacsimileSplitView', { }); tip.on('afterrender', function() { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { uri: uri, target: 'tip' }, - success: function(response){ + Ext.bind(function(response){ this.update(response.responseText); - }, - scope: this - }); + }, this) + ); }, tip); }, me); diff --git a/app/view/window/text/TextView.js b/app/view/window/text/TextView.js index 7221b9b12..08c6a5364 100644 --- a/app/view/window/text/TextView.js +++ b/app/view/window/text/TextView.js @@ -170,18 +170,16 @@ Ext.define('EdiromOnline.view.window.text.TextView', { }); tip.on('afterrender', function() { - Ext.Ajax.request({ - url: 'data/xql/getAnnotation.xql', - method: 'GET', - params: { + window.doAJAXRequest('data/xql/getAnnotation.xql', + 'GET', + { uri: uri, target: 'tip' }, - success: function(response){ + Ext.bind(function(response){ this.update(response.responseText); - }, - scope: this - }); + }, this) + ); }, tip); }, me); diff --git a/build.xml b/build.xml index 59dd87f9e..80fbf7e27 100755 --- a/build.xml +++ b/build.xml @@ -3,7 +3,7 @@ - + diff --git a/packages/eoTheme/sass/etc/all.scss b/packages/eoTheme/sass/etc/all.scss index afcb277a4..50a944a2b 100644 --- a/packages/eoTheme/sass/etc/all.scss +++ b/packages/eoTheme/sass/etc/all.scss @@ -1,11 +1,11 @@ -@import 'webfonts.scss'; +@import 'webfonts.scss'; @import 'mixins.scss'; /*Edirom*/ @import 'facsimile.scss'; @import 'xml.scss'; @import 'toolbar.scss'; - + //@import 'textViewContent.scss'; @import 'textView.scss'; @import 'headerView.scss'; @@ -16,4 +16,7 @@ @import 'freidi.scss'; /*Annotations*/ -@import 'annotation.scss'; \ No newline at end of file +@import 'annotation.scss'; + +/*renderingView (Verovio)*/ +@import 'renderingViewContent.scss' diff --git a/packages/eoTheme/sass/etc/renderingViewContent.scss b/packages/eoTheme/sass/etc/renderingViewContent.scss new file mode 100644 index 000000000..a9ef7c70a --- /dev/null +++ b/packages/eoTheme/sass/etc/renderingViewContent.scss @@ -0,0 +1,7 @@ +/* make verovio iFrame fit Edirom window */ +.renderingViewContent, .renderingViewContent iframe { + width: 100%; + height: 100%; + border: none; + overflow: hidden; +} diff --git a/resources/css/todo.css b/resources/css/todo.css index fd7fe2e2c..b94fb4654 100644 --- a/resources/css/todo.css +++ b/resources/css/todo.css @@ -400,10 +400,4 @@ span#workSwitch-btnInnerEl:before { .x-menu-item-active { background-color: rgb(36, 145, 235) !important; color: rgb(161, 209, 247) !important; -} - -/* Verovio view */ - -.renderingViewContent { - height: 100%; -} +} \ No newline at end of file diff --git a/resources/css/verovio-view.css b/resources/css/verovio-view.css index 333f23ba2..1ba61c69d 100644 --- a/resources/css/verovio-view.css +++ b/resources/css/verovio-view.css @@ -17,7 +17,7 @@ body { left: 0; right: 0; bottom: 0; - background-color: #cccccc; + background-color: rgba(0, 0, 0, 10%); text-align: center; line-height: 2em; }